このガイドでは、PeerDB を使用して PostgreSQL データベースを ClickHouse Managed Postgres に移行する方法を、手順を追って説明します。
ベータ前提条件
- ソース PostgreSQL データベースへのアクセス。
- データの移行先となる ClickHouse Managed Postgres インスタンス。
- マシンに PeerDB がインストールされていること。PeerDB GitHub リポジトリ のインストール手順に従ってください。必要なのは、リポジトリをクローンして
docker-compose upを実行することだけです。このガイドでは PeerDB UI を使用します。PeerDB の起動後、http://localhost:3000からアクセスできます。
移行前の考慮事項
移行を開始する前に、次の点を考慮してください。
- データベースオブジェクト: PeerDB は、ソーススキーマに基づいてターゲットデータベースにテーブルを自動作成します。ただし、索引、制約、トリガーなど、一部のデータベースオブジェクトは自動では移行されません。これらのオブジェクトは、移行後にターゲットデータベース側で手動で再作成する必要があります。
- DDL の変更: 継続的レプリケーションを有効にすると、PeerDB は DML 操作 (INSERT、UPDATE、DELETE) についてターゲットデータベースをソースと同期した状態に保ち、ADD COLUMN 操作も反映します。ただし、その他の DDL の変更 (DROP COLUMN、ALTER COLUMN など) は自動では反映されません。スキーマ変更のサポートの詳細はこちらを参照してください。
- ネットワーク接続: ソースデータベースとターゲットデータベースの両方に対して、PeerDB が実行されているマシンから到達できることを確認してください。接続を許可するには、ファイアウォールルールまたはセキュリティグループの設定が必要になる場合があります。
ピアを作成する
まず、ソースデータベースとターゲットデータベースの両方に対してピアを作成する必要があります。ピアは、データベースへの接続を表します。PeerDB UI で、サイドバーの「Peers」をクリックして「Peers」セクションに移動します。新しいピアを作成するには、+ New peer ボタンをクリックします。
ソースピアの作成
ホスト、ポート、データベース名、ユーザー名、パスワードなどの接続情報を入力して、ソース PostgreSQL データベース用のピアを作成します。入力が完了したら、Create peer ボタンをクリックしてピアを保存します。

ターゲットピアの作成
同様に、必要な接続情報を指定して、ClickHouse Managed Postgres インスタンス用のピアを作成します。インスタンスの接続情報は、ClickHouse Cloudコンソールから取得できます。詳細を入力したら、Create peer ボタンをクリックしてターゲットピアを保存します。

これで、"Peers" セクションにソースピアとターゲットピアの両方が表示されるはずです。

ソーススキーマのダンプを取得する
ソースデータベースの構成をターゲットデータベースに再現するには、ソースデータベースのスキーマダンプを取得する必要があります。pg_dump を使うと、ソース PostgreSQL データベースのスキーマのみのダンプを作成できます。
pg_dump のインストール
Ubuntu:
パッケージリストを更新します:
sudo apt updatePostgreSQL クライアントをインストールします:
sudo apt install postgresql-clientmacOS:
方法 1: Homebrew を使用する (推奨)
Homebrew がインストールされていない場合は、次のコマンドでインストールします:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"PostgreSQL をインストールします:
brew install postgresqlインストールを確認します:
pg_dump --versionpg_dump -d 'postgresql://<user>:<password>@<host>:<port>/<database>' -s > source_schema.sqlスキーマダンプから一意制約と索引を削除する
これをターゲットデータベースに適用する前に、これらの制約によって PeerDB からターゲットテーブルへのインジェストが妨げられないよう、ダンプファイルから UNIQUE 制約と索引を削除する必要があります。削除には次を使用できます。
# プレビュー
grep -n "CONSTRAINT.*UNIQUE" <dump_file_path>
grep -n "CREATE UNIQUE INDEX" <dump_file_path>
grep -n -E "(CONSTRAINT.*UNIQUE|CREATE UNIQUE INDEX)" <dump_file_path>
# 削除
sed -i.bak -E '/CREATE UNIQUE INDEX/,/;/d; /(CONSTRAINT.*UNIQUE|ADD CONSTRAINT.*UNIQUE)/d' <dump_file_path>スキーマダンプをターゲットデータベースに適用する
スキーマダンプファイルを整理したら、psql で接続し、スキーマダンプファイルを実行して、ターゲットの ClickHouse Managed Postgres データベースに適用できます。
psql -h <target_host> -p <target_port> -U <target_username> -d <target_database> -f source_schema.sqlターゲット側では、外部キー制約によって PeerDB のインジェストが妨げられないようにします。そのため、ターゲットのロール (上記でターゲットピアに使用したもの) を変更して、session_replication_role を replica に設定できます。
ALTER ROLE <target_role> SET session_replication_role = replica;ミラーを作成する
次に、ソースピアとターゲットピア間のデータ移行プロセスを定義するため、ミラーを作成します。PeerDB UI で、サイドバーの "Mirrors" をクリックして "Mirrors" セクションに移動します。新しいミラーを作成するには、+ New mirror ボタンをクリックします。

- 移行内容が分かる名前をミラーに付けます。
- ドロップダウンメニューから、先ほど作成したソースピアとターゲットピアを選択します。
- 次のことを確認します。
- Soft delete が OFF になっていること。
Advanced settingsを展開し、Postgres type system が有効で、PeerDB columns が無効になっていることを確認します。

- 移行するテーブルを選択します。特定のテーブルを選ぶことも、ソースデータベース内のすべてのテーブルを選ぶこともできます。

- ミラーの設定が完了したら、
Create mirrorボタンをクリックします。
"Mirrors" セクションに、新しく作成したミラーが表示されます。

初期ロードを待つ
ミラーを作成すると、PeerDB はソースからターゲットデータベースへの初期データロードを開始します。ミラーをクリックし、初期ロード タブを開くと、初期データ移行の進捗を確認できます。

初期ロードが完了すると、移行が完了したことを示すステータスが表示されます。
初期ロードとレプリケーションの監視
ソースピアをクリックすると、PeerDB が実行中のコマンド一覧を確認できます。たとえば、次のとおりです。
- まず、各テーブルの行数を見積もるために COUNT クエリを実行します。
- 次に、NTILE を使用したパーティション化クエリを実行し、大きなテーブルを効率的に転送できるよう、より小さな chunk に分割します。
- その後、FETCH コマンドを実行してソースデータベースからデータを取得し、PeerDB がそれらをターゲットデータベースに同期します。
移行後の作業
移行が完了したら、次の作業を実施します。
- カットオーバー前の検証を実行する
トラフィックを切り替える前に、ソース側とターゲット側の主要なテーブルを比較します。
-- 重要なテーブルの行数比較
SELECT 'public.orders' AS table_name, COUNT(*) AS row_count FROM public.orders;
SELECT 'public.customers' AS table_name, COUNT(*) AS row_count FROM public.customers;
-- 高頻度テーブルの最新レコードの抜き取り確認
SELECT MAX(updated_at) FROM public.orders;
SELECT MAX(id) FROM public.orders;- ソースシステムでの書き込みを停止する
まず、アプリケーションからの書き込みを一時停止します。さらに安全性を高めるため、切り替え時にはソースデータベースを読み取り専用に設定します。
ALTER DATABASE <source_db> SET default_transaction_read_only = on;ロールバックが必要な場合は、書き込みを再度有効化できます。
ALTER DATABASE <source_db> SET default_transaction_read_only = off;- レプリケーションが完全に追いついていることを確認する
書き込み頻度の高い1つ以上のテーブルについて、最新の行が移行元と移行先で一致していることを確認します。
-- ソースとターゲットの両方で実行し、結果を比較する
SELECT MAX(id) AS latest_id, MAX(updated_at) AS latest_ts FROM public.orders;- 制約、索引、トリガーを再作成して有効にする
インジェストのために制約や索引を削除したり適用を保留したりしていた場合は、ここで再度適用します。また、以前にターゲット側のレプリケーションロールを replica に設定していた場合は、それもリセットしてください。
ALTER ROLE <target_role> SET session_replication_role = origin;# 例: 制約/索引/トリガーを含むSQLファイルを適用する
psql -h <target_host> -p <target_port> -U <target_user> -d <target_db> -f post_migration_objects.sql- ターゲットテーブルのシーケンスをリセットする
データの読み込み後、シーケンスをテーブルの現在の値に合わせます。
-- システムスキーマ以外の全シリアル/IDカラムに対する汎用シーケンスリセット
DO $$
DECLARE r RECORD;
BEGIN
FOR r IN
SELECT
n.nspname AS schema_name,
c.relname AS table_name,
a.attname AS column_name,
pg_get_serial_sequence(format('%I.%I', n.nspname, c.relname), a.attname) AS seq_name
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid
WHERE c.relkind = 'r'
AND a.attnum > 0
AND NOT a.attisdropped
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
LOOP
IF r.seq_name IS NOT NULL THEN
EXECUTE format(
'SELECT setval(%L, COALESCE((SELECT MAX(%I) FROM %I.%I), 0) + 1, false)',
r.seq_name, r.column_name, r.schema_name, r.table_name
);
END IF;
END LOOP;
END $$;- アプリケーショントラフィックを切り替える
検証が完了し、シーケンスと制約の設定が済んだら:
- 読み取りトラフィックの送信先を ClickHouse Managed Postgres に切り替えます。
- 書き込みトラフィックの送信先を ClickHouse Managed Postgres に切り替えます。
- アプリケーションエラー、制約違反、データベースの健全性を監視します。
- リソースをクリーンアップする
移行に問題がないことを確認し、アプリケーションの切り替え先を ClickHouse Managed Postgres に変更したら、PeerDB のミラーとピアを削除できます。
参考資料
- ClickHouse Managed Postgres ドキュメント
- CDC 作成に関する PeerDB ガイド
- Postgres ClickPipe よくある質問 (PeerDB にも同様に当てはまります)
次のステップ
おめでとうございます。pg_dump と pg_restore を使用して、PostgreSQL データベースを ClickHouse Managed Postgres に正常に移行できました。これで、ClickHouse Managed Postgres の機能や ClickHouse とのインテグレーションを試す準備は万端です。まずは、10 分で読める以下のクイックスタートをご覧ください。