Menyinkronkan dua database di SQL Server

16

Saya memiliki dua database SQL Server. Satu adalah klien (aplikasi Windows) dan yang kedua di server. Saya ingin menyinkronkan kedua database ini sesering mungkin (mis. Setiap 2 menit!).

Saya telah membaca tentang berbagai cara sinkronisasi seperti replikasi, cap waktu, tabel log menggunakan pemicu, Microsoft Sync Framework dan sebagainya.

Sebenarnya saya tidak suka menggunakan metode sinkronisasi yang mungkin berupa kotak hitam (seperti replikasi) karena saya tidak ingin tabel khusus SQL Server diblokir saat saya memperbarui mereka dan menyinkronkannya dengan server.

  1. metode mana menurut Anda yang harus saya gunakan dalam keadaan seperti itu? Ingat bahwa setiap beberapa menit saya harus mengirim beberapa perubahan tabel dari klien ke server dan mengambil juga dua perubahan tabel dari server.

  2. Saya telah menemukan metode yang aneh tetapi baru. Apakah mungkin bahwa saya mencatat semua prosedur tersimpan yang dijalankan (untuk pilihan tertentu) di klien dan mengirimkannya dengan parameter mereka dalam .sqlfile ke server dan menjalankannya di sana? Hal yang sama akan terjadi di server dan dikirim ke klien. Apakah Anda berpikir bahwa ini adalah metode yang sederhana namun bermanfaat atau tidak?

  3. tolong sarankan saya pendekatan yang berguna jika Anda bisa. Terima kasih banyak.

EDIT: Ingat bahwa ini adalah sinkronisasi waktu-nyata dan ini membuatnya istimewa. Itu berarti ketika pengguna klien menggunakan tabel, proses sinkronisasi dengan server harus terjadi setiap beberapa menit sehingga tidak ada tabel yang harus dikunci.

Emad Farrokhi
sumber
1
Ingatlah bahwa "kotak hitam" itu didokumentasikan dengan relatif baik berkenaan dengan cara kerjanya, cara memelihara dan memonitornya, dan apa yang dapat Anda lakukan untuk memperbaikinya dalam skenario kegagalan yang umum (dan tidak biasa). Saya akan mempertimbangkan untuk menggulirkan metode sinkronisasi saya sendiri dan harus menemukan dan memperbaiki bug yang terkait dengan kasus tepi yang ditangani "kotak hitam" sejak lama jika dan hanya jika saya memiliki kebutuhan spesifik aplikasi yang sangat (sinkronisasi parsial, atau kebutuhan pengguna- resolusi konflik interaktif, dan sebagainya).
David Spillett
@ David Spillett: Apakah Anda berhasil menggunakan replikasi dalam proyek sinkronisasi real-time? Perhatian utama saya adalah sinkronisasi waktu-nyata dan "mengunci dan memblokir".
Emad Farrokhi

Jawaban:

14

Yah saya mungkin tidak mengerti, tetapi saya mencoba menjawabnya.

Anda bilang Anda membutuhkan solusi kinerja tinggi yang sering berjalan (minimal semua 2 menit) dan Anda membutuhkan pendekatan yang baik yang harus cepat tanpa mengunci. Tetapi Anda tidak ingin sistem blackbox.

Alih-alih sistem blackbox, yang digunakan pada jutaan instalasi dengan hasil yang baik, Anda mencoba untuk menemukan roda lagi dan membangun solusi Anda sendiri? Hm, terdengar agak aneh.

Sebenarnya ini adalah saran saya.

  1. Replikasi bahkan jika Anda mengatakan Anda tidak akan menggunakannya. Ini adalah solusi termudah dan terbaik yang dapat Anda gunakan untuk ini. Replikasi itu mudah diatur, direplikasi dengan cepat dan Anda tidak perlu menemukan roda lagi. Jika Anda hanya aneh tentang penguncian, Anda dapat mencoba untuk mengatur ISOLATION LEVELke READ_COMMITTED_SNAPSHOT. Anda dapat membaca lebih lanjut di sini . Ini akan menghabiskan sebagian dari tempdb Anda, tetapi tabel Anda selalu dapat dibaca dan ditulisi dan replikasi dapat bekerja di latar belakang.

Lihat contoh di bawah ini:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Ubah Data Capture) juga bisa menjadi solusi. Tetapi dengan cara ini Anda perlu membangun hampir semuanya sendiri. Dan saya telah membuat pengalaman yang CDCbisa menjadi hal yang rapuh dalam beberapa keadaan. CDCakan menangkap semua data pada tabel yang ditonton (Anda perlu menentukan setiap tabel yang ditonton secara manual). Setelah itu Anda akan mendapatkan nilai sebelum dan nilai setelah INSERT, UPDATEatau DELETE. CDCakan menahan informasi tersebut untuk jangka waktu tertentu (Anda dapat menentukannya sendiri). Pendekatannya dapat digunakan CDCpada tabel tertentu yang perlu Anda perhatikan dan secara manual mereplikasi perubahan tersebut ke database lain. Omong-omong, CDCgunakan Replikasi Server SQL di bawah tenda juga. ;-) Anda dapat membaca lebih lanjut di sini .

Peringatan: CDCtidak akan mengetahui DDLperubahan. Ini berarti, jika Anda mengubah tabel dan menambahkan kolom baru, CDCakan menonton tabel tetapi mengabaikan semua perubahan pada kolom baru. Bahkan hanya mencatat NULLsebagai nilai sebelum dan setelah nilai. Anda perlu menginisialisasi ulang setelah DDL-Perubahan ke tabel yang ditonton.

  1. Cara Anda dijelaskan di atas adalah seperti menangkap beban kerja menggunakan SQL Server Profiler dan menjalankannya lagi di database lain untuk beberapa tolok ukur. Yah itu bisa berhasil. Tetapi kenyataan bahwa ada terlalu banyak efek samping agak terlalu berat bagi saya. Apa yang Anda lakukan jika Anda menangkap panggilan prosedur pada klien Anda. Setelah itu jalankan perintah yang sama di basis data prinsip Anda karena tidak sinkron? Prosedur dapat berjalan melalui, tetapi mungkin menghapus / memperbarui / memasukkan baris yang tidak ada di klien Anda. Atau bagaimana Anda menangani banyak klien dengan satu prinsip. Saya pikir ini terlalu rumit. Dalam kasus terburuk, Anda mungkin menghancurkan integritas Anda.
  2. Gagasan lain bisa berbasis aplikasi atau menggunakan pemicu. Tergantung pada berapa banyak tabel yang ingin Anda selaraskan. Anda dapat menulis semua perubahan ke tabel pementasan terpisah dan menjalankan Pekerjaan Server SQL Server semua x Menit untuk menyinkronkan baris-baris dalam tabel pementasan dengan master Anda. Tetapi ini mungkin agak berat jika Anda mencoba menyinkronkan (misalnya) 150 tabel. Anda akan memiliki overhead yang besar.

Nah ini 2 sen saya. Semoga Anda memiliki gambaran umum yang baik dan mungkin Anda menemukan satu solusi yang cocok untuk Anda.

Ionik
sumber
9

Saya akan mencoba untuk menyebutkan beberapa opsi di sini dengan kelebihan dan kekurangan saat saya mempersepsikannya:

  1. Replikasi SQL Server - ini adalah alat SQL Server asli terbaik dan paling dioptimalkan untuk tugas ini. Tetapi ada beberapa masalah: a. untuk semua klien Anda, terlepas dari apakah itu database SQL Express atau tidak, Anda akan memerlukan lisensi SQL Server CAL. Ini dapat dihindari menggunakan per lisensi prosesor. b. Anda tidak dapat menyinkronkan klien SQL CE sesuai di sini . c. SQL Express atau LocalDB tidak dapat bertindak sebagai penerbit atau distributor , sehingga Anda memiliki sedikit kontrol pada klien atas proses replikasi.
  2. Microsoft Sync Framework - bagi saya lebih cocok untuk basis data aplikasi seluler yang lebih kecil. Ini menambahkan cukup banyak tabel ke database Anda dan tidak seefisien replikasi. Karena ini diterapkan di luar SQL Server sebagai komponen, itu akan lebih sulit untuk dikonfigurasi. Saya tidak punya pengalaman dengan itu, hanya mencobanya dan memutuskan untuk tidak menggunakannya.

  3. Pelacakan perubahan basis data . Ini adalah fungsi SQL Server bawaan yang berfungsi untuk Anda mengubah pelacakan termasuk memasukkan, memperbarui, dan menghapus. Semua hal lain seperti mengirim dan menerapkan perubahan, menyelesaikan konflik, dll. Anda harus membuat kode sendiri.

  4. Kolom baris konversi (stempel waktu) Jika Anda melarang semua penghapusan (tidak ada sinkronisasi catatan yang dihapus) - Anda dapat menerapkan solusi Anda sendiri hanya berdasarkan informasi perubahan baris. Kolom baris konversi juga digunakan oleh Replikasi SQL Server, jadi Anda harus menambahkannya.
  5. CDC sebagaimana disebutkan dalam jawaban Ionic - saya tidak punya pengalaman dengan itu, karena hanya tersedia dalam edisi Perusahaan atau Pengembang.

  6. Menggunakan trik Anda sendiri dengan mencatat prosedur tersimpan yang dijalankan - sangat tergantung pada sifat aplikasi database Anda. Tetapi ketika prosedur menjadi sedikit berbeda, di sana Anda bisa mendapatkan kekacauan besar dalam data. Dan bagaimana Anda menangani konflik?

Dari pertanyaan Anda, tampaknya Anda perlu menyinkronkan hanya beberapa tabel dan tidak seluruh database besar. Untuk tujuan ini, Anda harus menganalisis kebutuhan Anda lebih detail daripada yang Anda tentukan dalam pertanyaan, seperti:

  • Bisakah penghapusan terjadi dan apa yang terjadi kemudian?
  • Dapatkah konflik terjadi, bagaimana mencegahnya dan bagaimana menyelesaikannya?
  • Bagaimana saya akan berurusan dengan perubahan struktur tabel?
  • ...

Jika pada akhirnya Anda mengetahui, bahwa penghapusan dan konflik bukanlah masalah Anda dan bahwa struktur Anda tidak akan banyak berubah, Anda dapat mempertimbangkan untuk menulis logika Anda sendiri, tetapi dapat dengan mudah berkembang menjadi 1000 baris kode.

Vojtěch Dohnal
sumber
2

Terima kasih atas tanggapan Anda.

Saya berhasil menyelesaikan proses sinkronisasi dengan menangkap prosedur tersimpan yang dijalankan bukan sebagai banyak tetapi satu per satu yang bekerja sangat baik dalam kasus saya. Karena integritas dan semuanya dipertimbangkan dengan hati-hati, sistem telah bekerja secara real-time hingga sekarang.

Emad Farrokhi
sumber
Hebat namun bisa tolong jelaskan lebih detail apa yang Anda lakukan. Apakah Anda cukup mencatat panggilan prosedur tersimpan yang dieksekusi dan menyimpannya dalam beberapa temp table / script dan memiliki pekerjaan menjalankan skrip ini dan yang menetapkan bidang (seperti bidang bit atau bidang datetime di mana Anda mengatakan untuk SEMUA ini catatan yang belum diproses memprosesnya dan memperbarui bidang bit?) Saya senang Anda memecahkan masalah Anda, tetapi Anda perlu memberikan wawasan lebih lanjut tentang apa yang Anda lakukan untuk membantu orang lain belajar?
JonH
0

Jawaban terlambat tetapi mungkin bermanfaat untuk memberi tahu pengunjung

Saya memiliki tantangan serupa mencoba mendistribusikan data di server yang berbeda dan menyelesaikannya dengan menggunakan alat pihak ketiga ( Diff untuk perubahan skema dan DataDiff untuk sinkronisasi perubahan data) dan mengikuti skrip PowerShell yang diperlukan untuk mengotomatiskan proses:

#check for the existence of the Outputs folder
function CheckAndCreateFolder($rootFolder, [switch]$Outputs)
{
$location = $rootFolder

#setting up location 
if($Outputs -eq $true)
{
    $location += "\Outputs"
}

#if the folder doesn't exist it will be created
if(-not (Test-Path $location))
{ mkdir $location -Force:$true -Confirm:$false | Out-Null }

return $location
}

#root folder for the schema sync process
$rootFolder = "SchemaSync"

#schema output summaries location 
$outsLoc = CheckAndCreateFolder $rootFolder -Outputs

#ApexSQL Diff location, date stamp variable is defined, along with tools parameters 
$diffLoc   = "ApexSQLDiff"
$stamp = (Get-Date -Format "MMddyyyy_HHMMss") 
$Params = "/pr:""MyProject.axds""    /out:""$outsLoc\SchemaOutput_$stamp.txt"" /sync /v /f" 
$returnCode = $LASTEXITCODE

#initiate the schema comparison and synchronization process
(Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params))

#write output to file
"$outsLoc\SchemaOutput_$dateStamp.txt"

#schema changes are detected
if($returnCode -eq 0)
{
"`r`n $returnCode - Schema changes were successfully synchronized" >> 

}
else
{
#there are no schema changes
if($returnCode -eq 102)
{
"`r`n $returnCode - There are no schema changes. Job aborted" >> 
}
#an error is encountered
else
{
"`r`n $returnCode - An error is encountered" >> 

#output file is opened when an error is encountered
Invoke-Item "$outsLoc\SchemaOutput_$stamp.txt"
}

}

Metode ini menjadwalkan perbandingan antara dua database dan menyinkronkan perubahan yang ditemukan secara real time. Berikut adalah beberapa artikel yang menawarkan petunjuk langkah demi langkah:

https://solutioncenter.apexsql.com/automatically-compare-and-synchronize-sql-server-data/ https://solutioncenter.apexsql.com/how-to-automatically-keep-two-sql-server-database- skema-dalam-sinkronisasi /

Monte Chavis
sumber