ストレージサービスにデータを複製する
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-08-05T18: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":"v7.5.3"}
--server: TiCDC クラスター内の任意の TiCDCサーバーのアドレス。--changefeed-id: 変更フィードの ID。形式は^[a-zA-Z0-9]+(\-[a-zA-Z0-9]+)*$正規表現に一致する必要があります。この ID が指定されていない場合、TiCDC は ID として UUID (バージョン 4 形式) を自動的に生成します。--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いずれかCDC:ErrSinkUnknownProtocolprotocolが返されます。
外部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:ListBuckets3:PutObjectおよびs3:GetObject。 - changefeed 構成項目
sink.cloud-storage-config.flush-concurrencyが 1 より大きい場合、つまり単一ファイルの並列アップロードが有効になっている場合は、 リストパーツに関連する権限を追加する必要があります。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_TENANT_ID$AZURE_CLIENT_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 形式をサポートしています。
注記:
テーブル バージョンは、上流テーブルで DDL 操作が実行された後にのみ変更され、上流 TiDB が DDL の実行を完了すると、新しいテーブル バージョンが TSO になります。ただし、テーブル バージョンの変更は、テーブル スキーマの変更を意味するものではありません。たとえば、列にコメントを追加しても、スキーマ ファイルの内容は変更されません。
インデックスファイル
インデックス ファイルは、書き込まれたデータが誤って上書きされるのを防ぐために使用され、データ変更レコードと同じパスに保存されます。
{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}",
}