SQL Server CDCでの変更の日時のキャプチャ


8

そこで、本番データベースの1つで変更データキャプチャを使用して調査を開始しました。各変更の日時を知りたいのですが。ウォークスルーやチュートリアルなどを読むと、標準的なアプローチは、LSNを使用してcdc.lsn_time_mappingシステムテーブルに関連付けることです。このアプローチは機能しますが、1日に数十万の変更について話す場合、それほど単純ではなく、効率的でもありません。

テスト環境で、変更トラックテーブルに次の調整を行いました。ALTER TABLE末尾に列を追加するステートメントを発行し、[__ChangeDateTime]それをデフォルト値にしましたGetDate()。アプローチは機能しているようですが、変更の追跡は引き続き正常に機能し、日時が取得されています。 しかし、システムテーブルをいじくり回すと、少し緊張します。

これがMicrosoftが最初から追加しシステムフィールドでない場合は、理由があったはずです。代わりに、LSNからcdc.lsn_time_mappingへのアプローチを選択したので、この方法で独自のハックを作成することで、問題に備えていますか?

更新:

テスト中にGetDate()が時々私たちのニーズに対して十分に正確ではないことが発見されました-同じ時間を共有する複数の変更。sysdatetime()およびdatetime2を使用して値をナノ秒に移動することをお勧めします。2008+のオプションのみ明らかに。

回答:


8

CDCはログリーダーエージェントを使用して変更テーブルにデータを入力することに注意してください。なぜそれが重要なのですか?そのメカニズムにより、行は変更テーブルに、基本テーブルで行われた変更とは非同期で表示されます。

実際には、新しい順に記録できる3つの異なる時点があります。

  1. 変更が変更テーブルに配信された時刻(記録しているもの)。
  2. コミットされた変更を含むトランザクションの時間(を使用してcdc.lsn_time_mapping)。
  3. (デフォルトの制約、トリガーなどを使用して)ベーステーブルの列に手動でデータを入力した時間。

したがって、最初に録音する内容を明確にする必要があります。通常、#2または#3のいずれかを考慮します。

LSNマッピングメカニズム(#2)で十分なパフォーマンスが得られない場合、サポートされている唯一の方法は、ベーステーブルに列を追加して自分で設定することです(#3)。

内部テーブルの変更に関しては、ポリシーの問題として、サポートされている代替手段がある場合は内部でハッキングしないことをお勧めします。最後に必要なのは、重要な生産システムがダウンし、製品サポートに連絡する必要があり、このような理由でサービスが拒否されることです。物事を破壊する可能性(アップグレード)や、予期しないことで破壊される(他の回答で述べたように、CDCをオフにしてから再びオンにする)ことを気にしないでください。


3

実用的な例:

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');

この回答は、あなたが何をしているか、そしてそれが関連する理由を説明するいくつかのコメントから利益を得るでしょう。
Erik

2

私が与える唯一の警告は、これらのテーブルがCDCが無効になると自動的に削除されることです。更新可能になったときに列が自動的に再作成されない

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.