1 デベジウムの概要
debezium は、変更データをキャプチャするためのオープンソースの分散プラットフォームです。データベースのすべての挿入、更新、削除操作に応答できます。
2 Debezium が PostgreSQL に接続する
debezium が PostgreSQL サーバーまたはクラスターに初めて接続するとき、コネクタはすべてのスキーマの一貫したスナップショットを取得します。スナップショットが完了すると、コネクタはデータベース コンテンツの挿入、更新、削除と、PostgreSQL データベースにコミットされた行レベルの変更を継続的にキャプチャします。
3 スナップショットの問題
3.1 引き起こされた質問
私はオフライン移行とオンライン移行をサポートする必要があるデータベース移行ツールに取り組んでいます。次に、オフライン マイグレーションとオンライン マイグレーションの境界点を決定する必要があり、境界点より前ではオフライン マイグレーションが使用され、境界点以降ではオフライン マイグレーションが使用されます。明らかに、PostgreSQL に接続された debezium によって生成されたスナップショットが境界点です。
-
debezium を使用して PostgreSQL で生成されたスナップショットに接続するにはどうすればよいですか?
debezium の公式ドキュメントを確認したところ、debezium には生成されたスナップショットをエクスポートするためのインターフェイスが提供されていないことがわかりました。
3.2 この問題を解決しようとする試み - 失敗
debezium 接続 PostgreSQL debezium ログに、スナップショットが出力されます。
-
postgresデータベースで出力されたスナップショットを使用しようとしています。
結果: エラーが報告され、そのようなスナップショットは存在しません。
3.3 postgres スナップショット
トランザクション A を開始すると、トランザクション A でスナップショット P を作成できます。トランザクション A がコミットされると、スナップショット P は自動的に削除されます。
-
postgres スナップショットの作成をテストする
-
取引を開始する
begin;
-
スナップショットを作成する
SELECT pg_export_snapshot();
コンソールはスナップショットを出力します。
pg_export_snapshot --------------------- 00000003-00004E71-1 (1 row)
-
スナップショットを使用する
pg_dump ツールを使用してデータを postgres にエクスポートします。スナップショットがパラメータとして使用されます。
pg_dump -a "postgres" --snapshot=00000003-00004E71-1 > pg.sql
スナップショットは正常に使用できます
-
トランザクションをコミットする
commit;
-
スナップショットを再度使用する
pg_dump -a "postgres" --snapshot=00000003-00004E71-1 > pg.sql
エラー:
pg_dump: error: query failed: ERROR: invalid snapshot identifier: "00000003-00004E71-1" pg_dump: error: query was: SET TRANSACTION SNAPSHOT '00000003-00004E71-1'
理由: スナップショット「00000003-00004E71-1」は、トランザクションがコミットされたときに postgres データベースによって削除されました。
-
-
2.2でスナップショットエラーを使用する理由を推測してください
トランザクションが送信され、debezium の postgresql への接続中に作成されたスナップショットが postgres データベースによって削除されました
4 スナップショットの問題解決
4.1 debezium を postgres に接続してスナップショットを作成するプロセス
debezium のソース コードと、debezium が postgres に接続するプロセス中に生成される postgres データベース ログを表示すると、debezium が postgres に接続してスナップショットを作成するプロセスが明確になります。
具体的なプロセスは次のとおりです。
-
debezium が postgres データベースの walsender スレッドに接続します
-
Debezium は、レプリケーション スロットの作成を要求するメッセージを postgres に送信します。
-
postgresのクリーンアップスナップショット
walsender スレッドは、メッセージを受信するたびにスナップショットをクリーンアップします。もちろん、この時点ではスナップショットは作成されておらず、クリーンアップするスナップショットもありません。
-
postgres はレプリケーション スロットを作成し、同時にスナップショット P を作成します。
-
Debezium は次のメッセージを postgres に送信します
-
postgresのクリーンアップスナップショット
4.2 解決策
-
解決
debezium が次のメッセージを送信する前 (スナップショットが削除される前) に、スナップショットを使用するように debezium ソース コードを変更します。
-
debeziumのソースコードを変更する方法
io.debezium.connector.postgresql.snapshot.QueryingSnapshotter.java を変更して、スナップショット処理のコードを追加します。
@Override public String snapshotTransactionIsolationLevelStatement(SlotCreationResult newSlotInfo) { if (newSlotInfo != null) { /* *快照为:newSlotInfo.snapshotName() *add your own code */ String snapSet = String.format("SET TRANSACTION SNAPSHOT '%s';", newSlotInfo.snapshotName()); return "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; \n" + snapSet; } return Snapshotter.super.snapshotTransactionIsolationLevelStatement(newSlotInfo); }
4.3 削減結合スキーム
-
4.2 の解決策は debezium ソース コードを変更する必要があり、結合度は非常に高くなります。
-
debezium は、ユーザーがカスタム スナップショットを実装するためのインターフェイスを提供します
スナップショット モードでは
custom
、Java spi メカニズムを使用して、独自の実装されたインターフェイスを挿入できますio.debezium.connector.postgresql.spi.Snapshotter
。 -
結合低減スキームの具体的な実装
-
新しい mvn プロジェクト
プロジェクト例 https://www.aliyundrive.com/s/vPMNvLGeAGY
-
io.debezium.connector.postgresql.spi.Snapshotter
インターフェースを実装するプロジェクトの例では、debezium がデータベース内のすべてのテーブルを走査することを禁止し、ローカル シェル スクリプトを実行するためのパラメーターとしてスナップショットを使用しました。
-
設定ファイルの追加
resource ディレクトリの下に新しい META-INF/services ディレクトリを作成し、このディレクトリ内に上記のインターフェイスの完全修飾名と一致する新しいファイルを作成し、実装クラスの完全修飾名を記述する必要があります。このファイルのインターフェイス。
-
-
コンパイルとパッケージ化
mvn clean
mvn install
mvn package
-
パッケージ化された jar パッケージを debezium-connector-postgres ディレクトリにコピーします
-
debeziumコネクタ構成ファイルを変更する
プロジェクトの例では、次の内容を構成ファイルに追加します。
"snapshot.mode":"custom" "snapshot.custom.class":"io.debezium.connector.postgresql.snapshot.PgDumpSnapshotter"
-