ストレージサービスへのデータの複製
TiDB v6.5.0以降、TiCDCはAmazon S3、GCS、Azure Blob Storage、NFSなどのstorageサービスへの行変更イベントの保存をサポートします。本ドキュメントでは、TiCDCを使用してこれらのstorageサービスに増分データをレプリケートするチェンジフィードの作成方法と、データの保存方法について説明します。本ドキュメントの構成は以下のとおりです。
変更データをstorageサービスに複製する
次のコマンドを実行して、changefeed タスクを作成します。
cdc cli changefeed create \
    --server=http://10.0.10.25:8300 \
    --sink-uri="s3://logbucket/storage_test?protocol=canal-json" \
    --changefeed-id="simple-replication-task"
出力は次のようになります。
Info: {"upstream_id":7171388873935111376,"namespace":"default","id":"simple-replication-task","sink_uri":"s3://logbucket/storage_test?protocol=canal-json","create_time":"2024-12-26T18:52:05.566016967+08:00","start_ts":437706850431664129,"engine":"unified","config":{"case_sensitive":false,"enable_old_value":true,"force_replicate":false,"ignore_ineligible_table":false,"check_gc_safe_point":true,"enable_sync_point":false,"sync_point_interval":600000000000,"sync_point_retention":86400000000000,"filter":{"rules":["*.*"],"event_filters":null},"mounter":{"worker_num":16},"sink":{"protocol":"canal-json","schema_registry":"","csv":{"delimiter":",","quote":"\"","null":"\\N","include_commit_ts":false},"column_selectors":null,"transaction_atomicity":"none","encoder_concurrency":16,"terminator":"\r\n","date_separator":"none","enable_partition_separator":false},"consistent":{"level":"none","max_log_size":64,"flush_interval":2000,"storage":""}},"state":"normal","creator_version":"v8.1.2"}
--server: TiCDC クラスター内の任意の TiCDCサーバーのアドレス。--changefeed-id: チェンジフィードのID。形式は正規表現^[a-zA-Z0-9]+(\-[a-zA-Z0-9]+)*$に一致する必要があります。このIDが指定されていない場合、TiCDCは自動的にUUID(バージョン4形式)をIDとして生成します。--sink-uri: チェンジフィードのダウンストリームアドレス。詳細はシンクURIを構成する参照。--start-ts: チェンジフィードの開始TSO。TiCDCはこのTSOからデータのプルを開始します。デフォルト値は現在時刻です。--target-ts: チェンジフィードの終了TSO。TiCDCはこのTSOまでデータのプルを停止します。デフォルト値は空で、TiCDCはデータのプルを自動的に停止しません。--config: チェンジフィードの設定ファイル。詳細はTiCDC チェンジフィード構成パラメータ参照してください。
シンクURIを構成する
このセクションでは、Amazon S3、GCS、Azure Blob Storage、NFSなどのstorageサービスのシンクURIを設定する方法について説明します。シンクURIは、TiCDCターゲットシステムの接続情報を指定するために使用されます。形式は次のとおりです。
[scheme]://[host]/[path]?[query_parameters]
URI の[query_parameters]には、次のパラメータを設定できます。
| パラメータ | 説明 | デフォルト値 | 値の範囲 | 
|---|---|---|---|
worker-count | ダウンストリームのクラウドstorageにデータの変更を保存するための同時実行性。 | 16 | [1, 512] | 
flush-interval | ダウンストリームのクラウドstorageにデータの変更を保存する間隔。 | 5s | [2s, 10m] | 
file-size | バイト数がこのパラメータの値を超えると、データ変更ファイルはクラウドstorageに保存されます。 | 67108864 | [1048576, 536870912] | 
protocol | ダウンストリームに送信されるメッセージのプロトコル形式。 | 該当なし | canal-jsonとcsv | 
enable-tidb-extension | protocol canal-jsonに設定され、 enable-tidb-extension trueに設定されている場合、 TiCDC はウォーターマークイベント送信し、 TiDB拡張フィールド Canal-JSON メッセージに追加します。 | false | falseとtrue | 
注記:
データ変更ファイルは、
flush-intervalまたはfile-sizeいずれかが要件を満たしている場合に下流に保存されます。5protocolパラメータは必須です。TiCDCが変更フィードの作成時にこのパラメータを受け取らない場合は、CDC:ErrSinkUnknownProtocolエラーが返されます。
外部storageのシンクURIを構成する
クラウドstorageシステムにデータを保存する場合、クラウドサービスプロバイダーに応じて異なる認証パラメータを設定する必要があります。このセクションでは、Amazon S3、Google Cloud Storage(GCS)、Azure Blob Storage を使用する場合の認証方法と、それぞれのストレージstorageにアクセスするためのアカウントの設定方法について説明します。
以下は Amazon S3 の設定例です。
--sink-uri="s3://bucket/prefix?protocol=canal-json"
データを複製する前に、Amazon S3 のディレクトリに適切なアクセス権限を設定する必要があります。
- TiCDC に必要な最小限
s3:PutObject権限:s3:ListBucket、およびs3:GetObject。 - changefeed 構成項目
sink.cloud-storage-config.flush-concurrency1 より大きい場合、つまり単一ファイルの並列アップロードが有効になっている場合は、 リストパーツに関連する権限を追加する必要があります。s3:AbortMultipartUploads3:ListMultipartUploadPartss3:ListBucketMultipartUploads
 
レプリケーションデータstorageディレクトリを作成していない場合は、 バケットを作成するを参照して指定リージョンに S3 バケットを作成してください。必要に応じて、 フォルダを使用して Amazon S3 コンソールでオブジェクトを整理するを参照してバケット内にフォルダを作成することもできます。
次の方法で Amazon S3 にアクセスできるようにアカウントを設定できます。
方法1: アクセスキーを指定する
アクセスキーとシークレットアクセスキーを指定した場合、それらに基づいて認証が行われます。URIでキーを指定する方法に加えて、以下の方法がサポートされています。
- TiCDC は環境変数
$AWS_ACCESS_KEY_IDと$AWS_SECRET_ACCESS_KEY読み取ります。 - TiCDC は環境変数
$AWS_ACCESS_KEYと$AWS_SECRET_KEY読み取ります。 - TiCDC は、 
$AWS_SHARED_CREDENTIALS_FILE環境変数で指定されたパスにある共有資格情報ファイルを読み取ります。 - TiCDC は
~/.aws/credentialsパスにある共有資格情報ファイルを読み取ります。 
- TiCDC は環境変数
 方法2: IAMロールに基づくアクセス
TiCDCサーバーを実行している EC2 インスタンスにAmazon S3 にアクセスするための権限が設定されたIAMロール関連付けます。セットアップが成功すると、TiCDC は追加設定なしで Amazon S3 内の対応するディレクトリに直接アクセスできるようになります。
以下は GCS の構成例です。
--sink-uri="gcs://bucket/prefix?protocol=canal-json"
GCSへのアクセスに使用するアカウントは、アクセスキーを指定することで設定できます。認証は指定されたcredentials-fileに基づいて行われます。URIでキーを指定することに加えて、以下の方法がサポートされています。
- TiCDC は、 
$GOOGLE_APPLICATION_CREDENTIALS環境変数で指定されたパスにあるファイルを読み取ります。 - TiCDC はファイル
~/.config/gcloud/application_default_credentials.jsonを読み取ります。 - TiCDC は、クラスターが GCE または GAE で実行されているときに、メタデータサーバーから資格情報を取得します。
 
以下は、Azure Blob Storage の構成例です。
--sink-uri="azure://bucket/prefix?protocol=canal-json"
次の方法で、Azure Blob Storage にアクセスするようにアカウントを構成できます。
方法1: 共有アクセス署名を指定する
URIに
account-nameとsas-token設定した場合、このパラメーターで指定されたstorageアカウント名と共有アクセス署名トークンが使用されます。共有アクセス署名トークンには&文字が含まれているため、URIに追加する前に%26としてエンコードする必要があります。パーセントエンコードを使用して、sas-token全体を直接エンコードすることもできます。方法2: アクセスキーを指定する
URIで
account-nameとaccount-key設定した場合、このパラメータで指定されたstorageアカウント名とキーが使用されます。URIでキーファイルを指定するだけでなく、TiCDCは環境変数$AZURE_STORAGE_KEYからキーを読み取ることもできます。方法3: Azure ADを使用してバックアップを復元する
環境変数
$AZURE_CLIENT_ID$AZURE_TENANT_ID設定し$AZURE_CLIENT_SECRET。
ヒント:
TiCDC における Amazon S3、GCS、Azure Blob Storage の URI パラメータの詳細については、 外部ストレージサービスのURI形式参照してください。
NFSのシンクURIを構成する
以下は NFS の構成例です。
--sink-uri="file:///my-directory/prefix?protocol=canal-json"
ストレージパス構造
このセクションでは、データ変更レコード、メタデータ、および DDL イベントのstorageパス構造について説明します。
データ変更記録
データ変更レコードは次のパスに保存されます。
{scheme}://{prefix}/{schema}/{table}/{table-version-separator}/{partition-separator}/{date-separator}/CDC{num}.{extension}
scheme:storageタイプを指定します (例:s3、gcs、azure、file。prefix: ユーザー定義の親ディレクトリを指定します (例:s3:// **bucket/bbb/ccc**。schema: スキーマ名を指定します (例:s3://bucket/bbb/ccc/ **test**。table: テーブル名を指定します (例:s3://bucket/bbb/ccc/test/ **table1**。table-version-separator: テーブルバージョンでパスを区切る区切り文字を指定します (例:s3://bucket/bbb/ccc/test/table1/ **9999**)。partition-separator: テーブルパーティションによってパスを区切るセパレーターを指定します (例:s3://bucket/bbb/ccc/test/table1/9999/ **20**。date-separator: トランザクションのコミット日に基づいてファイルを分類します。デフォルト値はdayです。値のオプションは次のとおりです。none:date-separatorなし。たとえば、バージョンtest.table1が9999であるすべてのファイルはs3://bucket/bbb/ccc/test/table1/9999に保存されます。year: 区切り文字はトランザクションコミット日の年です (例:s3://bucket/bbb/ccc/test/table1/9999/ **2022**。month: 区切り文字はトランザクションコミット日の年と月です。例:s3://bucket/bbb/ccc/test/table1/9999/ **2022-01**。day: 区切り文字はトランザクションコミット日の年、月、日です。例:s3://bucket/bbb/ccc/test/table1/9999/ **2022-01-02**。
num: データの変更を記録したファイルのシリアル番号を保存します (例:s3://bucket/bbb/ccc/test/table1/9999/2022-01-02/CDC **000005** .csv。extension: ファイルの拡張子を指定します。TiDB v6.5.0 は CSV および Canal-JSON 形式をサポートしています。
注記:
テーブル バージョンは次のシナリオで変更されます。
- アップストリーム TiDB はテーブルに対して DDL 操作を実行します。
 - TiCDC はノード間でテーブルをスケジュールします。
 - テーブルが属する変更フィードが再開されます。
 テーブルバージョンの変更はテーブルスキーマの変更を意味するものではないことに注意してください。例えば、列にコメントを追加しても、スキーマファイルの内容は変更されません。
インデックスファイル
インデックスファイルは、書き込まれたデータが誤って上書きされるのを防ぐために使用されます。インデックスファイルは、データ変更レコードと同じパスに保存されます。
{scheme}://{prefix}/{schema}/{table}/{table-version-separator}/{partition-separator}/{date-separator}/meta/CDC.index
インデックスファイルには、現在のディレクトリで使用されている最大のファイル名が記録されます。例:
CDC000005.csv
この例では、このディレクトリ内のファイルCDC000001.csvからCDC000004.csv使用中です。TiCDC クラスターでテーブルスケジューリングまたはノードの再起動が発生すると、新しいノードはインデックスファイルを読み取り、 CDC000005.csv使用中かどうかを判断します。使用中でない場合、新しいノードはCDC000005.csvからファイルに書き込みます。使用中の場合はCDC000006.csvから書き込みを開始し、他のノードによって書き込まれたデータの上書きを防ぎます。
メタデータ
メタデータは次のパスに保存されます。
{protocol}://{prefix}/metadata
メタデータは JSON 形式のファイルです。例:
{
    "checkpoint-ts":433305438660591626
}
checkpoint-ts:commit-tsがcheckpoint-tsより小さいトランザクションは、ダウンストリームのターゲットstorageに書き込まれます。
DDLイベント
テーブルレベルのDDLイベント
アップストリーム テーブルの DDL イベントによってテーブル バージョンが変更されると、TiCDC は自動的に次の処理を実行します。
データ変更レコードを書き込むための新しいパスに切り替えます。例えば、バージョン
test.table1が441349361156227074に変更されると、TiCDCはデータ変更レコードを書き込むためのパスをs3://bucket/bbb/ccc/test/table1/441349361156227074/2022-01-02/に変更します。テーブル スキーマ情報を格納するために、次のパスにスキーマ ファイルを生成します。
{scheme}://{prefix}/{schema}/{table}/meta/schema_{table-version}_{hash}.json
schema_441349361156227074_3131721815.jsonスキーマ ファイルを例にとると、このファイル内のテーブル スキーマ情報は次のようになります。
{
    "Table":"table1",
    "Schema":"test",
    "Version":1,
    "TableVersion":441349361156227074,
    "Query":"ALTER TABLE test.table1 ADD OfficeLocation blob(20)",
    "Type":5,
    "TableColumns":[
        {
            "ColumnName":"Id",
            "ColumnType":"INT",
            "ColumnNullable":"false",
            "ColumnIsPk":"true"
        },
        {
            "ColumnName":"LastName",
            "ColumnType":"CHAR",
            "ColumnLength":"20"
        },
        {
            "ColumnName":"FirstName",
            "ColumnType":"VARCHAR",
            "ColumnLength":"30"
        },
        {
            "ColumnName":"HireDate",
            "ColumnType":"DATETIME"
        },
        {
            "ColumnName":"OfficeLocation",
            "ColumnType":"BLOB",
            "ColumnLength":"20"
        }
    ],
    "TableColumnsTotal":"5"
}
Table: テーブル名。Schema: スキーマ名。Version:storageシンクのプロトコル バージョン。TableVersion: テーブルバージョン。Query: DDL ステートメント。Type: DDL タイプ。TableColumns: 1 つ以上のマップの配列。各マップはソース テーブル内の列を表します。TableColumnsTotal:TableColumns配列のサイズ。
データベースレベルのDDLイベント
アップストリーム データベースでデータベース レベルの DDL イベントが実行されると、TiCDC は次のパスにスキーマ ファイルを自動的に生成し、データベース スキーマ情報を格納します。
{scheme}://{prefix}/{schema}/meta/schema_{table-version}_{hash}.json
schema_441349361156227000_3131721815.jsonスキーマ ファイルを例にとると、このファイル内のデータベース スキーマ情報は次のようになります。
{
  "Table": "",
  "Schema": "schema1",
  "Version": 1,
  "TableVersion": 441349361156227000,
  "Query": "CREATE DATABASE `schema1`",
  "Type": 1,
  "TableColumns": null,
  "TableColumnsTotal": 0
}
データ型
この節では、 schema_{table-version}_{hash}.jsonファイル(以下、スキーマファイル)で使用されるデータ型について説明します。データ型はT(M[, D])として定義されています。詳細についてはデータ型参照してください。
整数型
TiDBの整数型はIT[(M)] [UNSIGNED]と定義され、
ITは整数型で、TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT、またはBITになります。Mはタイプの表示幅です。
整数型はスキーマ ファイル内で次のように定義されます。
{
    "ColumnName":"COL1",
    "ColumnType":"{IT} [UNSIGNED]",
    "ColumnPrecision":"{M}"
}
10進数型
TiDBの10進数型はDT[(M,D)][UNSIGNED]と定義され、
DTは浮動小数点型で、FLOAT、DOUBLE、DECIMAL、またはNUMERICになります。Mはデータ型の精度、つまり合計桁数です。Dは小数点以下の桁数です。
10 進型はスキーマ ファイルで次のように定義されます。
{
    "ColumnName":"COL1",
    "ColumnType":"{DT} [UNSIGNED]",
    "ColumnPrecision":"{M}",
    "ColumnScale":"{D}"
}
日付と時刻の種類
TiDBの日付型はDTと定義され、
DTは日付型で、DATEまたはYEARになります。
日付タイプはスキーマ ファイルで次のように定義されます。
{
    "ColumnName":"COL1",
    "ColumnType":"{DT}"
}
TiDBの時間型はTT[(M)]と定義され、
TTは時間のタイプで、TIME、DATETIME、またはTIMESTAMPになります。Mは 0 から 6 までの範囲の秒の精度です。
時間タイプはスキーマ ファイルで次のように定義されます。
{
    "ColumnName":"COL1",
    "ColumnType":"{TT}",
    "ColumnScale":"{M}"
}
文字列型
TiDBの文字列型はST[(M)]として定義され、
STは文字列型で、CHAR、VARCHAR、TEXT、BINARY、BLOB、またはJSONになります。Mは文字列の最大長です。
文字列型はスキーマ ファイル内で次のように定義されます。
{
    "ColumnName":"COL1",
    "ColumnType":"{ST}",
    "ColumnLength":"{M}"
}
列挙型と集合型
Enum 型と Set 型は、スキーマ ファイルで次のように定義されます。
{
    "ColumnName":"COL1",
    "ColumnType":"{ENUM/SET}",
}