Nắm bắt thời gian thay đổi trong SQL Server CDC


8

Vì vậy, chúng tôi đã bắt đầu khám phá bằng cách sử dụng dữ liệu thay đổi trên một trong các cơ sở dữ liệu sản xuất của chúng tôi. Chúng tôi muốn biết thời gian của mỗi thay đổi. Đọc qua các hướng dẫn và hướng dẫn, vv có vẻ như cách tiếp cận tiêu chuẩn là sử dụng LSN để liên quan đến cdc.lsn_time_mappingbảng hệ thống. Cách tiếp cận này hoạt động nhưng không đơn giản và cũng không hiệu quả khi nói về 100 ngàn thay đổi mỗi ngày.

Trong môi trường thử nghiệm, tôi đã thực hiện điều chỉnh sau cho các bảng theo dõi thay đổi. Tôi đã đưa ra một ALTER TABLEtuyên bố để thêm một cột vào cuối được gọi [__ChangeDateTime]và làm cho nó có giá trị mặc định GetDate(). Cách tiếp cận dường như hoạt động, theo dõi thay đổi vẫn hoạt động bình thường, thời gian đang được nắm bắt. Nhưng mucking xung quanh với các bảng hệ thống làm cho tôi một chút lo lắng.

Nếu đây không phải là một lĩnh vực hệ thống mà Microsoft đã thêm từ đầu, họ phải có lý do của họ. Vì thay vào đó họ đã chọn cách tiếp cận LSN thành cdc.lsn_time_mapping, tôi có tự đặt ra vấn đề bằng cách tạo bản hack của riêng mình theo cách này không?

CẬP NHẬT:

Được phát hiện trong quá trình kiểm tra rằng đôi khi GetDate () không đủ chính xác cho nhu cầu của chúng tôi - nhiều thay đổi chia sẻ cùng một lúc. Đề xuất sử dụng sysdatetime () và datetime2 để di chuyển giá trị ra nano giây. Tùy chọn cho năm 2008+ chỉ rõ ràng.

Câu trả lời:


7

Hãy nhớ rằng CDC sử dụng một tác nhân đọc nhật ký để điền vào bảng thay đổi. Tại sao điều đó quan trọng? Theo cơ chế đó, các hàng hiển thị trong các bảng thay đổi không đồng bộ với các thay đổi được thực hiện trong các bảng cơ sở.

Thực tế, có 3 điểm thời gian khác nhau có thể được ghi lại, theo thứ tự thời gian đảo ngược:

  1. Thời gian thay đổi được gửi đến bảng thay đổi (đó là những gì bạn đang ghi).
  2. Thời gian giao dịch có chứa thay đổi đã cam kết (sử dụng cdc.lsn_time_mapping).
  3. Thời gian bạn điền thủ công một cột trong bảng cơ sở (sử dụng ràng buộc mặc định, kích hoạt, v.v.).

Vì vậy, điều đầu tiên là phải rõ ràng về những gì bạn muốn ghi lại. Thông thường chúng tôi sẽ quan tâm đến # 2 hoặc # 3.

Nếu cơ chế ánh xạ LSN (# 2) không hoạt động đủ tốt cho bạn, thì phương án duy nhất được hỗ trợ là thêm một cột vào bảng cơ sở và tự điền vào đó (# 3).

Liên quan đến việc thay đổi các bảng nội bộ, như là một vấn đề của chính sách, tôi nghĩ tốt nhất là tránh hack xung quanh với các bên trong khi có các lựa chọn thay thế được hỗ trợ. Điều cuối cùng bạn muốn là một hệ thống sản xuất quan trọng sẽ ngừng hoạt động, cần phải gọi Hỗ trợ sản phẩm và bị từ chối dịch vụ vì những thứ như thế này. Đừng bao giờ bận tâm đến các vấn đề của nó có khả năng phá vỡ mọi thứ (nâng cấp) hoặc bị hỏng vì không mong muốn (tắt CDC, sau đó bật lại, như đã đề cập trong câu trả lời khác).


3

Một ví dụ thực tế:

USE Database;
GO

DECLARE @from_lsn binary(10), @to_lsn binary(10)
SET @from_lsn = sys.fn_cdc_get_min_lsn('schema_tablename')
SET @to_lsn = sys.fn_cdc_get_max_lsn()

SELECT
    sys.fn_cdc_map_lsn_to_time(__$start_lsn) AS 'Time'
    ,[Field1]
    ,[Field2]
    ,[Field3]
FROM [cdc].[fn_cdc_get_all_changes_schema_tablename]
  (@from_lsn, @to_lsn, N'all');

Câu trả lời này sẽ có lợi từ một số ý kiến ​​giải thích những gì bạn đang làm và tại sao nó có liên quan.
Erik

2

Nhắc nhở duy nhất tôi sẽ đưa ra là những bảng đó sẽ tự động bị hủy khi CDC bị vô hiệu hóa. Cột không được tạo lại tự động khi bạn có thể đổi tên

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.