Manage Sequences in pglogical Replication for Disaster Recovery Setup in OCI Database with PostgreSQL
はじめに
このチュートリアルでは、プライマリ・システムとディザスタ・リカバリ(DR)システム間の論理双方向レプリケーション設定でPostgreSQL順序値を同期するためのカスタム・ソリューションの概要を示します。
問題の内容:
現在のセットアップでは、pglogical bidirectional replicationを構成しました。一部のレプリケート表は順序に依存しますが、これらの順序のlast_value
がプライマリ環境とDR環境の間でレプリケートされないことがわかりました。
これは想定された動作であり、pglogicalのバグとはみなされません。設計上、順序は非トランザクションとみなされ、本質的に競合を回避するためにノード固有とみなされるため、順序値はレプリケートされません。
このギャップに対処するために、プライマリ・システムとDRシステムの間で順序値を同期するカスタム・ソリューションを実装しました。具体的には、次のような手順を開発しています。
-
プライマリ・データベースから各関連順序の
last_value
を取得します。 -
プライマリと一致するように、DR側の対応するシーケンスを更新します。
-
pg_cron
拡張子を使用して、1分ごとに自動的に実行されます。
このアプローチにより、順序値が両方のシステム間で一貫性が保たれるようになるため、主にDR環境での潜在的なデータの整合性や競合の問題が回避されます。
目的
- PostgreSQLOCI Database with PostgreSQLを使用したOCI DatabaseでのDR設定のpglogicalレプリケーションの順序の管理。
タスク1: pglogical双方向レプリケーションの設定
プライマリシステムとDRシステム間でpglogical双方向レプリケーションがすでに構成されていることを確認します。
まだ構成されていない場合は、公式ドキュメントに従って、「ソース・データベースでのpglogical Extension Replicationの設定」に従ってpglogical
を設定します。
タスク2: 必須拡張の有効化
プライマリ・システムとDRシステムの両方で、OCIコンソールから構成を作成して、次の拡張を有効にします。
-
pg_cron
-
dblink
DBSystemsに構成ファイルを適用したら、各DBSystemのpostgres
データベースに接続し、次の問合せを実行します。
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS dblink;
タスク3: 手順の作成
postgres
データベースで、プライマリ・システムとDRシステムの両方にプロシージャを作成します。
プロシージャ定義:
CREATE OR REPLACE PROCEDURE sync_sequences_from_remote()
LANGUAGE plpgsql
AS $$
DECLARE
-- Update the connection string with correct credentials and hostname
conn_str TEXT := 'host=<hostname> user=<username> password=<password> dbname=postgres';
row RECORD;
remote_seq_query TEXT :=
$_$SELECT schemaname, sequencename, last_value
FROM pg_sequences
WHERE schemaname !~ 'pg_catalog|cron|information_schema|pg_toast|pg_temp'
AND last_value IS NOT NULL$_$;
full_seq_name TEXT;
setval_sql TEXT;
BEGIN
FOR row IN
SELECT * FROM dblink(conn_str, remote_seq_query)
AS t(schemaname TEXT, sequencename TEXT, last_value BIGINT)
LOOP
full_seq_name := quote_ident(row.schemaname) || '.' || quote_ident(row.sequencename);
setval_sql := FORMAT('SELECT setval(%L, %s, true);', full_seq_name, row.last_value);
RAISE NOTICE 'Setting sequence: %', setval_sql;
EXECUTE setval_sql;
END LOOP;
END;
$$;
ノート:
<hostname>
、<username>
および<password>
を実際の値で安全に置換します。<hostname>
を使用して、DBシステムのFQDNを表します。
タスク4: DRシステムでのpg_cron
ジョブの作成
次の問合せを実行して、pg_cron
ジョブを作成し、DRデータベース・システムで1分ごとに実行するプロシージャをスケジュールします。
SELECT cron.schedule('UPDATE SEQUENCE', '*/1 * * * *', $$ CALL sync_sequences_from_remote(); $$);
ノート:
pg_cron
ジョブがDRでのみ有効であることを確認します。- 必要に応じてジョブ・スケジュールを調整します。
タスク5: プライマリ・システムでのpg_cron
ジョブの作成と無効化の維持
次の問合せを実行して、pg_cron
ジョブを作成し、無効にします。
SELECT cron.schedule('*/1 * * * *', $$ CALL sync_sequences_from_remote() $$);
-- Disable the job (on Primary)
SELECT cron.alter_job(jobid := <job_id>, active := false);
タスク6: フェイルオーバーの処理
フェイルオーバーが発生した場合は、次のステップに従います。
-
新しいDR (以前のプライマリ)で、
pg_cron
ジョブを有効にします。 -
新しいプライマリ(以前のDR)で、
pg_cron
ジョブを無効化します。
これにより、同期プロセスは常に現在のDRシステムでのみ実行されます。
ノート:
有用なコマンド:
-- List all scheduled jobs and get job ID SELECT jobid, schedule, command, active FROM cron.job; -- Disable a job SELECT cron.alter_job(jobid := <job_id>, active := false); -- Enable a job SELECT cron.alter_job(jobid := <job_id>, active := true);
環境固有の要件に基づいてプロシージャおよびジョブ定義を調整します。
本番環境にデプロイする前に、開発環境で手順を十分にテストします。
関連リンク
確認
- 作者 - Arvind Yadav氏(プリンシパル・メンバーのテクニカル・スタッフ)
その他の学習リソース
docs.oracle.com/learnで他のラボを確認するか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスして、Oracle Learning Explorerになります。
製品ドキュメントについては、Oracle Help Centerを参照してください。
Manage Sequences in pglogical Replication for Disaster Recovery Setup in OCI Database with PostgreSQL
G39330-01
Copyright ©2025, Oracle and/or its affiliates.