Đồng bộ hóa hai cơ sở dữ liệu trong SQL Server


16

Tôi có hai cơ sở dữ liệu SQL Server. Một là máy khách (ứng dụng Windows) và thứ hai là trên máy chủ. Tôi muốn đồng bộ hóa hai cơ sở dữ liệu này thường xuyên (ví dụ: cứ sau 2 phút!).

Tôi đã đọc về các cách đồng bộ hóa khác nhau như sao chép, dấu thời gian, bảng nhật ký bằng cách sử dụng kích hoạt, Microsoft Sync Framework, v.v.

Trên thực tế, tôi không muốn sử dụng phương thức đồng bộ hóa có thể là hộp đen (như sao chép) vì tôi không muốn các bảng cụ thể của SQL Server bị chặn trong khi tôi cập nhật chúng và đồng bộ hóa chúng với máy chủ.

  1. bạn nghĩ nên sử dụng phương pháp nào trong trường hợp như vậy? Hãy nhớ rằng cứ sau vài phút tôi phải gửi một vài thay đổi bảng từ máy khách đến máy chủ và tìm nạp hai thay đổi bảng từ máy chủ.

  2. Tôi đã tìm thấy một phương pháp lạ nhưng mới. Có phải là tôi có thể ghi nhật ký tất cả các thủ tục được lưu trữ (đối với ưu tiên cụ thể) trong máy khách và gửi chúng với các tham số của chúng trong một .sqltệp đến máy chủ và thực hiện chúng ở đó không? Điều tương tự sẽ xảy ra trên máy chủ và gửi cho khách hàng. Bạn có nghĩ rằng đây là một phương pháp đơn giản nhưng hữu ích hay không?

  3. xin vui lòng gợi ý cho tôi bất kỳ phương pháp hữu ích nếu bạn có thể. Cảm ơn bạn rất nhiều.

EDIT: Hãy nhớ rằng đây là đồng bộ hóa thời gian thực và điều này làm cho nó trở nên đặc biệt. Điều này có nghĩa là khi người dùng máy khách đang sử dụng bảng, quá trình đồng bộ hóa với máy chủ phải diễn ra cứ sau vài phút để không có bảng nào bị khóa.


1
Hãy nhớ rằng những "hộp đen" đó được ghi chép tương đối tốt về cách chúng hoạt động, cách duy trì và giám sát chúng, và những gì bạn có thể làm để khắc phục chúng trong các tình huống lỗi phổ biến (và không phổ biến). Tôi sẽ cân nhắc việc sử dụng phương pháp đồng bộ hóa của riêng mình và phải tìm và sửa các lỗi liên quan đến các trường hợp cạnh mà "hộp đen" đã giải quyết từ lâu nếu và chỉ khi tôi có nhu cầu cụ thể về ứng dụng (đồng bộ hóa một phần hoặc nhu cầu của người dùng- giải quyết xung đột tương tác, v.v.)
David Spillett

@DavidSpillett: Bạn đã sử dụng nhân rộng trong dự án đồng bộ hóa thời gian thực thành công chưa? Mối quan tâm chính của tôi là đồng bộ hóa thời gian thực và "khóa và chặn".
Emad Farrokhi

Câu trả lời:


14

Vâng tôi có thể không nhận được nó, nhưng tôi cố gắng trả lời nó.

Bạn nói rằng bạn cần một giải pháp hiệu suất cao chạy thường xuyên (tối thiểu tất cả 2 phút) và bạn cần một cách tiếp cận tốt, nhanh chóng mà không cần khóa. Nhưng bạn không muốn có một hệ thống hộp đen.

Thay vì một hệ thống hộp đen, được sử dụng trên hàng triệu cài đặt với kết quả tốt, bạn có thử phát minh lại bánh xe và xây dựng giải pháp của riêng mình không? Hừm, nghe hơi lạ.

Trong thực tế đây là những gợi ý của tôi.

  1. Nhân rộng ngay cả khi bạn nói bạn sẽ không sử dụng nó. Đây là giải pháp dễ nhất và tốt nhất bạn có thể sử dụng cho việc này. Bản sao dễ cài đặt, sao chép nhanh và bạn không phải phát minh lại bánh xe. Nếu bạn chỉ lạ về khóa, bạn có thể thử để thiết lập ISOLATION LEVELđể READ_COMMITTED_SNAPSHOT. Bạn có thể đọc thêm về nó ở đây . Điều này sẽ sử dụng hết một phần tempdb của bạn, nhưng bảng của bạn luôn có thể đọc và ghi được và bản sao có thể hoạt động ở chế độ nền.

Xem ví dụ dưới đây:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Change Data Capture) cũng có thể là một giải pháp. Nhưng theo cách này bạn cần phải tự mình xây dựng gần như mọi thứ. Và tôi đã tạo ra trải nghiệm CDCcó thể là một điều mong manh trong một số trường hợp. CDCsẽ thu thập tất cả dữ liệu trên một bảng đã xem (bạn cần chỉ định từng bảng được xem theo cách thủ công). Sau đó, bạn sẽ nhận được giá trị trước và giá trị sau một INSERT, UPDATEhoặc DELETE. CDCsẽ giữ lại những thông tin đó trong một khoảng thời gian (bạn có thể tự mình chỉ định thông tin đó). Cách tiếp cận có thể là sử dụng CDCtrên một số bảng nhất định mà bạn cần xem và sao chép thủ công những thay đổi đó sang cơ sở dữ liệu khác. Nhân tiện, cũng CDCsử dụng Bản sao máy chủ SQL dưới mui xe. ;-) Bạn có thể đọc thêm về nó ở đây .

Cảnh báo: CDCsẽ không nhận thức được các DDLtrao đổi. Điều này có nghĩa, nếu bạn thay đổi bảng và thêm một cột mới, CDCsẽ xem bảng nhưng bỏ qua tất cả các thay đổi đối với cột mới. Trong thực tế, nó chỉ ghi lại NULLnhư giá trị trước và giá trị sau. Bạn cần phải xác định lại nó sau DDL-Thay đổi vào một bảng đã xem.

  1. Cách bạn mô tả ở trên là một cái gì đó giống như nắm bắt một khối lượng công việc bằng SQL Server Profiler và chạy lại nó trên một cơ sở dữ liệu khác cho một số điểm chuẩn. Vâng, nó có thể làm việc. Nhưng thực tế là có quá nhiều tác dụng phụ là hơi quá nặng đối với tôi. Bạn sẽ làm gì nếu bạn thực hiện một cuộc gọi thủ tục trên máy khách của mình. Sau đó chạy cùng một lệnh tại cơ sở dữ liệu nguyên tắc của bạn vì nó không đồng bộ? Quy trình có thể chạy qua, nhưng nó có thể xóa / cập nhật / chèn các hàng không có trong máy khách của bạn. Hoặc làm thế nào để bạn xử lý nhiều khách hàng với một nguyên tắc. Tôi nghĩ rằng điều này là quá khó khăn. Trong trường hợp xấu nhất, bạn có thể phá hủy tính toàn vẹn của bạn.
  2. Một ý tưởng khác có thể dựa trên ứng dụng hoặc sử dụng kích hoạt. Tùy thuộc vào số lượng bảng bạn muốn được đồng bộ hóa. Bạn có thể viết tất cả các thay đổi vào một bảng phân tầng riêng biệt và chạy Công việc Tác nhân Máy chủ SQL tất cả x Phút để đồng bộ hóa các hàng đó trong bảng phân tầng với chủ của bạn. Nhưng điều này có thể hơi nặng nề nếu bạn cố gắng đồng bộ hóa (ví dụ) 150 bảng. Bạn sẽ có một chi phí lớn.

Vâng, đây là 2 xu của tôi. Hy vọng rằng bạn có một cái nhìn tổng quan tốt và có thể bạn đã tìm thấy một giải pháp phù hợp với bạn.


9

Tôi sẽ cố gắng liệt kê một số tùy chọn ở đây với những lợi thế và bất lợi khi tôi giải quyết chúng:

  1. Bản sao máy chủ SQL - đây là công cụ SQL Server gốc tốt nhất và được tối ưu hóa nhất cho tác vụ này. Nhưng có một số vấn đề: a. đối với tất cả khách hàng của bạn, bất kể họ có cơ sở dữ liệu SQL Express hay không, bạn sẽ cần giấy phép SQL Server CAL. Điều này có thể tránh được bằng cách sử dụng mỗi cấp phép bộ xử lý. b. Bạn không thể đồng bộ hóa máy khách SQL CE theo đây . c. SQL Express hoặc LocalDB không thể hoạt động như một nhà xuất bản hoặc nhà phân phối , do đó bạn có ít quyền kiểm soát khách hàng hơn trong quá trình sao chép.
  2. Microsoft Sync Framework - dường như phù hợp hơn với các cơ sở dữ liệu ứng dụng di động nhỏ hơn. Nó thêm khá nhiều bảng vào cơ sở dữ liệu của bạn và nó không hiệu quả như sao chép. Vì nó được triển khai bên ngoài SQL Server như một thành phần, nên sẽ khó cấu hình hơn. Tôi không có kinh nghiệm với nó, chỉ thử nó và quyết định không sử dụng nó.

  3. Theo dõi thay đổi cơ sở dữ liệu . Đây là một chức năng SQL Server tích hợp giúp bạn thay đổi theo dõi bao gồm chèn, cập nhật và xóa. Mọi thứ khác như gửi và áp dụng các thay đổi, giải quyết xung đột, v.v. bạn sẽ phải tự viết mã.

  4. Cột Rowversion (dấu thời gian) Nếu bạn không cho phép tất cả các lần xóa (không đồng bộ hóa các bản ghi bị xóa) - bạn có thể thực hiện giải pháp của riêng mình chỉ dựa trên thông tin chuyển hàng. Các cột Rowversion cũng được sử dụng bởi SQL Server Replication, vì vậy bạn sẽ cần thêm chúng bằng mọi cách.
  5. CDC như được đề cập trong câu trả lời của Ionic - Tôi không có kinh nghiệm với nó, vì nó chỉ có sẵn trong các phiên bản Enterprise hoặc Developer.

  6. Sử dụng thủ thuật của riêng bạn với việc ghi nhật ký các thủ tục được lưu trữ - phụ thuộc vào bản chất của ứng dụng cơ sở dữ liệu của bạn. Nhưng khi các thủ tục có chút khác biệt, ở đó bạn có thể nhận được một mớ hỗn độn lớn trong dữ liệu. Và làm thế nào bạn sẽ đối phó với xung đột?

Từ câu hỏi của bạn, có vẻ như bạn cần đồng bộ hóa chỉ vài bảng chứ không phải toàn bộ cơ sở dữ liệu lớn. Đối với mục đích này, bạn nên phân tích nhu cầu của bạn chi tiết hơn bạn đã chỉ định trong câu hỏi, như:

  • Có thể xóa xảy ra và những gì xảy ra sau đó?
  • Có thể xảy ra xung đột, làm thế nào để ngăn chặn chúng và làm thế nào để giải quyết chúng?
  • Làm thế nào tôi sẽ đối phó với thay đổi cấu trúc bảng?
  • ...

Nếu cuối cùng bạn phát hiện ra rằng việc xóa và xung đột không phải là vấn đề của bạn và cấu trúc của bạn sẽ không thay đổi nhiều, bạn có thể xem xét việc viết logic của riêng mình, nhưng nó có thể dễ dàng phát triển thành 1000 hàng mã.


2

Cảm ơn tất cả các phản hồi của bạn.

Tôi đã giải quyết thành công quá trình đồng bộ hóa bằng cách nắm bắt các thủ tục được lưu trữ đã thực hiện không phải là một bó mà từng bước một hoạt động rất tốt trong trường hợp của tôi. Vì tính toàn vẹn và mọi thứ được xem xét cẩn thận, hệ thống đã hoạt động theo thời gian thực cho đến nay.


Tuyệt vời tuy nhiên bạn có thể vui lòng giải thích chi tiết hơn những gì bạn đã làm. Bạn có chỉ cần ghi nhật ký các cuộc gọi của các thủ tục được lưu trữ đã được thực thi và lưu trữ chúng trong một số bảng / kịch bản tạm thời và có một công việc chạy tập lệnh này và đặt một trường (chẳng hạn như trường bit hoặc trường datetime nơi bạn nói cho TẤT CẢ các bản ghi chưa được xử lý xử lý chúng và cập nhật trường bit?) Tôi rất vui vì bạn đã giải quyết vấn đề của mình nhưng bạn cần cung cấp thêm thông tin chi tiết về những gì bạn đã làm để giúp người khác học?
JonH

0

Câu trả lời muộn nhưng nó có thể hữu ích cho khách truy cập chủ đề

Tôi gặp một thách thức tương tự khi cố gắng phân phối dữ liệu trên các máy chủ khác nhau và giải quyết nó bằng cách sử dụng các công cụ của bên thứ ba ( Diff cho thay đổi lược đồ và DataDiff để đồng bộ hóa thay đổi dữ liệu) và theo kịch bản PowerShell cần thiết để tự động hóa quy trình:

#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"
}

}

Phương pháp này lên lịch so sánh giữa hai cơ sở dữ liệu và đồng bộ hóa các thay đổi được tìm thấy trong thời gian thực. Dưới đây là một số bài viết cung cấp hướng dẫn từng bước:

https://solutioncenter.apexsql.com/automatically-compare-and-syn syncize-sql-server-data / https://solutioncenter.apexsql.com/how-to-automatically-keep-two-sql-server-database- lược đồ đồng bộ /

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.