両端で同じデータベース システムを使用し、レプリケーションを使用する
リモート エンドも PostgreSQL である場合、ホット スタンバイでストリーミング レプリケーションを使用して、リモート エンドをローカル エンドと透過的かつ自動的に同期させることができます。
ローカル エンドとリモート エンドの両方が MySQL である場合、binlog レプリケーションなどの MySQL のさまざまなレプリケーション機能を使用して、同様のことを行うことができます。
外部スクリプトを使用して同期する
外部スクリプトを使用しても問題はありません。実際、DBI-Link など (以下を参照) を使用している場合でも、 PgAgentpsql
を使用しない限り、おそらく cron ジョブから外部スクリプト (または ) を使用してレプリケーションを開始する必要があります。
トリガー プロシージャによって維持されるキュー テーブルに行を蓄積するか、新しい行のみを常に確実に選択するクエリを記述できることを確認してください。次に、ターゲット データベースとINSERT
新しい行に接続します。
コピーする行が大きすぎてメモリに快適に収まらない場合は、カーソルを使用してFETCHで行を読み取ることができます。これは、コピーする行が大きすぎてメモリに快適に収まらない場合に役立ちます。
私はこの順序で作業を行います:
- PostgreSQL に接続する
- MySQL に接続する
- PostgreSQL トランザクションを開始する
- MySQL トランザクションを開始します。MySQL が MyISAM を使用している場合は、今すぐ修正してください。
- おそらくカーソルを介して、または
DELETE FROM queue_table RETURNING *
- それらをMySQLに挿入します
DELETE
まだ行っていない場合は、PostgreSQL のキュー テーブルから行を取得します。
COMMIT
MySQL トランザクション。
- MySQL
COMMIT
が成功した場合COMMIT
、PostgreSQL トランザクション。失敗した場合はROLLBACK
、PostgreSQL トランザクションを再試行してください。
PostgreSQLCOMMIT
はローカル データベースであるため、失敗する可能性は非常に低いですが、完全な信頼性が必要な場合は、PostgreSQL 側で2 フェーズ コミットを使用できます。
PREPARE TRANSACTION
PostgreSQLで
COMMIT
MySQLで
- 次に、MySQL コミットの結果に応じて、
COMMIT PREPARED
またはPostgreSQL で。ROLLBACK PREPARED
これはニーズに対して複雑すぎる可能性がありますが、変更が両方のデータベースで発生するか、どちらのデータベースでも発生しないかを完全に確認する唯一の方法です。
ところで、真剣に、MySQL がMyISAMテーブル ストレージを使用している場合は、おそらくそれを修正する必要があります。クラッシュ時にデータが失われる可能性があり、トランザクションで更新することはできません。InnoDBに変換します。
PostgreSQL で DBI-Link を使用する
多分それは、私が PostgreSQL に慣れているからかもしれませんが、DBI リンク経由PL/Perlu
で仕事をする PostgreSQL 関数を使ってこれを行うでしょう。
レプリケーションが必要な場合は、DBI-Link を使用して MySQL データベースに接続し、キュー テーブルにデータを挿入するプロシージャを実行しPL/PgSQL
ます。PL/Perl
DBI-Link には多くの例が存在するため、ここでは繰り返しません。これは一般的な使用例です。
トリガーを使用して変更をキューに入れ、DBI リンクを使用して同期します
新しい行のみをコピーする必要があり、テーブルが追加専用である場合は、新しく編集されたすべての行をメイン テーブルと同じ定義を持つ別のキュー テーブルに追加するトリガー プロシージャを作成できます。INSERT
同期する場合は、同期手順を 1 回のトランザクションLOCK TABLE the_queue_table IN EXCLUSIVE MODE;
で実行し、データをコピーして、DELETE FROM the_queue_table;
. INSERT
これにより、 -only テーブルでのみ機能しますが、行が失われないことが保証されます。UPDATE
ターゲット テーブルでの処理DELETE
は可能ですが、はるかに複雑です。
外部データ ラッパーを使用して MySQL を PostgreSQL に追加する
あるいは、PostgreSQL 9.1 以降では、MySQL Foreign Data Wrapper、ODBC FDW、またはJDBC FDWを使用して、PostgreSQL がリモートの MySQL テーブルをローカル テーブルであるかのように認識できるようにすることを検討します。次に、書き込み可能な CTEを使用してデータをコピーできます。
WITH moved_rows AS (
DELETE FROM queue_table RETURNING *
)
INSERT INTO mysql_table
SELECT * FROM moved_rows;