データの移行
これは、PostgreSQL から ClickHouse への移行に関するガイドの パート 1 です。具体例を用いて、リアルタイムレプリケーション(CDC)方式により効率的に移行を行う方法を示します。ここで扱う多くの概念は、PostgreSQL から ClickHouse への手動での一括データ転送にも適用できます。
データセット
Postgres から ClickHouse への典型的なマイグレーション例を示すサンプルデータセットとして、こちら で説明している Stack Overflow データセットを使用します。これは、2008 年から 2024 年 4 月までに Stack Overflow 上で発生したすべての post、vote、user、comment、badge を含みます。このデータ用の PostgreSQL スキーマを以下に示します。

PostgreSQL でテーブルを作成するための DDL コマンドは こちら から利用できます。
このスキーマは必ずしも最適というわけではありませんが、主キー、外部キー、パーティショニング、インデックスなど、PostgreSQL の一般的な機能をいくつか活用しています。
これらそれぞれの概念を、ClickHouse の対応する機能へマイグレーションしていきます。
マイグレーション手順を検証する目的で、このデータセットを PostgreSQL インスタンスに読み込みたいユーザー向けに、DDL とともにダウンロード可能な pg_dump 形式のデータを用意しています。続いて、データロード用コマンドを以下に示します。
posts
wget https://datasets-documentation.s3.eu-west-3.amazonaws.com/stackoverflow/pdump/2024/posts.sql.gz gzip -d posts.sql.gz psql < posts.sql
posthistory
wget https://datasets-documentation.s3.eu-west-3.amazonaws.com/stackoverflow/pdump/2024/posthistory.sql.gz gzip -d posthistory.sql.gz psql < posthistory.sql
コメント
wget https://datasets-documentation.s3.eu-west-3.amazonaws.com/stackoverflow/pdump/2024/comments.sql.gz gzip -d comments.sql.gz psql < comments.sql
投票
wget https://datasets-documentation.s3.eu-west-3.amazonaws.com/stackoverflow/pdump/2024/votes.sql.gz gzip -d votes.sql.gz psql < votes.sql
badges
wget https://datasets-documentation.s3.eu-west-3.amazonaws.com/stackoverflow/pdump/2024/badges.sql.gz gzip -d badges.sql.gz psql < badges.sql
postlinks
wget https://datasets-documentation.s3.eu-west-3.amazonaws.com/stackoverflow/pdump/2024/postlinks.sql.gz gzip -d postlinks.sql.gz psql < postlinks.sql
データの移行
リアルタイムレプリケーション(CDC)
PostgreSQL 用の ClickPipes をセットアップするには、このガイドを参照してください。このガイドでは、さまざまな種類のソースとなる Postgres インスタンスを扱っています。
ClickPipes または PeerDB を用いた CDC アプローチでは、PostgreSQL データベース内のすべてのテーブルが ClickHouse に自動的にレプリケートされます。
更新と削除をほぼリアルタイムで処理するために、ClickPipes は Postgres のテーブルを、更新や削除の処理に特化した ReplacingMergeTree エンジンを使って ClickHouse のテーブルに対応付けます。ClickPipes を使用してデータがどのように ClickHouse にレプリケートされるかについての詳細はこちらを参照してください。CDC を用いたレプリケーションでは、更新または削除操作をレプリケートする際に、ClickHouse 内に重複した行が作成される点に注意することが重要です。ClickHouse でそれらを処理するための、FINAL 修飾子を使用した手法を参照してください。
ClickPipes を使用して ClickHouse に users テーブルがどのように作成されるかを見ていきましょう。
セットアップが完了すると、ClickPipes は PostgreSQL から ClickHouse へのすべてのデータ移行を開始します。ネットワークやデプロイメントの規模によって所要時間は異なりますが、Stack Overflow データセットであれば数分程度で完了するはずです。
手動による一括ロードと定期更新
手動アプローチを用いる場合、データセットの初回一括ロードは次の方法で実施できます。
- テーブル関数 - ClickHouse の Postgres テーブル関数 を使用して、Postgres からデータを
SELECTし、ClickHouse のテーブルにINSERTします。数百 GB 規模までの一括ロードに適しています。 - エクスポート - CSV や SQL スクリプトファイルといった中間形式へエクスポートします。これらのファイルは、クライアントから
INSERT FROM INFILE句を使うか、オブジェクトストレージとそれ用の関数(例: s3, gcs)を利用して ClickHouse にロードできます。
PostgreSQL から手動でデータをロードする場合は、まず ClickHouse 上にテーブルを作成する必要があります。ClickHouse におけるテーブルスキーマの最適化については、Stack Overflow データセットを用いた例も含む データモデリングのドキュメント を参照してください。
PostgreSQL と ClickHouse の間ではデータ型が異なる場合があります。各テーブルのカラムに対応する同等の型を確認するために、Postgres テーブル関数 と併せて DESCRIBE コマンドを使用できます。次のコマンドは PostgreSQL の posts テーブルを DESCRIBE する例です。自身の環境に合わせて修正して利用してください。
PostgreSQL と ClickHouse 間のデータ型マッピングの概要については、付録ドキュメントを参照してください。
このスキーマに対して型を最適化する手順は、データが他のソース(例:S3 上の Parquet)からロードされている場合と同じです。Parquet を使用する別のガイドで説明されている手順を適用すると、次のスキーマになります。
PostgreSQL からデータを読み込み、ClickHouse に挿入する単純な INSERT INTO SELECT 文で、これを埋めることができます。
増分ロードはスケジュール実行することもできます。Postgres テーブルが挿入のみを受け付け、単調増加する id もしくはタイムスタンプが存在する場合、ユーザーは上記のテーブル関数アプローチを用いて増分分のみをロードできます。すなわち、SELECT に WHERE 句を適用できます。このアプローチは、同じカラムが更新されることが保証されている場合には更新の取り込みにも利用できます。一方で、削除をサポートするには完全な再ロードが必要となりますが、テーブルが大きくなると、これを実現するのは難しくなる可能性があります。
ここでは、CreationDate を用いた初回ロードと増分ロードを示します(行が更新された場合、このカラムも更新されると仮定します)。
ClickHouse は、
=,!=,>,>=,<,<=, および IN といった単純なWHERE句を PostgreSQL サーバー側へプッシュダウンします。これにより、変更セットの識別に使用されるカラムにインデックスを作成しておくことで、増分ロードをより効率的に実行できます。
クエリレプリケーションを使用している場合に UPDATE 操作を検出する 1 つの方法として、
XMINシステムカラム(トランザクション ID)をウォーターマークとして利用することが挙げられます。このカラムの変化は変更を示すため、その変更を宛先テーブルに適用できます。この方法を用いるユーザーは、XMINの値はラップアラウンドする可能性があり、比較には全表スキャンが必要となるため、変更の追跡がより複雑になることに注意してください。