はじめに
CDC (Change Data Capture) は、リアルタイムなデータ統合を必要とする最新のデータアーキテクチャにおいて極めて重要なパターンです。本稿では、ClickHouse Cloud ネイティブのデータ統合ソリューションである ClickPipes が、MySQL データベース向けの CDC をどのように実装しているかを技術的に掘り下げて解説します。信頼性が高く高性能なデータベースレプリケーションを支える仕組みを理解したいエンジニアやアーキテクトに向けて、MySQL CDC 実装の内部構造を紹介します。
MySQL レプリケーションの基礎
まずは、MySQL におけるレプリケーションの基礎から振り返りましょう。
バイナリログ: MySQL CDC の基盤
MySQL のバイナリログ (binlog) は、レプリケーションアーキテクチャの要です。下図に示すように、データベースのデータおよび構造に対するすべての変更が順次記録されます。

バイナリログには、次の事象を表すイベントが含まれます。
- データ操作 (INSERT、UPDATE、DELETE)
- データ定義 (CREATE、ALTER、DROP)
- トランザクション境界 (BEGIN、COMMIT、ROLLBACK)
各バイナリログイベントには、メタデータ (タイムスタンプ、サーバー ID など) を持つイベントヘッダーと、実際の変更データを持つイベントボディが含まれます。
バイナリログのフォーマット
MySQL には 3 種類の binlog フォーマットが用意されています。
- STATEMENT: SQL 文を記録
- ログサイズが小さい
- 決定論的でない関数によりレプリケーションの問題が生じる可能性がある
- CDC には不向き
- ROW: 変更された行を記録
- 変更された行の変更前・変更後のイメージを記録
- 忠実度が最も高い一方、ログサイズは大きくなる
- CDC に必須
- MIXED: デフォルトで STATEMENT を使用し、必要に応じて ROW に切り替え
- CDC には不向き
前提条件 — binlog_row_image = FULL
ClickPipes では、MySQL バイナリログの各行変更に完全な変更前・変更後イメージが含まれている必要があるため、ソースデータベースは binlog_row_image='FULL' で稼働している必要があります (MySQL 8.x ではデフォルトです)。MINIMAL や NOBLOB などの軽量モードでは、容量を節約するために変更のないカラムが除外されますが、それにより ClickPipes が更新を冪等に再生したり、主キーの書き換えを安全に処理したりできなくなります。binlog_row_image = FULL への変更によってログ量が増えるのは主に UPDATE が頻発する場合であり、INSERT や DELETE は変わらないため、オーバーヘッドは通常それほど大きくありません。
グローバルトランザクション識別子 (GTID)
GTID は、サーバー間でトランザクションを一貫して識別する手段を提供します。
GTID = source_id:transaction_idGTID セットの例: 123e4567-e89b-12d3-a456-426614174000:1-1000,2000-3000
GTID ベースのレプリケーションの利点:
- サーバー再起動をまたいだトランザクションの追跡
- フェイルオーバーと高可用性の簡素化
- レプリケーショントポロジー変更の容易化
ClickPipes MySQL CDC のアーキテクチャ
ClickPipes は、初期データのロードと継続的なレプリケーションの双方を処理する堅牢なアーキテクチャによって MySQL 向け CDC を実現しています。
アーキテクチャの概要
下図は、ClickPipes における MySQL CDC のアーキテクチャを示しています。

ClickPipes MySQL CDC パイプラインは、いくつかの主要コンポーネントで構成されています。
- 接続管理 (Connection Management): ソース MySQL データベースへの接続を確立・維持
- Binlog シンカー (Binlog Syncer): MySQL のバイナリログストリームに接続
- イベントプロセッサー (Event Processor): バイナリログイベントを処理して構造化された変更レコードに変換
- スキーマレジストリ (Schema Registry): ソーステーブルの構造を追跡
- チェックポインティング (Checkpointing): 障害後の再開を可能にするため進捗を記録
- 変換レイヤー (Transformation Layer): MySQL の型を ClickHouse の型に変換
- シンクレイヤー (Sink Layer): ClickHouse へ効率的にデータを書き込み
接続とセットアップ
MySQL CDC フローが開始されると、ClickPipes は次の処理を行います。
- MySQL 設定の検証
- binlog_format = 'ROW' の確認
- binlog_row_image = 'FULL' の確認
- binlog 保持期間設定の検証
- レプリケーション機能の調査
- GTID サポートの検出
- レプリケーション開始位置の確立
- テーブルスキーマの抽出
- カラム定義とデータ型の取得
- 主キーの特定
- MySQL の型から ClickHouse の型へのマッピング
初期データのロード
変更のストリーミングを開始する前に、ClickPipes は初期スナップショットを取得します。

このプロセスでは以下を実行します。
- データの一貫したスナップショットを作成
- ClickHouse 内にターゲットテーブルをセットアップ
- ストリーミングを開始する binlog ポジションまたは GTID を記録
変更のストリーミング
初期ロードの完了後、ClickPipes は継続的に変更をストリーミングします。

ストリーミングプロセスの流れは以下のとおりです。
- MySQL の binlog ストリームに接続
- トランザクション順にイベントを処理
- 行イベントを構造化された変更レコードに変換
- 変更を ClickHouse に適用
- チェックポイントを更新して進捗を記録
GTID レプリケーションと Binlog ポジションベースのレプリケーションの比較
ClickPipes は両方のレプリケーション方式をサポートしています。
GTID ベースのレプリケーション
GTID は、トランザクションを追跡するための論理的で一貫した手段を提供します。トランザクションが完了すると GTID セットが更新され、チェックポイントに保存されます。この仕組みにより効率的な再開が可能となり、サーバーの再起動やトポロジー変更に対しても耐性を持ちます。
Binlog ポジションベースのレプリケーション
従来の binlog ポジションによる追跡は、ファイル名とポジションを用いて動作します。ログローテーションイベントが発生すると、新しいファイル名とポジションで位置が更新されます。この手法も有効ではあるものの、サーバー変更に対する耐性が低く、高可用性構成での管理がより複雑になります。フェイルオーバーが発生した場合は、パイプの再同期が必要になります。
バイナリログイベントの処理
ClickPipes は複数種類の binlog イベントを処理します。
行イベント

パイプラインは以下を処理します。
- INSERT 操作: カラム値を抽出し、挿入レコードを作成
- UPDATE 操作: 変更前後の両方の値をキャプチャし、更新レコードを作成
- DELETE 操作: カラム値を抽出し、削除レコードを作成
スキーマ変更イベント
ClickPipes は DDL 文をパースすることでスキーマ変更を検出し、処理します。システムは以下を実行します。
- TiDB の SQL パーサーを使用して DDL 文をパース
- スキーマ変更 (特にカラムの追加) を抽出
- スキーマレジストリを更新
- ターゲットテーブルに変更を反映
型のマッピングと変換
ClickPipes は、MySQL の幅広いデータ型に対応しています。
| MySQL の型 | ClickHouse の型 | 備考 |
| TINYINT | Int8/UInt8 | 符号なしバリアントは UInt にマッピング |
| TINYINT(1) | Bool | |
| SMALLINT | Int16/UInt16 | |
| MEDIUMINT | Int32/UInt32 | (MySQL は 24 ビット整数) |
| INT | Int32/UInt32 | |
| BIGINT | Int64/UInt64 | |
| FLOAT | Float32 | |
| DOUBLE | Float64 | |
| DECIMAL | Decimal | 精度 (precision) とスケール (scale) を維持 |
| CHAR/VARCHAR/TEXT | String | |
| BINARY/VARBINARY/BLOB | String | |
| JSON | String | JSON テキストとして保持 |
| DATE | Date32 | |
| TIME | DateTime64(6) | 日付部分は Unix エポック |
| YEAR | Int16 | |
| DATETIME/TIMESTAMP | DateTime64(6) | |
| ENUM | LowCardinality(String) | |
| SET | String | カンマ区切りの値 |
| BIT | UInt64 | |
| GEOMETRY | String | WKT フォーマット |
| VECTOR | Array(Float32) | MySQL 8.4 以降向け |
型変換システムは、以下のようなエッジケースも処理します。
- Enum/Set 値の参照 (binlog_row_metadata が必要)
- バイナリデータの処理
パフォーマンスの最適化
ClickPipes は、MySQL CDC 向けにいくつかの最適化を実装しています。
トランザクションのバッチ処理
一貫性を維持するために変更はトランザクションごとにグループ化され、バッチサイズは設定可能です。
アイドルタイムアウト
アイドルタイムアウトを用いてデータが流れていない状態を検知し、非アクティブな時間帯におけるリソースの浪費を防ぎます。
並列処理
可能な箇所では並列処理を活用しています。
- スキーマ取得の並列化
- バッチ単位でのテーブル処理
- ClickHouse への同時書き込み
バックオフ戦略
指数バックオフを備えたインテリジェントなリトライロジックにより、一時的な障害に対する耐性を確保しています。
モニタリングとオブザーバビリティ
ClickPipes は、MySQL CDC フロー向けの包括的なモニタリング機能を提供します。主要メトリクスには以下が含まれます。
- 毎秒の処理レコード数
- binlog から読み取ったバイト数
- レプリケーションレイテンシ
- エラー率
- 現在のポジション/GTID
障害シナリオへの対応
ClickPipes は、さまざまな障害シナリオに対して堅牢なエラーハンドリングを実装しています。
接続障害
バックオフを伴う接続の自動リトライを行い、一時的なネットワーク障害を適切に処理します。
スキーマの不整合 (Schema Skew)
ソースとターゲットのスキーマ間の差異によってデータが気付かないうちに破損することがないよう、スキーマの不整合を検出してレポートします。
障害後の再開
障害発生後に復旧できるようチェックポイントを保持し、データの欠落や重複を防ぎます。
オープンソースへの貢献
ClickPipes における MySQL CDC 機能の構築にあたっては、利用しているオープンソースライブラリに大幅な拡張を加える必要がありました。私たちのチームは、CDC 実装の中核を担う go-mysql-org/go-mysql ライブラリに対して、いくつかの改善をコントリビューションしています。
これらの貢献により、ClickPipes は堅牢でメンテナンスの行き届いた基盤の上で MySQL レプリケーションを提供できています。
ベストプラクティス
ClickPipes で MySQL CDC を最適なパフォーマンスで運用するための推奨事項は以下のとおりです。
- MySQL の設定
binlog_format = 'ROW'に設定binlog_row_image = 'FULL'に設定binlog_row_metadata = 'FULL'に設定 (カラムフィルタリング、ソース側でのカラム削除に伴う問題の回避、豊富な enum/set サポートのため)- 適切な binlog 保持期間を設定 (最低 24 時間)
- テーブル設計
- すべてのテーブルで主キーを使用
- 変更頻度の高いテーブルではラージオブジェクト型のカラムを回避
- 大規模テーブルのパーティショニングを検討
- ネットワークの最適化
- 可能な場合は ClickPipes と MySQL を同一環境に配置
- VPC ピアリングやプライベート接続を利用
- セキュアな転送のために TLS を有効化
- モニタリング
- レプリケーションレイテンシを追跡
- binlog の増加率を監視
- レプリケーションの遅延に対するアラートを設定
ベンチマークとパフォーマンス
ClickPipes MySQL CDC の詳細なパフォーマンスベンチマークは近日中に公開予定です。初期テストでは、高頻度の小規模トランザクション、大規模な一括操作、現実的な混合ワークロードなど、さまざまなワークロードにおいて有望な結果が得られています。本システムは、最適な条件下において毎秒数万件の変更を 30 秒未満のレイテンシで処理できるように設計されています。
制限事項とエッジケース
ClickPipes MySQL CDC には一部制限事項があります。
- スキーマ変更:
- カラムの追加は完全にサポート
- カラムの削除およびリネームは検出されるものの伝播は不可
- テーブルのリネームには手動での対応が必要
- データ型:
- バイナリデータはサイズ制限内である必要あり
- レプリケーションの要件:
- バイナリログが有効化され、適切に設定されている必要あり
- 十分な権限が必要
- 最適なパフォーマンスを得るにはテーブルに主キーが必要
- TRUNCATE 操作はサポートされていません。
まとめ
ClickPipes MySQL CDC は、MySQL データベースからの変更をキャプチャして処理するための、堅牢で高性能なソリューションを提供します。MySQL ネイティブのレプリケーション機能を活用し、インテリジェントな処理パイプラインを実装することで、ClickHouse とのリアルタイムデータ統合を実現します。
本システムのアーキテクチャは、信頼性、パフォーマンス、使いやすさを高い次元で両立しており、業務系データストアから分析パイプラインに至るまで幅広いユースケースに適しています。MySQL CDC 実装の内部動作を理解することで、データフローの最適化やトラブルシューティングをより効果的に行えるようになります。
ClickPipes による MySQL CDC のセットアップに関する詳細は、公式ドキュメント を参照してください。ClickPipes における MySQL CDC はプライベートプレビューとして利用可能になりました。ぜひお試しください。
参考資料
今すぐ ClickHouse Cloud を始めて、$300 のクレジットを受け取りましょう。30 日間の無料トライアル終了後は、従量課金プランに移行できます。ボリュームベースの割引について詳しくは お問い合わせ ください。詳細は 料金ページ をご覧ください。



