Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Khắc phục sự cố sao chép giao dịch SQL Server

Sao chép giao dịch SQL Server là một trong những kỹ thuật nhân bản phổ biến nhất được sử dụng để sao chép hoặc phân phối dữ liệu qua nhiều đích.

Trong các bài trước, chúng ta đã thảo luận về SQL Server Replication, cách nó hoạt động bên trong và cách cấu hình Replication thông qua Replication Wizard hoặc cách tiếp cận T-SQL. Bây giờ, chúng tôi tập trung vào các vấn đề sao chép SQL và khắc phục sự cố một cách chính xác.

Sự cố sao chép SQL

Đa số khách hàng sử dụng SQL Server Transactional Replication chủ yếu tập trung vào việc đạt được dữ liệu gần thời gian thực có sẵn trong các phiên bản cơ sở dữ liệu Người đăng ký. Do đó, DBA quản lý Bản sao nên biết các vấn đề liên quan đến Sao chép SQL có thể có khác nhau có thể phát sinh. Ngoài ra, DBA phải có khả năng giải quyết những vấn đề này trong thời gian ngắn.

Chúng tôi có thể phân loại tất cả các vấn đề sao chép SQL thành các danh mục dưới đây (dựa trên kinh nghiệm của tôi):

Vấn đề về cấu hình

  • Kích thước sao chép văn bản tối đa
  • Dịch vụ SQL Server Agent chưa được đặt để khởi động chế độ Tự động
  • Các phiên bản Sao chép không được giám sát chuyển sang trạng thái Đăng ký chưa được khởi tạo
  • Các sự cố đã biết trong SQL Server

Vấn đề về quyền

  • Sự cố về quyền công việc của tác nhân SQL Server
  • Thông tin xác thực công việc của Snapshot Agent không thể truy cập đường dẫn của Thư mục Snapshot
  • Thông tin đăng nhập công việc của Log Reader Agent không thể kết nối với cơ sở dữ liệu Nhà xuất bản / phân phối
  • Thông tin công việc của Đại lý phân phối không thể kết nối với cơ sở dữ liệu phân phối / Người đăng ký

Sự cố kết nối

  • Máy chủ của nhà xuất bản không được tìm thấy hoặc không thể truy cập được
  • Không tìm thấy máy chủ phân phối hoặc không thể truy cập được
  • Không tìm thấy máy chủ người đăng ký hoặc không thể truy cập được

Vấn đề về tính toàn vẹn của dữ liệu

  • Lỗi vi phạm Khóa chính hoặc Khóa duy nhất
  • Lỗi Không tìm thấy hàng
  • Khoá ngoại hoặc các lỗi vi phạm ràng buộc khác

Vấn đề về hiệu suất

  • Các giao dịch đang hoạt động lâu dài trong cơ sở dữ liệu của nhà xuất bản
  • Thao tác CHÈN / CẬP NHẬT / XÓA hàng loạt trên Bài viết
  • Thay đổi dữ liệu lớn trong một Giao dịch duy nhất
  • Chặn trong cơ sở dữ liệu phân phối

Các vấn đề liên quan đến tham nhũng

  • Cơ sở dữ liệu của nhà xuất bản bị lỗi
  • Lỗi tệp Nhật ký giao dịch của nhà xuất bản
  • Lỗi cơ sở dữ liệu phân phối
  • Lỗi cơ sở dữ liệu người đăng ký

Chuẩn bị môi trường DEMO

Trước khi đi sâu vào chi tiết về các vấn đề SQL Replication, chúng ta cần chuẩn bị môi trường cho bản demo. Như đã thảo luận trong các bài viết trước của tôi, mọi thay đổi dữ liệu xảy ra trên cơ sở dữ liệu Người đăng ký trong Bản sao giao dịch sẽ không hiển thị trực tiếp với cơ sở dữ liệu Nhà xuất bản. Do đó, chúng tôi sẽ thực hiện một số sửa đổi trực tiếp trong cơ sở dữ liệu Người đăng ký cho mục đích học tập.

Hãy hết sức thận trọng và không sửa đổi bất kỳ điều gì trong Cơ sở dữ liệu sản xuất. Nó sẽ ảnh hưởng đến tính toàn vẹn Dữ liệu của cơ sở dữ liệu Người đăng ký. Tôi sẽ lấy các tập lệnh sao lưu cho mọi thay đổi được thực hiện và sẽ sử dụng các tập lệnh đó để khắc phục sự cố Sao chép SQL.

Thay đổi 1 - Chèn Bản ghi vào Bảng Person.ContactType

Trước khi chèn bản ghi vào Person.ContacType bảng, hãy xem cấu trúc bảng đó, một vài ràng buộc mặc định và thuộc tính mở rộng được biên dịch lại trong tập lệnh bên dưới:

CREATE TABLE [Person].[ContactType](
	[ContactTypeID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[Name] [dbo].[Name] NOT NULL,
	[ModifiedDate] [datetime] NOT NULL,
 CONSTRAINT [PK_ContactType_ContactTypeID] PRIMARY KEY CLUSTERED 
(
	[ContactTypeID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO

Tôi đã chọn bảng này vì nó có ít cột hơn. Nó là thuận tiện hơn cho các mục đích thử nghiệm. Bây giờ, hãy kiểm tra xem chúng ta có gì về cấu trúc của nó:

  • ContactTypeId được định nghĩa là CỘT IDENTITY - nó sẽ tự động tạo các giá trị Khóa chính và KHÔNG ĐỂ THAY THẾ.
  • NOT FOR REPLICATION là thuộc tính đặc biệt có thể được sử dụng trên nhiều loại Đối tượng khác nhau như Bảng, Ràng buộc như Ràng buộc khóa ngoại, Ràng buộc kiểm tra, Trình kích hoạt và cột Danh tính trên Nhà xuất bản hoặc Người đăng ký trong khi chỉ sử dụng bất kỳ phương pháp Sao chép nào. Nó cho phép DBA lập kế hoạch hoặc triển khai Nhân rộng để đảm bảo rằng một số chức năng nhất định hoạt động khác nhau trong Nhà xuất bản / Người đăng ký khi sử dụng Nhân bản.
  • Trong trường hợp của chúng tôi, chúng tôi hướng dẫn SQL Server sử dụng các giá trị IDENTITY chỉ được tạo trên cơ sở dữ liệu Publisher. Thuộc tính IDENTITY không được sử dụng cho Person.ContactType trong cơ sở dữ liệu Người đăng ký. Tương tự, chúng tôi có thể sửa đổi các Ràng buộc hoặc Trình kích hoạt để làm cho chúng hoạt động khác đi trong khi tính năng Sao chép được định cấu hình bằng tùy chọn này.
  • 2 cột NOT NULL khác có sẵn trong bảng.
  • Bảng có khóa chính được xác định trên ContactTypeId . Chỉ cần nhắc lại, khóa chính là một yêu cầu bắt buộc để sao chép. Nếu không có nó trên bảng, chúng tôi sẽ không thể sao chép một bài báo trên bảng.

Bây giờ, hãy CHÈN một bản ghi mẫu cho Người . ContactType trong AdventureWorks_REPL cơ sở dữ liệu:

CHÈN trực tiếp trên bảng sẽ không thành công trên cơ sở dữ liệu Người đăng ký vì Thuộc tính danh tính bị vô hiệu hóa chỉ để sao chép bởi tùy chọn NOT FOR REPLICATION. Bất cứ khi nào chúng tôi thực hiện thao tác INSERT theo cách thủ công, chúng tôi vẫn cần sử dụng tùy chọn SET IDENTITY_INSERT như sau:

 SET IDENTITY_INSERT AdventureWorks_REPL.Person.ContactType ON;

 INSERT INTO AdventureWorks_REPL.Person.ContactType(ContactTypeID, Name, ModifiedDate)
 VALUES (21, 'Test Position', GETDATE())
SET IDENTITY_INSERT AdventureWorks_REPL.Person.ContactType OFF;

Sau khi thêm tùy chọn SET IDENTITY_INSERT, chúng tôi có thể CHÈN bản ghi thành công vào Person.ContactType bảng.

Việc thực thi SELECT trên bảng sẽ hiển thị bản ghi mới được chèn:

Chúng tôi đã thêm một bản ghi mới chỉ vào cơ sở dữ liệu Người đăng ký không có sẵn trong cơ sở dữ liệu Nhà xuất bản trên Person.ContactType bảng.

Việc thực thi một CHỌN trên cùng một bảng của cơ sở dữ liệu Nhà xuất bản không hiển thị bất kỳ bản ghi nào. Do đó, bất kỳ thay đổi nào được thực hiện trên cơ sở dữ liệu Người đăng ký sẽ không được sao chép sang cơ sở dữ liệu Nhà xuất bản.

Thay đổi 2 - Xóa 2 Bản ghi khỏi Bảng Person.ContactType

Chúng tôi gắn bó với Person.ContactType quen thuộc của mình bàn. Trước khi xóa bản ghi khỏi cơ sở dữ liệu Người đăng ký, chúng tôi phải xác minh xem các bản ghi đó có tồn tại trên cả Nhà xuất bản và Người đăng ký hay không. Xem bên dưới:

Bây giờ, chúng tôi có thể xóa 2 ContactTypeId này sử dụng câu lệnh sau:

DELETE FROM AdventureWorks_REPL.Person.ContactType
WHERE ContactTypeID IN (19,20)

Tập lệnh trên cho phép chúng tôi xóa 2 bản ghi khỏi Person.ContactType trong cơ sở dữ liệu Người đăng ký:

Chúng tôi có tham chiếu khóa ngoài ngăn việc xóa 2 bản ghi này khỏi Person.ContactType bàn. Chúng ta có thể xử lý tình huống này bằng cách tạm thời vô hiệu hóa ràng buộc Khóa ngoại trên bảng con. Tập lệnh bên dưới:

ALTER TABLE [Person].[BusinessEntityContact] NOCHECK CONSTRAINT [FK_BusinessEntityContact_ContactType_ContactTypeID];

Sau khi các khóa ngoài bị vô hiệu hóa, chúng tôi có thể xóa thành công các bản ghi khỏi Person.ContactType bảng:

Điều này cũng đã sửa đổi ràng buộc Tham chiếu khóa ngoại trên 2 bảng. Chúng tôi có thể cố gắng mô phỏng các vấn đề sao chép SQL dựa trên tình huống này.

Trong tình huống hiện tại của chúng tôi, chúng tôi biết rằng Person.ContactType bảng không có dữ liệu được đồng bộ hóa giữa Nhà xuất bản và Người đăng ký.

Tin tôi đi, trong một số môi trường Sản xuất, các nhà phát triển hoặc DBA thực hiện một số bản sửa lỗi dữ liệu trên cơ sở dữ liệu Người đăng ký. giống như tất cả các thay đổi mà chúng tôi đã thực hiện trước đó đã gây ra các vấn đề về tính toàn vẹn của dữ liệu trên cơ sở dữ liệu Nhà xuất bản và Người đăng ký trong cùng một bảng. Là một DBA, tôi cần một cơ chế đơn giản hơn để xác minh những loại khác biệt này. Nếu không, nó sẽ khiến cuộc sống của DBA trở nên thảm hại.

Đây là giải pháp từ Microsoft cho phép chúng tôi xác minh sự khác biệt về dữ liệu giữa các bảng trong Nhà xuất bản và Người đăng ký. Có, bạn đoán đúng. Đó là tiện ích TableDiff mà chúng ta đã thảo luận trong các bài viết trước.

Tiện ích TableDiff

Tiện ích TableDiff chủ yếu được sử dụng trong môi trường Nhân bản. Chúng ta cũng có thể sử dụng nó cho các trường hợp khác mà chúng ta cần so sánh 2 bảng SQL Server về sự không hội tụ. Chúng ta có thể so sánh chúng và xác định sự khác biệt giữa 2 bảng này. Sau đó, tiện ích giúp đồng bộ hóa Điểm đến bảng tới Nguồn bảng bằng cách tạo các tập lệnh INSERT / UPDATE / DELETE cần thiết.

TableDiff là một chương trình độc lập tablediff.exe được cài đặt theo mặc định tại C:\ Program Files \ Microsoft SQL Server \ 130 \ COM sau khi chúng tôi đã cài đặt các thành phần nhân bản. Xin lưu ý rằng đường dẫn mặc định có thể thay đổi theo các tham số Cài đặt Máy chủ SQL. Số 130 trong đường dẫn cho biết phiên bản SQL Server (SQL Server 2016). Do đó, nó sẽ khác nhau đối với mọi phiên bản cài đặt SQL Server khác nhau.

Bạn có thể truy cập tiện ích TableDiff thông qua Command Prompt hoặc chỉ từ các tệp hàng loạt. Tiện ích không có Wizard hoặc GUI ưa thích để sử dụng. Cú pháp chi tiết của tiện ích TableDiff có trong bài viết MSDN. Bài viết hiện tại của chúng tôi chỉ tập trung vào một số tùy chọn cần thiết.

Để So sánh 2 bảng bằng tiện ích TableDiff, chúng tôi cần cung cấp các chi tiết bắt buộc cho bảng Nguồn và Bảng đích, chẳng hạn như Tên máy chủ nguồn, Tên cơ sở dữ liệu nguồn, Tên lược đồ nguồn, Tên bảng nguồn, Tên máy chủ đích, Tên cơ sở dữ liệu đích, Điểm đến Tên lược đồ và Tên Bảng Đích.

Hãy thử kiểm tra TableDiff với Person.ContactType bảng có sự khác biệt giữa Nhà xuất bản và Người đăng ký.

Mở Command prompt và điều hướng đến đường dẫn tiện ích TableDiff (nếu đường dẫn đó không được thêm vào các biến Môi trường).

Để xem danh sách tất cả các tham số có sẵn, hãy nhập lệnh “tablediff-?” để liệt kê tất cả các tùy chọn và thông số có sẵn. Kết quả như sau:

Hãy kiểm tra Người. Loại liên hệ trên cơ sở dữ liệu Nhà xuất bản và Người đăng ký của chúng tôi bằng cách chạy lệnh dưới đây:

tablediff -sourceserver RRJ -sourcedatabase AdventureWorks -sourceschema Person -sourcetable ContactType -destinationserver RRJ -destinationdatabase AdventureWorks_REPL -destinationschema Person -destinationtable ContactType

Lưu ý rằng tôi chưa cung cấp người dùng nguồn , chuacepassword , người dùng đích mật khẩu đích kể từ khi đăng nhập Windows của tôi có quyền truy cập vào các bảng. Nếu bạn muốn sử dụng Thông tin đăng nhập SQL thay vì Xác thực Windows, các tham số trên là bắt buộc để truy cập các bảng để so sánh . Nếu không, bạn sẽ nhận được lỗi.

Kết quả của việc thực thi lệnh chính xác:

Nó cho thấy rằng chúng ta có 3 điểm khác biệt. Một là bản ghi mới trong cơ sở dữ liệu Đích và hai bản ghi không có sẵn trong cơ sở dữ liệu Đích.

Bây giờ, chúng ta hãy xem nhanh phần Linh tinh khác các tùy chọn có sẵn cho tiện ích TableDiff.

  • -et - ghi tóm tắt kết quả vào bảng đích
  • -dt - bỏ bảng đích kết quả nếu nó đã tồn tại
  • -f - tạo tập lệnh T-SQL DML với các câu lệnh INSERT / UPDATE / DELETE để đưa bảng Đích đến hội tụ với bảng Nguồn.
  • -o - tên tệp đầu ra nếu tùy chọn -f được sử dụng để tạo tệp hội tụ.

Chúng tôi sẽ tạo một tệp hội tụ với -f -o các tùy chọn cho lệnh trước đó của chúng tôi:

tablediff -sourceserver RRJ -sourcedatabase AdventureWorks -sourceschema Person -sourcetable ContactType -destinationserver RRJ -destinationdatabase AdventureWorks_REPL -destinationschema Person -destinationtable ContactType -f -o C:\PersonContactType.sql

Tệp hội tụ được tạo thành công:

Như bạn có thể thấy, việc tạo tệp mới trong thư mục gốc của ổ C:không được phép vì lý do bảo mật. Do đó, nó hiển thị thông báo lỗi và tạo tệp đầu ra Tệp DIFFIX. *. Sql trong thư mục tiện ích TableDiff. Khi chúng tôi mở tệp đó, chúng tôi có thể thấy các chi tiết bên dưới:

Các tập lệnh INSERT được tạo cho 2 bản ghi đã xóa và các tập lệnh DELETE được tạo cho các bản ghi mới được chèn vào cơ sở dữ liệu Người đăng ký. Công cụ cũng quan tâm đến việc sử dụng các tùy chọn IDENTITY_INSERT theo yêu cầu cho Điểm đến bàn. Do đó, công cụ này sẽ rất được sử dụng bất cứ khi nào một DBA cần đồng bộ hóa hai bảng.

Trong trường hợp của chúng tôi, tôi sẽ không thực thi các tập lệnh, vì chúng tôi cần những khác biệt này để mô phỏng các vấn đề sao chép SQL của chúng tôi.

Ưu điểm của Tiện ích TableDiff

  • TableDiff là một tiện ích miễn phí nằm trong cài đặt các thành phần SQL Server Replication được sử dụng để so sánh hoặc hội tụ bảng.
  • Các tập lệnh tạo hội tụ có thể được tạo mà không cần can thiệp thủ công.

Hạn chế của Tiện ích TableDiff

  • Tiện ích TableDiff chỉ có thể được thực thi từ dấu nhắc lệnh hoặc tệp lô.
  • Từ dấu nhắc lệnh, bạn chỉ có thể thực hiện một phép so sánh bảng tại một thời điểm, trừ khi bạn có nhiều lời nhắc lệnh mở song song để so sánh nhiều bảng.
  • Bảng Nguồn mà bạn cần so sánh bằng cách sử dụng tiện ích TableDiff yêu cầu Khóa chính hoặc cột Danh tính được xác định hoặc cột ROWGUID có sẵn để thực hiện so sánh từng hàng. Nếu -strict tùy chọn được sử dụng, bảng Đích cũng yêu cầu Khóa chính hoặc cột Danh tính hoặc cột ROWGUID khả dụng.
  • Nếu bảng Nguồn hoặc bảng đích chứa sql_variant cột loại dữ liệu, bạn không thể sử dụng tiện ích TableDiff để so sánh nó.
  • Có thể nhận thấy các vấn đề về hiệu suất khi thực thi tiện ích TableDiff trên các bảng chứa các bản ghi lớn, vì nó sẽ thực hiện so sánh từng hàng trên các bảng này.
  • Các tập lệnh hội tụ được tạo bởi tiện ích TableDiff không bao gồm các cột kiểu dữ liệu ký tự BLOB, chẳng hạn như varchar (max) , nvarchar (tối đa) , varbinary (max) , văn bản , ntext hoặc hình ảnh cột và xml hoặc dấu thời gian cột. Do đó, bạn cần các phương pháp thay thế để xử lý các bảng có các cột kiểu dữ liệu này.

Tuy nhiên, ngay cả với những hạn chế này, tiện ích TableDiff có thể được sử dụng trên bất kỳ bảng SQL Server nào để xác minh dữ liệu nhanh chóng hoặc kiểm tra sự hội tụ. Tuy nhiên, bạn cũng có thể mua một công cụ tốt của bên thứ ba.

Bây giờ, chúng ta hãy xem xét các vấn đề khác nhau của SQL Replication một cách chi tiết.

Vấn đề về cấu hình

Từ kinh nghiệm của mình, tôi đã phân loại các tùy chọn Cấu hình sao chép thường bị bỏ lỡ có thể dẫn đến các vấn đề nghiêm trọng về Sao chép SQL dưới dạng Cấu hình vấn đề. Dưới đây là một số trong số chúng.

Kích thước sao chép văn bản tối đa

Kích thước bản đại diện văn bản tối đa đề cập đến Kích thước sao chép văn bản tối đa tính bằng byte . Nó áp dụng cho tất cả các kiểu dữ liệu như char (max), nvarchar (max), varbinary (max), text, ntext, varbinary, xml, hình ảnh .

SQL Server có tùy chọn mặc định để giới hạn độ dài cột kiểu dữ liệu chuỗi tối đa (tính bằng byte) được sao chép là 65536 byte.

Chúng ta cần đánh giá cẩn thận Kích thước bản sao văn bản tối đa bất cứ khi nào Bản sao được cấu hình cho cơ sở dữ liệu. Để làm được điều đó, chúng ta phải kiểm tra tất cả các cột kiểu dữ liệu ở trên và xác định số byte tối đa có thể sẽ được chuyển qua Replication.

Thay đổi giá trị thành -1 cho biết rằng không có giới hạn. Tuy nhiên, chúng tôi khuyên bạn nên đánh giá độ dài chuỗi tối đa và định cấu hình giá trị đó.

Chúng tôi có thể định cấu hình Kích thước Repl Văn bản Tối đa bằng SSMS hoặc T-SQL.

Trong SSMS, nhấp chuột phải vào tên Máy chủ> Thuộc tính > Nâng cao :

Chỉ cần nhấp vào 65536 để sửa đổi nó. Đối với các bài kiểm tra, tôi đã thay đổi 65536 thành 1000000 và nhấp vào OK :

Để định cấu hình tùy chọn Kích thước bản đại diện văn bản tối đa qua T-SQL, hãy mở cửa sổ truy vấn mới và thực thi tập lệnh bên dưới dựa trên cơ sở dữ liệu chính:

EXEC sys.sp_configure N'max text repl size (B)', N'-1'
GO
RECONFIGURE WITH OVERRIDE
GO

Truy vấn này sẽ cho phép Sao chép không giới hạn kích thước của các cột kiểu dữ liệu ở trên.

Để xác minh, chúng tôi có thể thực hiện CHỌN trên sys.configurations DMV và kiểm tra value_in_use cột như bên dưới:

Dịch vụ tác nhân máy chủ SQL không được đặt để bắt đầu chế độ tự động

Sao chép dựa trên Tác nhân nhân bản được thực thi dưới dạng công việc Tác nhân máy chủ SQL. Do đó, bất kỳ sự cố nào với một số Dịch vụ SQL Server Agent sẽ có ảnh hưởng trực tiếp đến chức năng Sao chép.

Chúng tôi cần đảm bảo rằng Chế độ khởi động của SQL Server và SQL Server Agent Services được đặt thành Tự động. Nếu được đặt thành Thủ công, chúng ta nên định cấu hình một số cảnh báo. Họ sẽ thông báo cho DBA hoặc Quản trị viên máy chủ khởi động Dịch vụ tác nhân máy chủ SQL khi Máy chủ khởi động lại những dịch vụ đã lên kế hoạch hoặc ngoài kế hoạch.

Nếu không được thực hiện, Bản sao có thể không chạy trong một thời gian dài, điều này cũng ảnh hưởng đến các công việc SQL Server Agent khác.

Phiên bản sao chép không được giám sát Đi vào trạng thái đăng ký chưa được khởi tạo

Tương tự như việc giám sát Dịch vụ tác nhân SQL Server, việc định cấu hình Dịch vụ thư cơ sở dữ liệu trong bất kỳ phiên bản SQL Server nào đóng một vai trò quan trọng trong việc cảnh báo DBA hoặc người được định cấu hình kịp thời. Đối với bất kỳ sự cố hoặc lỗi công việc nào, các công việc SQL Server Agent như Log Reader Agent hoặc Distribution Agent có thể được định cấu hình để gửi cảnh báo đến DBA hoặc thành viên nhóm tương ứng qua email. Việc thực thi công việc Replication Agent không thành công có thể dẫn đến các tình huống dưới đây:

Không thực hiện Công việc tác nhân đọc nhật ký . Tệp Nhật ký giao dịch của cơ sở dữ liệu Nhà xuất bản sẽ chỉ được sử dụng lại sau lệnh được đánh dấu để sao chép được đọc bởi Log Reader Agent và gửi thành công đến cơ sở dữ liệu phân phối. Nếu không, log_reuse_wait_desc cột sys.databases sẽ hiển thị giá trị dưới dạng Replication, cho biết rằng không thể sử dụng lại nhật ký cơ sở dữ liệu cho đến khi nó chuyển thành công các thay đổi sang cơ sở dữ liệu phân phối. Do đó, việc không thực thi tác nhân Trình đọc Nhật ký sẽ tiếp tục tăng kích thước của tệp Nhật ký Giao dịch của cơ sở dữ liệu Nhà xuất bản và chúng tôi sẽ gặp phải các vấn đề về hiệu suất trong quá trình Sao lưu đầy đủ hoặc các vấn đề về dung lượng đĩa trên phiên bản cơ sở dữ liệu Nhà xuất bản.

Không thực hiện Công việc Đại lý Phân phối. Công việc Đại lý phân phối đọc dữ liệu từ cơ sở dữ liệu phân phối và gửi đến cơ sở dữ liệu Người đăng ký. Sau đó, nó đánh dấu các bản ghi đó để xóa trong cơ sở dữ liệu phân phối. Nếu công việc của Đại lý phân phối không thực thi, nó sẽ làm tăng kích thước của cơ sở dữ liệu phân phối gây ra các vấn đề về hiệu suất đối với hiệu suất Nhân bản tổng thể. Theo mặc định, cơ sở dữ liệu phân phối được định cấu hình để lưu giữ các bản ghi tối đa là 0-72 giờ như được hiển thị trong thuộc tính Lưu giữ giao dịch bên dưới. Nếu quá trình tái tạo không thành công trong hơn 72 giờ, đăng ký tương ứng sẽ được đánh dấu là chưa được khởi tạo, buộc chúng tôi phải định cấu hình lại Đăng ký hoặc tạo ảnh chụp nhanh mới để Nhân rộng hoạt động trở lại.

Không thực hiện Dọn dẹp phân phối:công việc phân phối . Công việc dọn dẹp phân phối chịu trách nhiệm xóa tất cả các bản ghi được sao chép khỏi cơ sở dữ liệu phân phối để giữ cho kích thước cơ sở dữ liệu phân phối được kiểm soát. Việc không thực hiện công việc này dẫn đến kích thước cơ sở dữ liệu phân phối tăng lên dẫn đến các vấn đề về hiệu suất sao chép.

Để đảm bảo rằng chúng tôi không gặp phải bất kỳ sự cố nào chưa được giám sát này, Thư cơ sở dữ liệu phải được định cấu hình để báo cáo tất cả các lỗi hoặc thử lại công việc cho các thành viên trong nhóm tương ứng để có hành động kịp thời.

Sự cố đã biết trong SQL Server

Một số phiên bản SQL Server nhất định đã biết các sự cố sao chép trong phiên bản RTM hoặc các phiên bản trước đó. Các sự cố này đã được khắc phục trong các Gói dịch vụ hoặc gói CU. Do đó, chúng tôi khuyên bạn nên áp dụng gói Dịch vụ hoặc gói CU mới nhất khi đã có sẵn cho tất cả SQL Server sau khi thử nghiệm chúng trong môi trường QA. Mặc dù đây là khuyến nghị chung cho các máy chủ chạy SQL Server, nhưng nó cũng có thể áp dụng cho Replication.

Vấn đề về quyền

Trong môi trường với SQL Server Transactional Replication được định cấu hình, chúng ta có thể quan sát các vấn đề về Quyền thường xuyên. Chúng tôi có thể phải đối mặt với chúng trong thời gian cấu hình Nhân bản hoặc bất kỳ hoạt động Bảo trì nào trên Nhà xuất bản hoặc Nhà phân phối hoặc các phiên bản cơ sở dữ liệu Người đăng ký. Nó dẫn đến mất thông tin đăng nhập hoặc quyền. Bây giờ chúng ta hãy quan sát một số vấn đề về quyền thường xuyên liên quan đến Nhân bản.

Các vấn đề về quyền công việc của tác nhân SQL Server

Tất cả các tác nhân sao chép sử dụng công việc SQL Server Agent. Mỗi công việc SQL Server Agent liên quan đến Ảnh chụp nhanh hoặc Tác nhân đọc nhật ký hoặc Phân phối được thực thi dưới một số thông tin đăng nhập Windows hoặc SQL như được hiển thị bên dưới:

Để bắt đầu công việc SQL Server Agent, bạn cần có SQLAgentOperatorRole để bắt đầu tất cả công việc hoặc SQLAgentUserRole hoặc SQLAgentReaderRole để bắt đầu công việc mà bạn sở hữu. Nếu bất kỳ công việc nào không thể bắt đầu đúng cách, hãy kiểm tra xem chủ sở hữu công việc có các quyền cần thiết để thực hiện công việc đó hay không.

Thông tin công việc của tác nhân ảnh chụp nhanh không thể truy cập đường dẫn thư mục ảnh chụp nhanh

Trong các bài viết trước của chúng tôi, chúng tôi nhận thấy rằng việc thực thi tác nhân Ảnh chụp nhanh sẽ tạo ảnh chụp nhanh của các bài viết trong đường dẫn thư mục cục bộ hoặc thư mục chia sẻ để được truyền đến cơ sở dữ liệu Người đăng ký thông qua tác nhân phân phối. Vị trí đường dẫn Ảnh chụp nhanh có thể được xác định trong Thuộc tính xuất bản > Ảnh chụp nhanh :

Nếu tác nhân Ảnh chụp nhanh không có quyền truy cập vào vị trí tệp Ảnh chụp nhanh này, chúng tôi có thể nhận được lỗi:

Quyền truy cập vào đường dẫn ‘C:\ Program Files \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ repldata \ un \ XXXX \ YYYYMMDDHHMISS \’ bị từ chối.

Để giải quyết vấn đề, tốt hơn hết bạn nên cấp quyền truy cập đầy đủ vào đường dẫn thư mục C:\ Program Files \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ repldata \ un \ cho tài khoản mà Tác nhân Ảnh chụp nhanh thực thi. Trong cấu hình của chúng tôi, chúng tôi sử dụng tài khoản SQL Server Agent và SQL Server Agent Service đang chạy trong tài khoản RRJ \ RRJ.

Thông tin xác thực công việc của tác nhân đọc nhật ký không thể kết nối với cơ sở dữ liệu nhà xuất bản / phân phối

Tác nhân đọc nhật ký kết nối với cơ sở dữ liệu nhà xuất bản để thực thi sp_replcmds quy trình quét các giao dịch được đánh dấu để Sao chép từ nhật ký Giao dịch của cơ sở dữ liệu Nhà xuất bản.

Nếu chủ sở hữu cơ sở dữ liệu của cơ sở dữ liệu Nhà xuất bản không được đặt đúng cách, chúng tôi có thể nhận được các lỗi sau:

Quá trình không thể thực thi ‘sp_replcmds’ trên ‘RRJ.

Hoặc

Không thể thực thi với tư cách là phần tử chính của cơ sở dữ liệu vì “dbo” chính không tồn tại, loại phần tử chính này không thể bị mạo danh hoặc bạn không có quyền.

Để giải quyết vấn đề này, hãy đảm bảo rằng thuộc tính chủ sở hữu cơ sở dữ liệu của cơ sở dữ liệu Nhà xuất bản được đặt thành sa hoặc một tài khoản hợp lệ khác (xem bên dưới).

Nhấp chuột phải vào Nhà xuất bản cơ sở dữ liệu ( AdventureWorks )> Thuộc tính > Tệp . Đảm bảo rằng Chủ sở hữu trường được đặt thành sa hoặc bất kỳ thông tin đăng nhập hợp lệ nào và không trống .

Nếu bất kỳ vấn đề về quyền nào xảy ra khi chúng tôi đang kết nối với cơ sở dữ liệu Nhà xuất bản hoặc phân phối, hãy kiểm tra thông tin đăng nhập được sử dụng cho Tác nhân đọc nhật ký và cấp cho họ quyền để truy cập các cơ sở dữ liệu đó.

Thông tin công việc của Đại lý phân phối không thể kết nối với Cơ sở dữ liệu người đăng ký / phân phối

Đại lý phân phối có thể gặp vấn đề về quyền nếu tài khoản không được phép truy cập cơ sở dữ liệu phân phối hoặc kết nối với cơ sở dữ liệu Người đăng ký. Trong trường hợp này, chúng tôi có thể gặp các lỗi sau:

Không thể bắt đầu thực hiện bước 2 (lý do:Lỗi xác thực proxy RRJ \ RRJ, lỗi hệ thống:Tên người dùng hoặc mật khẩu không chính xác.)

Quá trình không thể kết nối với Người đăng ký ‘RRJ.

Đăng nhập không thành công cho người dùng ‘RRJ \ RRJ’.

Để giải quyết vấn đề này, hãy kiểm tra tài khoản được sử dụng trong Thuộc tính đăng ký và đảm bảo rằng tài khoản đó có các quyền cần thiết để kết nối với cơ sở dữ liệu Phân phối hoặc Người đăng ký.

Sự cố kết nối

Chúng tôi thường định cấu hình Nhân bản giao dịch trên các máy chủ trong cùng một mạng hoặc trên các vị trí được phân phối theo địa lý. Nếu cơ sở dữ liệu phân phối được đặt trên một máy chủ chuyên dụng ngoài Nhà xuất bản hoặc Người đăng ký, nó sẽ dễ bị mất gói mạng - sự cố kết nối.

Trong trường hợp có những vấn đề như vậy, nhân viên nhân bản (Trình đọc nhật ký hoặc Đại lý phân phối) có thể báo cáo các lỗi dưới đây:

Máy chủ nhà xuất bản không được tìm thấy hoặc không thể truy cập được

Máy chủ phân phối không được tìm thấy hoặc không thể truy cập được

Máy chủ người đăng ký không được tìm thấy hoặc không thể truy cập được

Để khắc phục những sự cố này, chúng tôi có thể thử kết nối với cơ sở dữ liệu Nhà xuất bản, Nhà phân phối hoặc Người đăng ký trong SSMS để kiểm tra xem liệu chúng tôi có thể kết nối với các phiên bản SQL Server này mà không gặp bất kỳ sự cố nào hay không.

Nếu sự cố kết nối xảy ra thường xuyên, chúng tôi có thể thử ping liên tục máy chủ để xác định bất kỳ mất gói nào. Ngoài ra, chúng tôi phải làm việc với các thành viên nhóm cần thiết để giải quyết những vấn đề đó và khởi động máy chủ để Replication tiếp tục truyền dữ liệu.

Các vấn đề về tính toàn vẹn của dữ liệu

Vì sao chép giao dịch là cơ chế một chiều, mọi thay đổi dữ liệu xảy ra trên Người đăng ký (theo cách thủ công hoặc từ ứng dụng) sẽ không được phản ánh cho Nhà xuất bản. Điều này có thể dẫn đến sự khác biệt về dữ liệu giữa Nhà xuất bản và Người đăng ký.

Hãy xem xét các vấn đề đó liên quan đến Tính toàn vẹn của dữ liệu và xem cách giải quyết chúng. Lưu ý rằng chúng tôi đã chèn một bản ghi vào Person.ContactType bảng và đã xóa 2 bản ghi khỏi Person.ContactType trong cơ sở dữ liệu Người đăng ký. Chúng tôi sẽ sử dụng 3 bản ghi này để tìm lỗi.

Các lỗi vi phạm khóa chính hoặc khóa duy nhất

Tôi sẽ kiểm tra bản ghi INSERT trên Person.ContactType bàn. Hãy chèn bản ghi đó vào cơ sở dữ liệu của Nhà xuất bản và xem điều gì sẽ xảy ra:

Khởi chạy Replication Monitor để xem nó diễn ra như thế nào. Chúng tôi gặp lỗi:

Mở rộng Nhà xuất bản Xuất bản , chúng tôi nhận được các chi tiết sau:

Nếu chúng tôi đã định cấu hình Cảnh báo sao chép và chỉ định những người tương ứng nhận cảnh báo qua thư của họ, chúng tôi sẽ nhận được thông báo qua email thích hợp với thông báo lỗi: Không thể chèn hàng khóa trùng lặp trong đối tượng 'Person.ContactType' với chỉ mục duy nhất 'AK_ContactType_Name ' . Giá trị khóa trùng lặp là (Vị trí Kiểm tra). (Nguồn:MSSQLServer, Số lỗi:2601)

Để giải quyết vấn đề liên quan đến vi phạm Khóa duy nhất hoặc Các vấn đề về khóa chính, chúng tôi có một số tùy chọn:

  • Phân tích lý do tại sao lại xảy ra lỗi này, cách bản ghi có sẵn trong cơ sở dữ liệu Người đăng ký và ai đã chèn bản ghi đó vì lý do gì. Xác định xem nó có cần thiết hay không.
  • Thêm bộ phận bỏ qua vào cấu hình Đại lý phân phối để bỏ qua Số lỗi 2601 hoặc Số lỗi 2627 trong trường hợp vi phạm Khóa chính.

Trong trường hợp của chúng tôi, chúng tôi đã cố tình chèn dữ liệu để nhận được lỗi này. Để xử lý vấn đề này, hãy xóa bản ghi được chèn theo cách thủ công đó để tiếp tục sao chép các thay đổi nhận được từ Nhà xuất bản.

DELETE from Person.ContactType
where ContactTypeID = 21

Để nghiên cứu các tùy chọn khác và so sánh sự khác biệt giữa hai cách tiếp cận này, tôi sẽ bỏ qua tùy chọn đầu tiên (hiệu quả và được khuyến nghị) và chuyển sang tùy chọn thứ hai bằng cách thêm -kiperrors tham số cho công việc Đại lý phân phối.

Chúng tôi có thể triển khai nó bằng cách chỉnh sửa Công việc đại lý phân phối > Các bước > nhấp vào 2 Bước công việc có tên Chạy tác nhân > nhấp vào Chỉnh sửa để xem lệnh có sẵn:

Bây giờ, thêm -SkipErrors 2601 cuối cùng (2601 là số lỗi - chúng tôi có thể bỏ qua bất kỳ số lỗi nào nhận được như một phần của Tái tạo) và nhấp vào OK .

Để đảm bảo rằng Công việc phân phối biết về sự thay đổi cấu hình này, chúng tôi cần khởi động lại công việc Đại lý phân phối. Đối với điều đó, hãy dừng nó lại và bắt đầu lại từ Bước 1 như được hiển thị bên dưới:

The Replication Monitor displays that one of the error records is skipped from the Replication, that started working fine.

Since the Replication issue is resolved successfully, we’d recommend removing the -SkipErrors parameter from the Distribution Agent job. Then, restart the job to get the changes reflected.

Thus, we’ve fixed the replication issue, but let’s compare the data across the same Person.ContactType in the Publisher and Subscriber databases. The results show the data variance, or the data integrity issue :

ModifiedDate is different across the Publisher and Subscriber databases. It happens because the data in the Subscriber database was inserted earlier (when we were preparing the test data), and the data in the Publisher database has just been inserted.

If we deleted the record from the Subscriber database, the record from the Publisher would have been inserted to match the data across the Publisher and the Subscriber databases.

Most of the newbie DBAs simply add the -SkipErrors option to get the replication working immediately without detailed investigations of the issue. Hence, it is recommended not to use the -SkipErrors option as a primary solution without proper examination of the problem. The Person.ContactType table had only 3 columns. Assume that the table has over 20 columns. Then, we have just screwed up the Data integrity of this table with that -SkipErrors lệnh.

We used this approach just to illustrate the usage of that option. The best way is to examine and clarify the reason for variance and then perform the appropriate DELETE statements on the Subscriber database to maintain the Data Integrity across the Publisher and Subscriber databases.

Row Not Found Errors

Let’s try to perform an UPDATE on one of the records that were deleted from the Subscriber database:

Let’s check the Replication Monitor to see the performance. We have the following error:

The row was not found at the Subscriber when applying the replicated UPDATE command for Table ‘[Person].[ContactType]’ with Primary Key(s):[ContactTypeID] =19 (Source:MSSQLServer, Error number:20598).

There are two ways to resolve this error. First, we can use -SkipErrors for Error Number 20598 . Or, we can INSERT the record with ContactTypeID =19 (shown in the error message) to get the data changes reflected.

If we skip this error, we’ll lose the record with ContactTypeId =19 from the Subscriber database permanently. It can cause data inconsistency issues. Hence, we aren’t going to use the -SkipErrors lựa chọn. Instead, we’ll apply the INSERT approach.

The Replication resumes correctly by sending the UPDATE to the Subscriber database.

It is the same when we try to delete the ContactTypeId =20 from the Publisher database and see the error popping up in the Replication Monitor.

The Replication Monitor shows us a message similar to the one we already noticed:

The row was not found at the Subscriber when applying the replicated DELETE command for Table ‘[Person].[ContactType]’ with Primary Key(s):[ContactTypeID] =20 (Source:MSSQLServer, Error number:20598)

Similar to the previous error, we need to identify the missing record and insert it back to the Subscriber database for the DELETE statement to get replicated properly. For DELETE scenario, using -SkipErrors doesn’t have any issues but can’t be considered as a safe option, as both missing UPDATE or missing DELETE record are captured with the same error number 20598 and adding -SkipErrors 20598 will skip applying all records from the Subscriber database.

We can also get more details about the problematic command by using the sp_browsereplcmds stored procedure which we have discussed earlier as well. Let’s try to use sp_browsereplcmds stored procedure for the previous error we have received out as shown below.

exec sp_browsereplcmds @xact_seqno_start = '0x000000A500001160000600000000'
			, @xact_seqno_end = '0x000000A500001160000600000000'
			, @publisher_database_id = 1
			, @command_id = 1

@xact_seqno_start and @xact_seqno_end will be the same value. We can fetch that value from the Transaction Sequence number in the Replication Monitor along with Command ID.

@publisher_database_id can be fetched from the id column of the distribution..MSPublisher_databases DMV.

select * from MSpublisher_databases 

Foreign Key or Other Constraint Violation Errors

The error messages related to Foreign keys or any other data issues are slightly different. Microsoft has made these error messages detailed and self-explanatory for anyone to understand what the issue is about.

To identify the exact command that was executed on the Publisher and resolve it efficiently, we can use the sp_browsereplcmds procedure explained above and identify the root cause of the issue.

Once the commands are identified as INSERT/UPDATE/DELETE which caused the errors, we can take corresponding actions to resolve the problems correctly which is more efficient compared to simply adding -SkipErrors approach. Once corrective measures are taken, Replication will start resuming fine immediately.

Word of Caution Using -SkipErrors Option

Those who are comfortable using -SkipErrors option to resolve error quickly should remember that -SkipErrors option is added at the Distribution agent level and applies to all Published articles in that Publication. Command -SkipErrors will result in skipping any number of commands related to that particular error across all published articles any number of times resulting in discrepancies we have seen in demo resulting in data discrepancies across Publisher and Subscriber without knowing how many tables are having discrepancies and would require efforts to compare the tables and fix it out.

Kết luận

Thanks for going through another robust article. I hope it was helpful for you to understand the SQL Server Transactional Replication issues and methods of troubleshooting them. In our next article, we’ll continue the discussion about the SQL Transaction Replication issues, examine other types, such as Corruption-related issues, and learn the best methods of handling them.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 3 cách lấy danh sách cơ sở dữ liệu trong SQL Server (T-SQL)

  2. Làm cách nào để tôi tham số hóa một chuỗi rỗng với DBNull. Giá trị rõ ràng và nhanh chóng

  3. Điều gì KHÔNG phải là toán tử logic trong SQL Server - Hướng dẫn sử dụng SQL Server / TSQL Phần 121

  4. @@ TEXTSIZE trong SQL Server là gì?

  5. Lệnh Sql JOIN có ảnh hưởng đến hiệu suất không?