TiCDC よくある質問
このドキュメントでは、TiCDC の使用時に遭遇する可能性のある一般的な質問を紹介します。
注記:
このドキュメントでは、
cdc cli
コマンドで指定するサーバーアドレスは--server=http://127.0.0.1:8300
です。コマンドを使用するときは、アドレスを実際の PD アドレスに置き換えてください。
TiCDC でタスクを作成するときにstart-ts
選択するにはどうすればよいですか?
レプリケーション タスクのstart-ts
は、上流の TiDB クラスターのタイムスタンプ Oracle (TSO) に対応します。 TiCDC は、レプリケーション タスクでこの TSO にデータを要求します。したがって、レプリケーション タスクのstart-ts
は次の要件を満たす必要があります。
- 値
start-ts
は、現在の TiDB クラスターの値tikv_gc_safe_point
よりも大きくなります。そうしないと、タスクの作成時にエラーが発生します。 - タスクを開始する前に、ダウンストリームに
start-ts
より前のすべてのデータがあることを確認してください。データをメッセージ キューにレプリケートするなどのシナリオで、アップストリームとダウンストリームの間でデータの整合性が必要ない場合は、アプリケーションのニーズに応じてこの要件を緩和できます。
start-ts
を指定しない場合、またはstart-ts
を0
として指定した場合、レプリケーション タスクの開始時に、TiCDC は現在の TSO を取得し、この TSO からタスクを開始します。
TiCDC でタスクを作成するときに一部のテーブルを複製できないのはなぜですか?
cdc cli changefeed create
を実行してレプリケーション タスクを作成すると、TiCDC はアップストリーム テーブルがレプリケーション要件を満たすかどうかを確認します。一部のテーブルが要件を満たしていない場合は、不適格なテーブルのリストとともにsome tables are not eligible to replicate
が返されます。 Y
またはy
を選択してタスクの作成を続行すると、これらのテーブルのすべての更新はレプリケーション中に自動的に無視されます。 Y
またはy
以外の入力を選択した場合、レプリケーション タスクは作成されません。
TiCDC レプリケーション タスクの状態を表示するにはどうすればよいですか?
TiCDC レプリケーション タスクのステータスを表示するには、 cdc cli
を使用します。例えば:
cdc cli changefeed list --server=http://127.0.0.1:8300
期待される出力は次のとおりです。
[{
"id": "4e24dde6-53c1-40b6-badf-63620e4940dc",
"summary": {
"state": "normal",
"tso": 417886179132964865,
"checkpoint": "2020-07-07 16:07:44.881",
"error": null
}
}]
checkpoint
: TiCDC は、このタイムスタンプより前のすべてのデータをダウンストリームに複製しました。state
: このレプリケーション タスクの状態。各状態とその意味の詳細については、 フィード状態の変更を参照してください。
注記:
この機能は TiCDC 4.0.3 で導入されました。
TiCDC のgc-ttl
は何ですか?
v4.0.0-rc.1 以降、PD はサービス レベルの GC セーフポイントの設定において外部サービスをサポートしています。どのサービスでも GC セーフポイントを登録および更新できます。 PD は、この GC セーフポイントより後のキーと値のデータが GC によってクリーンアップされないことを保証します。
この機能により、レプリケーション タスクが利用できないか中断された場合、TiCDC によって消費されるデータが GC によってクリーンアップされずに TiKV に保持されることが保証されます。
TiCDCサーバーを起動するときに、 gc-ttl
を構成することで GC セーフポイントの存続時間 (TTL) 期間を指定できます。 TiUPを使用して変更します gc-ttl
もできます。デフォルト値は 24 時間です。 TiCDC では、この値は次のことを意味します。
- TiCDC サービスが停止した後、GC セーフポイントが PD に保持される最大時間。
- タスクが中断または手動で停止された後に、レプリケーション タスクを一時停止できる最大時間。一時停止されたレプリケーション タスクの時間が
gc-ttl
で設定された値よりも長い場合、レプリケーション タスクはfailed
ステータスになり、再開できず、GC セーフポイントの進行に影響を与え続けることはできません。
上記の 2 番目の動作は、TiCDC v4.0.13 以降のバージョンで導入されています。目的は、TiCDC のレプリケーション タスクが長時間中断され、上流の TiKV クラスターの GC セーフポイントが長期間継続できなくなり、古いデータ バージョンが多すぎる状態で保持され、上流クラスターのパフォーマンスに影響を与えることを防ぐことです。
注記:
たとえば、 Dumpling/ BRによる完全レプリケーション後の増分レプリケーションに TiCDC を使用する場合など、一部のシナリオでは、デフォルトの 24 時間の
gc-ttl
では不十分な場合があります。 TiCDCサーバーを開始するときに、gc-ttl
に適切な値を指定する必要があります。
TiCDCガベージコレクション(GC) セーフポイントの完全な動作は何ですか?
TiCDC サービスの開始後にレプリケーション タスクが開始される場合、TiCDC 所有者は、PD サービスの GC セーフポイントをすべてのレプリケーション タスクの中で最も小さい値checkpoint-ts
で更新します。サービス GC セーフポイントは、TiCDC がその時点およびその後に生成されたデータを削除しないことを保証します。レプリケーション タスクが中断または手動で停止された場合、このタスクのcheckpoint-ts
変わりません。一方、PDの対応サービスGCセーフポイントも更新されない。
レプリケーション タスクがgc-ttl
で指定された時間より長く一時停止されている場合、レプリケーション タスクはfailed
ステータスになり、再開できません。 PD対応サービスGCセーフポイントは継続します。
TiCDC がサービス GC セーフポイントに設定する存続時間 (TTL) は 24 時間です。これは、TiCDC サービスが中断されてから 24 時間以内に回復できる場合、GC メカニズムはデータを削除しないことを意味します。
TiCDC タイム ゾーンとアップストリーム/ダウンストリーム データベースのタイム ゾーンの関係を理解するにはどうすればよいですか?
アップストリームのタイムゾーン | TiCDC タイムゾーン | ダウンストリームのタイムゾーン | |
---|---|---|---|
コンフィグレーション方法 | タイムゾーンのサポートを参照 | TiCDCサーバーの起動時に--tz パラメーターを使用して構成されます | sink-uri のtime-zone パラメータを使用して構成されます |
説明 | アップストリーム TiDB のタイム ゾーン。タイムスタンプ タイプの DML 操作およびタイムスタンプ タイプの列に関連する DDL 操作に影響します。 | TiCDC は、アップストリーム TiDB のタイム ゾーンが TiCDC タイム ゾーン構成と同じであると想定し、タイムスタンプ列に対して関連する操作を実行します。 | ダウンストリーム MySQL は、ダウンストリームのタイムゾーン設定に従って、DML および DDL 操作のタイムスタンプを処理します。 |
注記:
このタイム ゾーンは時間タイプの変換に使用されるため、TiCDCサーバーのタイム ゾーンを設定するときは注意してください。アップストリーム タイム ゾーン、TiCDC タイム ゾーン、およびダウンストリーム タイム ゾーンを一貫した状態に保ちます。 TiCDCサーバーは、次の優先順位でタイム ゾーンを選択します。
- TiCDC は、最初に
--tz
を使用して指定されたタイム ゾーンを使用します。--tz
が使用できない場合、TiCDC はTZ
環境変数を使用してタイム ゾーン セットを読み取ろうとします。TZ
環境変数が使用できない場合、TiCDC はマシンのデフォルトのタイムゾーンを使用します。
--config
で構成ファイルを指定せずにレプリケーション タスクを作成した場合、TiCDC のデフォルトの動作はどうなりますか?
-config
パラメータを指定せずにcdc cli changefeed create
コマンドを使用すると、TiCDC は次のデフォルト動作でレプリケーション タスクを作成します。
- システムテーブルを除くすべてのテーブルをレプリケートします
- 古い値機能を有効にします
- 有効なインデックスを含むテーブルのみをレプリケートします
TiCDC は、Canal 形式でのデータ変更の出力をサポートしていますか?
はい。 Canal 出力を有効にするには、 --sink-uri
パラメータでプロトコルをcanal
として指定します。例えば:
cdc cli changefeed create --server=http://127.0.0.1:8300 --sink-uri="kafka://127.0.0.1:9092/cdc-test?kafka-version=2.4.0&protocol=canal" --config changefeed.toml
注記:
- この機能は TiCDC 4.0.2 で導入されました。
- TiCDC は現在、Kafka などの MQ シンクへの Canal 形式でのデータ変更の出力のみをサポートしています。
詳細については、 TiCDC 変更フィード構成を参照してください。
TiCDC から Kafka までのレイテンシーがますます高くなるのはなぜですか?
Kafka の次のパラメータを調整します。
server.properties
message.max.bytes
値を1073741824
(1 GB) に増やします。server.properties
replica.fetch.max.bytes
値を1073741824
(1 GB) に増やします。consumer.properties
のfetch.message.max.bytes
値を増やして、message.max.bytes
値よりも大きくします。
TiCDC がデータを Kafka にレプリケートする場合、TiDB 内の単一メッセージの最大サイズを制御できますか?
protocol
をavro
またはcanal-json
に設定すると、行の変更ごとにメッセージが送信されます。 1 つの Kafka メッセージには 1 行の変更のみが含まれ、通常は Kafka の制限を超えることはありません。したがって、1 つのメッセージのサイズを制限する必要はありません。単一の Kafka メッセージのサイズが Kakfa の制限を超える場合は、 TiCDC から Kafka までのレイテンシーがますます高くなるのはなぜですか?を参照してください。
protocol
をopen-protocol
に設定すると、メッセージはバッチで送信されます。したがって、1 つの Kafka メッセージが過度に大きくなる可能性があります。この状況を回避するには、 max-message-bytes
パラメーターを構成して、毎回 Kafka ブローカーに送信されるデータの最大サイズを制御できます (オプション、デフォルトでは10MB
)。また、 max-batch-size
パラメーター (オプション、デフォルトでは16
) を構成して、各 Kafka メッセージ内の変更レコードの最大数を指定することもできます。
トランザクション内で行を複数回変更した場合、TiCDC は複数の行変更イベントを出力しますか?
いいえ。1 つのトランザクションで同じ行を複数回変更すると、TiDB は最新の変更のみを TiKV に送信します。したがって、TiCDC は最新の変更の結果しか取得できません。
TiCDC がデータを Kafka にレプリケートするとき、メッセージには複数のタイプのデータ変更が含まれますか?
はい。 1 つのメッセージに複数のupdate
またはdelete
が含まれる場合があり、 update
とdelete
共存する場合もあります。
TiCDC がデータを Kafka にレプリケートする場合、TiCDC Open Protocol の出力でタイムスタンプ、テーブル名、およびスキーマ名を表示するにはどうすればよいですか?
この情報は、Kafka メッセージのキーに含まれています。例えば:
{
"ts":<TS>,
"scm":<Schema Name>,
"tbl":<Table Name>,
"t":1
}
詳細については、 TiCDC オープン プロトコル イベント形式を参照してください。
TiCDC がデータを Kafka にレプリケートするとき、メッセージ内のデータ変更のタイムスタンプを確認するにはどうすればよいですか?
Kafka メッセージのキーのts
右に 18 ビット移動すると、UNIX タイムスタンプを取得できます。
TiCDC オープン プロトコルはnull
をどのように表現しますか?
TiCDC オープン プロトコルでは、タイプ コード6
はnull
を表します。
タイプ | コード | 出力例 | 注記 |
---|---|---|---|
ヌル | 6 | {"t":6,"v":null} |
詳細については、 TiCDC オープン プロトコルの列タイプ コードを参照してください。
TiCDC オープン プロトコルの行変更イベントがINSERT
イベントであるかUPDATE
イベントであるかをどのように判断できますか?
Old Value 機能が有効になっていない場合、TiCDC Open Protocol の行変更イベントがINSERT
イベントであるかUPDATE
イベントであるかを判断できません。この機能が有効になっている場合は、イベントに含まれるフィールドによってイベント タイプを判断できます。
UPDATE
イベントには"p"
と"u"
フィールドの両方が含まれますINSERT
イベントには"u"
フィールドのみが含まれますDELETE
イベントには"d"
フィールドのみが含まれます
詳細については、 オープンプロトコル行変更イベント形式を参照してください。
TiCDC はどのくらいの PDstorageを使用しますか?
TiCDC は PD で etcd を使用してメタデータを保存し、定期的に更新します。 etcd の MVCC と PD のデフォルトの圧縮の間の時間間隔は 1 時間であるため、TiCDC が使用する PDstorageの量は、この 1 時間以内に生成されるメタデータ バージョンの量に比例します。ただし、v4.0.5、v4.0.6、および v4.0.7 では、TiCDC に頻繁な書き込みの問題があるため、1 時間に 1000 のテーブルが作成またはスケジュールされている場合、etcdstorageがすべて占有され、 etcdserver: mvcc: database space exceeded
エラーが返されます。 。このエラーが発生した後は、etcdstorageをクリーンアップする必要があります。詳細はetcd メンテナンススペースクォータ参照してください。クラスターを v4.0.9 以降のバージョンにアップグレードすることをお勧めします。
TiCDC は大規模なトランザクションのレプリケーションをサポートしていますか?リスクはありますか?
TiCDC は、大規模トランザクション (サイズが 5 GB を超える) を部分的にサポートします。さまざまなシナリオに応じて、次のリスクが存在する可能性があります。
- プライマリとセカンダリのレプリケーションのレイテンシーが大幅に増加する可能性があります。
- TiCDC の内部処理能力が不足している場合、レプリケーションタスクエラー
ErrBufferReachLimit
が発生する可能性があります。 - TiCDC の内部処理能力が不足している場合、または TiCDC のダウンストリームのスループット能力が不足している場合、メモリ不足 (OOM) が発生する可能性があります。
v6.2 以降、TiCDC は単一テーブルのトランザクションを複数のトランザクションに分割することをサポートしています。これにより、大規模なトランザクションをレプリケートする際のレイテンシーとメモリ消費量を大幅に削減できます。したがって、アプリケーションにトランザクションのアトミック性に対する高度な要件がない場合は、発生する可能性のあるレプリケーションのレイテンシーと OOM を回避するために、大規模なトランザクションの分割を有効にすることをお勧めします。分割を有効にするには、シンク URI パラメーターの値をtransaction-atomicity
からnone
に設定します。
それでも上記のエラーが発生する場合は、 BRを使用して大規模なトランザクションの増分データを復元することをお勧めします。詳細な操作は次のとおりです。
- 大規模なトランザクションにより終了した変更フィードの
checkpoint-ts
記録し、この TSO をBR増分バックアップの--lastbackupts
として使用し、 増分データバックアップを実行します。 - 増分データをバックアップした後、 BRログ出力で
["Full backup Failed summary : total backup ranges: 0, total success: 0, total failed: 0"] [BackupTS=421758868510212097]
のようなログ レコードを見つけることができます。このログにBackupTS
を記録します。 - 増分データを復元する 。
- 新しい変更フィードを作成し、レプリケーション タスクを
BackupTS
から開始します。 - 古い変更フィードを削除します。
TiCDC は、損失のある DDL 操作によって発生したデータ変更をダウンストリームにレプリケートしますか?
非可逆 DDL は、TiDB で実行するとデータ変更を引き起こす可能性のある DDL を指します。一般的な非可逆 DDL 操作には次のようなものがあります。
- 列の型の変更 (INT -> VARCHAR など)
- 列の長さの変更 (例: VARCHAR(20) -> VARCHAR(10))
- 列の精度の変更 (例: DECIMAL(10, 3) -> DECIMAL(10, 2))
- 列の UNSIGNED または SIGNED 属性の変更 (たとえば、INT UNSIGNED -> INT SIGNED)
TiDB v7.1.0 より前では、TiCDC は同一の新旧データを含む DML イベントをダウンストリームにレプリケートします。ダウンストリームが MySQL の場合、ダウンストリームが DDL ステートメントを受信して実行するまで、これらの DML イベントによってデータは変更されません。ただし、ダウンストリームが Kafka またはクラウドstorageサービスである場合、TiCDC は冗長データの行をダウンストリームに書き込みます。
TiDB v7.1.0 以降、TiCDC ではこれらの冗長な DML イベントが削除され、ダウンストリームにレプリケートされなくなりました。
DDL ステートメントをダウンストリームMySQL 5.7にレプリケートする場合、時間タイプ フィールドのデフォルト値は一貫性がありません。私に何ができる?
create table test (id int primary key, ts timestamp)
ステートメントが上流の TiDB で実行されるとします。 TiCDC がこのステートメントをダウンストリームのMySQL 5.7に複製するとき、MySQL はデフォルトの構成を使用します。レプリケーション後のテーブルスキーマは以下のようになります。 timestamp
フィールドのデフォルト値はCURRENT_TIMESTAMP
になります。
mysql root@127.0.0.1:test> show create table test;
+-------+----------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------+
| test | CREATE TABLE `test` ( |
| | `id` int(11) NOT NULL, |
| | `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, |
| | PRIMARY KEY (`id`) |
| | ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------+
1 row in set
結果から、レプリケーションの前後でテーブルのスキーマが矛盾していることがわかります。これは、TiDB のデフォルト値explicit_defaults_for_timestamp
MySQL のデフォルト値と異なるためです。詳細はMySQL の互換性参照してください。
v5.0.1 または v4.0.13 以降、MySQL へのレプリケーションごとに、TiCDC は自動的にexplicit_defaults_for_timestamp = ON
を設定して、アップストリームとダウンストリームの間で時間タイプが一貫していることを確認します。 v5.0.1 または v4.0.13 より前のバージョンでは、TiCDC を使用して時間型データをレプリケートするときに、一貫性のないexplicit_defaults_for_timestamp
値によって引き起こされる互換性の問題に注意してください。
TiCDC レプリケーション タスクを作成するときにsafe-mode
をtrue
に設定すると、アップストリームからのINSERT
/ UPDATE
ステートメントがダウンストリームにレプリケートされた後にREPLACE INTO
になるのはなぜですか?
TiCDC は、すべてのデータが少なくとも 1 回複製されることを保証します。下流に重複データがあると書き込み競合が発生します。この問題を回避するために、TiCDC はINSERT
とUPDATE
ステートメントをREPLACE INTO
ステートメントに変換します。この動作はsafe-mode
パラメータによって制御されます。
v6.1.3 より前のバージョンでは、 safe-mode
デフォルトはtrue
で、これはすべてのINSERT
およびUPDATE
ステートメントがREPLACE INTO
ステートメントに変換されることを意味します。 v6.1.3 以降のバージョンでは、TiCDC はダウンストリームに重複データがあるかどうかを自動的に判断できるため、デフォルト値safe-mode
がfalse
に変更されます。重複データが検出されない場合、TiCDC はINSERT
およびUPDATE
ステートメントを変換せずに複製します。
レプリケーションのダウンストリームのシンクが TiDB または MySQL の場合、ダウンストリーム データベースのユーザーにはどのような権限が必要ですか?
シンクが TiDB または MySQL の場合、ダウンストリーム データベースのユーザーには次の権限が必要です。
Select
Index
Insert
Update
Delete
Create
Drop
Alter
Create View
recover table
ダウンストリーム TiDB にレプリケートする必要がある場合は、 Super
権限が必要です。
TiCDC はなぜディスクを使用するのですか? TiCDC はいつディスクに書き込みますか? TiCDC はレプリケーションのパフォーマンスを向上させるためにメモリバッファを使用しますか?
アップストリームの書き込みトラフィックがピーク時間にある場合、ダウンストリームはすべてのデータをタイムリーに消費できず、データの蓄積が発生する可能性があります。 TiCDC は、蓄積されたデータをディスクを使用して処理します。 TiCDC は、通常の動作中にデータをディスクに書き込む必要があります。ただし、ディスクへの書き込みのレイテンシーが100 ミリ秒以内であることを考慮すると、これは通常、レプリケーションのスループットとレプリケーションのレイテンシーのボトルネックにはなりません。 TiCDC はまた、メモリを使用してディスクからのデータの読み取りを高速化し、レプリケーションのパフォーマンスを向上させます。
アップストリームからTiDB LightningおよびBRを使用してデータを復元した後、TiCDC を使用したレプリケーションが停止したり停止したりするのはなぜですか?
現在、TiCDC はまだTiDB LightningおよびBRと完全な互換性はありません。したがって、TiCDC によってレプリケートされるテーブルではTiDB LightningおよびBRを使用しないでください。
チェンジフィードが一時停止から再開すると、そのレプリケーションのレイテンシーはますます長くなり、数分後にのみ通常の状態に戻ります。なぜ?
チェンジフィードが再開されると、TiCDC は TiKV 内のデータの履歴バージョンをスキャンして、一時停止中に生成された増分データ ログに追いつく必要があります。レプリケーション プロセスは、スキャンが完了した後にのみ続行されます。スキャンプロセスには数分から数十分かかる場合があります。
異なるリージョンにある 2 つの TiDB クラスター間でデータをレプリケートするには、TiCDC をデプロイするにはどうすればよいですか?
v6.5.2 より前の TiCDC バージョンの場合は、ダウンストリーム TiDB クラスターに TiCDC をデプロイすることをお勧めします。アップストリームとダウンストリーム間のネットワークレイテンシーが長い場合 (たとえば、100 ミリ秒を超える場合)、MySQL 伝送プロトコルの問題により、TiCDC がダウンストリームに対して SQL ステートメントを実行するときに生成されるレイテンシーが大幅に増加する可能性があります。これにより、システムのスループットが低下します。ただし、ダウンストリームに TiCDC を導入すると、この問題を大幅に軽減できます。 TiCDC v6.5.2 以降、最適化後は、上流の TiDB クラスターに TiCDC をデプロイすることをお勧めします。
DML ステートメントと DDL ステートメントを実行する順序は何ですか?
現在、TiCDC は次の順序を採用しています。
- TiCDC は、DDL
CommiTs
まで、DDL ステートメントの影響を受けるテーブルのレプリケーションの進行をブロックします。これにより、DDLCommiTs
より前に実行された DML ステートメントが最初にダウンストリームに正常にレプリケートされることが保証されます。 - TiCDC は DDL ステートメントのレプリケーションを続行します。複数の DDL ステートメントがある場合、TiCDC はそれらをシリアル方式で複製します。
- DDL ステートメントがダウンストリームで実行された後、TiCDC は DDL
CommiTs
の後に実行された DML ステートメントのレプリケーションを続行します。
上流と下流のデータが一貫しているかどうかを確認するにはどうすればよいですか?
ダウンストリームが TiDB クラスターまたは MySQL インスタンスの場合は、 同期差分インスペクター使用してデータを比較することをお勧めします。
単一テーブルのレプリケーションは、単一の TiCDC ノード上でのみ実行できます。複数の TiCDC ノードを使用して複数のテーブルのデータを複製することは可能ですか?
v7.1.0 以降、TiCDC は、TiKV リージョンの粒度でデータ変更ログをレプリケートする MQ シンクをサポートします。これにより、スケーラブルな処理能力が実現され、TiCDC が多数のリージョンを含む単一のテーブルをレプリケートできるようになります。この機能を有効にするには、 TiCDC 構成ファイルで次のパラメータを設定します。
[scheduler]
enable-table-across-nodes = true
アップストリームに長時間実行されているコミットされていないトランザクションがある場合、TiCDC レプリケーションは停止しますか?
TiDB にはトランザクション タイムアウト メカニズムがあります。トランザクションがmax-txn-ttl
より長い期間実行されると、TiDB はトランザクションを強制的にロールバックします。 TiCDC はトランザクションがコミットされるのを待ってからレプリケーションを続行するため、レプリケーションの遅延が発生します。
TiCDC が古い値機能を有効にすると、変更イベント形式にどのような変更が発生しますか?
以下の説明では、有効なインデックスの定義は次のとおりです。
- 主キー (
PRIMARY KEY
) は有効なインデックスです。 - 一意のインデックス (
UNIQUE INDEX
) は、インデックスのすべての列が null 非許容として明示的に定義され (NOT NULL
)、インデックスに仮想生成列 (VIRTUAL GENERATED COLUMNS
) がない場合に有効です。
TiDB は、v5.0 以降、クラスター化インデックス機能をサポートします。この機能は、主キーを含むテーブルにデータを格納する方法を制御します。詳細については、 クラスター化インデックスを参照してください。
古い値の機能を有効にすると、TiCDC は次のように動作します。
- 無効なインデックス列の変更イベントの場合、出力には新しい値と古い値の両方が含まれます。
- 有効なインデックス列の変更イベントの場合、出力は特定の条件に基づいて異なります。
- 一意のインデックス列 (
UNIQUE INDEX
) が更新され、テーブルに主キーがない場合、出力には新しい値と古い値の両方が含まれます。 - 上流の TiDB クラスターでクラスター化インデックスが無効になっており、非 INT タイプの主キー列が更新された場合、出力には新しい値と古い値の両方が含まれます。
- それ以外の場合、変更イベントは古い値の削除イベントと新しい値の挿入イベントに分割されます。
- 一意のインデックス列 (
上記の動作変更により、次の問題が発生する可能性があります。
有効なインデックス列の変更イベントに新しい値と古い値の両方が含まれている場合、Kafka シンクの分散動作では、同じインデックス列を持つ変更イベントが同じパーティションに分散されることが保証されない可能性があります。
Kafka Sink のインデックス値モードは、インデックス列の値に従ってイベントを分散します。変更イベントに新しい値と古い値の両方が含まれる場合、インデックス列の値が変更され、同じインデックス列を持つ変更イベントが異なるパーティションに分散される可能性があります。以下は例です。
TiDB クラスター化インデックス機能が無効になっている場合にテーブルt
を作成します。
CREATE TABLE t (a VARCHAR(255) PRIMARY KEY NONCLUSTERED);
次の DML ステートメントを実行します。
INSERT INTO t VALUES ("2");
UPDATE t SET a="1" WHERE a="2";
INSERT INTO t VALUES ("2");
UPDATE t SET a="3" WHERE a="2";
古い値機能が無効になっている場合、変更イベントは古い値の削除イベントと新しい値の挿入イベントに分割されます。 Kafka Sink のインデックス値ディスパッチャは、各イベントに対応するパーティションを計算します。前述の DML イベントは次のパーティションに分散されます。
パーティション-1 パーティション-2 パーティション-3 a = 2を挿入 a = 1 を挿入 a = 3 を挿入 削除 a = 2 a = 2を挿入 削除 a = 2 Kafka は各パーティション内のメッセージの順序を保証するため、コンシューマーは各パーティション内のデータを独立して処理し、DML の実行順序と同じ結果を得ることができます。
Old Value 機能が有効になっている場合、Kafka シンクのインデックス値ディスパッチャーは、同じインデックス列を持つ変更イベントを異なるパーティションに分散します。したがって、前述の DML は次のパーティションに分散されます (変更イベントには新しい値と古い値の両方が含まれます)。
パーティション-1 パーティション-2 パーティション-3 a = 2を挿入 a = 1 を更新 (a = 2) a = 3 を更新します (a = 2)。 a = 2を挿入 Kafka はパーティション間のメッセージの順序を保証しないため、前述の DML は使用中にインデックス列の更新順序を保持しない可能性があります。出力に新しい値と古い値の両方が含まれている場合にインデックス列の更新順序を維持するには、古い値機能を有効にするときにデフォルトのディスパッチャーを使用できます。
無効なインデックス列の変更イベントと有効なインデックス列の変更イベントの両方に新しい値と古い値が含まれている場合、Kafka シンクの Avro 形式は古い値を正しく出力できません
Avro 実装では、Kafka メッセージ値には現在の列の値のみが含まれます。したがって、イベントに新しい値と古い値が両方含まれている場合、古い値は正しく出力されません。古い値を出力するには、古い値機能を無効にして、分割削除イベントと挿入イベントを取得します。
無効なインデックス列の変更イベントと有効なインデックス列の変更イベントの両方に新しい値と古い値が含まれている場合、Cloud Storage シンクの CSV 形式は古い値を正しく出力できません
CSV ファイルの列数は固定されているため、イベントに新しい値と古い値が両方含まれる場合、古い値は正しく出力されません。古い値を出力するには、Canal-JSON 形式を使用できます。
TiDB Operatorによってデプロイされた TiCDC クラスターを操作するためにcdc cli
コマンドを使用できないのはなぜですか?
これは、 TiDB Operatorによってデプロイされた TiCDC クラスターのデフォルトのポート番号が8301
であるのに対し、TiCDCサーバーに接続するcdc cli
コマンドのデフォルトのポート番号が8300
であるためです。 cdc cli
コマンドを使用してTiDB Operatorによってデプロイされた TiCDC クラスターを操作する場合は、次のように--server
パラメーターを明示的に指定する必要があります。
./cdc cli changefeed list --server "127.0.0.1:8301"
[
{
"id": "4k-table",
"namespace": "default",
"summary": {
"state": "stopped",
"tso": 441832628003799353,
"checkpoint": "2023-05-30 22:41:57.910",
"error": null
}
},
{
"id": "big-table",
"namespace": "default",
"summary": {
"state": "normal",
"tso": 441872834546892882,
"checkpoint": "2023-06-01 17:18:13.700",
"error": null
}
}
]