TiCDC Table Routing New in v8.5.7
TiCDC のテーブルルーティングを使用すると、changefeed の設定を通じて、上流テーブルを特定の下流データベース名またはテーブル名にマッピングできます。この機能は TiCDC new architecture にのみ適用され、TiCDC classic architecture ではサポートされません。
テーブルルーティングは、TiCDC が下流に出力するデータベース名とテーブル名のみを変更します。行データ、カラム名、テーブルスキーマ、テーブルフィルタルール、トピックディスパッチルール、パーティションディスパッチルール、またはカラムセレクタルールは変更しません。
使用シナリオ
次のシナリオでテーブルルーティングを設定できます。
sales.ordersをarchive.sales_ordersにレプリケートする場合、または他の下流命名規則に従うテーブルにレプリケートする場合。- 複数のソースデータベースを同じターゲットデータベースにレプリケートしつつ、ソースデータベースを区別できるようにターゲットテーブル名を一意に保つ場合。たとえば、
tenant_001.ordersをtenant_mirror.tenant_001_ordersにレプリケートする場合。 - マイグレーション、ディザスタリカバリ、アーカイブ、またはシャドウトラフィック用の changefeed を構築し、上流と同じ名前の下流オブジェクトへの書き込みを避ける場合。
- MQ コンシューマーアプリケーションまたはストレージサービスに対して、安定したデータベース名とテーブル名を公開する場合。
テーブルルーティングを設定する
テーブルルーティングを設定する前に、TiCDC new architecture を有効にしてください。詳細は newarch を参照してください。
次の例では、sales.orders を archive.sales_orders にルーティングします。
[sink]
[[sink.dispatchers]]
matcher = ["sales.orders"]
target-schema = "archive"
target-table = "{schema}_{table}"
changefeed の開始後、TiCDC は sales.orders の DML および DDL イベントを下流の archive.sales_orders に書き込みます。
CREATE DATABASE、DROP DATABASE、ALTER DATABASEなどのデータベースレベル DDL については、TiCDC がルーティングルールに基づいて一意のターゲットデータベースを判定できる必要があります。そうでない場合、その DDL のレプリケーションは失敗します。- 同じ上流データベース内の異なるテーブルを異なるターゲットデータベースにルーティングしたい場合は、下流のターゲットデータベースを事前に作成し、自動レプリケーションが必要な上流のデータベースレベル DDL の実行を避ける必要があります。
設定フィールド
テーブルルーティング機能を使用するには、sink.dispatchers で次のフィールドを設定できます。
一致動作は次のとおりです。
- テーブルルーティングには、
target-schemaまたはtarget-tableを指定したsink.dispatchersルールのみが使用されます。 - 1 つのテーブルが複数のテーブルルーティングルールに一致する場合、
sink.dispatchers内で最初に一致したルールのみが有効になります。 matcherは常に上流のデータベース名とテーブル名に一致し、ルーティング後のターゲットデータベース名やテーブル名には一致しません。- changefeed 設定項目
case-sensitiveは、テーブルルーティング内のmatcherが大文字小文字を区別するかどうかにのみ影響します。{schema}および{table}から展開される値の大文字小文字は変更しません。詳細はcase-sensitiveを参照してください。
プレースホルダー
target-schema と target-table では、次のプレースホルダーを使用できます。
target-schema と target-table の値には、リテラルテキスト、{schema}、{table} のみを含めることができます。{db} のような未知のプレースホルダーを使用すると、TiCDC は changefeed 設定を拒否し、CDC:ErrInvalidTableRoutingRule エラーを返します。
ソーステーブル sales.orders を例にすると、次のようになります。
例
1 つのデータベース内のすべてのテーブルをルーティングする
次の設定では、sales データベース内のすべてのテーブルを archive データベースにルーティングし、ターゲットテーブル名に _bak を追加します。
[filter]
rules = ["sales.*"]
[sink]
[[sink.dispatchers]]
matcher = ["sales.*"]
target-schema = "archive"
target-table = "{table}_bak"
ルーティング結果の例:
sales.ordersはarchive.orders_bakにルーティングされます。sales.order_itemsはarchive.order_items_bakにルーティングされます。
複数のデータベースを同じターゲットデータベースにルーティングする
複数のデータベースを同じターゲットデータベースにルーティングする場合は、ターゲットテーブル名の一意性を確保するために、target-table に {schema} を含めることを推奨します。
[filter]
rules = ["sales.*", "crm.*", "finance.*"]
[sink]
[[sink.dispatchers]]
matcher = ["sales.*", "crm.*", "finance.*"]
target-schema = "archive"
target-table = "{schema}_{table}"
ルーティング結果の例:
sales.ordersはarchive.sales_ordersにルーティングされます。crm.ordersはarchive.crm_ordersにルーティングされます。finance.ordersはarchive.finance_ordersにルーティングされます。
Kafka sink の topic および partition dispatchers と一緒にテーブルルーティングを使用する
同じ dispatcher ルール内で、テーブルルーティングフィールドと既存の dispatch フィールドの両方を設定できます。
[filter]
rules = ["sales.orders"]
[sink]
[[sink.dispatchers]]
matcher = ["sales.orders"]
topic = "order-events"
partition = "index-value"
target-schema = "public"
target-table = "orders"
前述の例では、テーブルルーティングにより、下流データで公開されるデータベース名とテーブル名が public.orders に変更されます。
テーブルルーティングは、topic または partition のディスパッチ結果を変更しません。topic および partition dispatchers は、引き続き上流テーブル sales.orders に基づいて一致判定とディスパッチ計算を行います。
出力動作
DDL の動作
テーブルルーティングを有効にすると、TiCDC は DDL ステートメントを書き換え、構造化 DDL メタデータ内のデータベース名とテーブル名が SQL テキスト内のものと一貫するようにします。
たとえば、次のルールが設定されている場合:
[[sink.dispatchers]]
matcher = ["sales.*"]
target-schema = "archive"
target-table = "{table}_routed"
次の上流 DDL ステートメントに対して:
RENAME TABLE `sales`.`temp_table` TO `sales`.`renamed_table`;
TiCDC はこれを次の下流 DDL ステートメントに書き換えます。
RENAME TABLE `archive`.`temp_table_routed` TO `archive`.`renamed_table_routed`;
DDL ステートメントにテーブル参照が含まれており、その参照先テーブルがテーブルルーティングルールに一致する場合、TiCDC は参照先テーブル名も書き換えます。たとえば、TiCDC は CREATE VIEW ステートメント内のテーブル参照や、ALTER TABLE ステートメント内の外部キー参照を書き換えることができます。
CREATE DATABASE、DROP DATABASE、ALTER DATABASE ... CHARACTER SET/COLLATE などのデータベースレベル DDL については、データベース名がテーブルルーティングルールに一致する場合、TiCDC はそのデータベース名を書き換えます。同じ上流データベースが複数のテーブルルーティングルールに一致し、それらのルールが異なるターゲットデータベース名にマッピングされる場合、TiCDC はそのデータベースレベル DDL に対して一意のターゲットデータベースを判定できず、changefeed はテーブルルーティングエラーを返します。
changefeed の作成時または更新時に、TiCDC は現在レプリケーション対象範囲にあるテーブルに基づいてターゲットテーブルの競合をチェックします。実行時には、TiCDC は CREATE TABLE、RENAME TABLE、DROP TABLE、DROP DATABASE などの DDL をレプリケートする際に、競合検出状態を更新します。データベースレベル DDL ステートメントについては、TiCDC はそれをレプリケートする際に一意のターゲットデータベースを判定できるかどうかを評価します。
ルート競合の検出
ルート競合は、1 つの changefeed 内で 2 つの異なる上流テーブルが同じ下流の (schema, table) にルーティングされる場合に発生します。TiCDC は、複数の上流テーブルを同じ下流テーブルにマージすることをサポートしていません。
たとえば、次の設定では競合が発生する可能性があります。
[filter]
rules = ["sales.*", "crm.*"]
[sink]
[[sink.dispatchers]]
matcher = ["sales.*"]
target-schema = "archive"
target-table = "{table}"
[[sink.dispatchers]]
matcher = ["crm.*"]
target-schema = "archive"
target-table = "{table}"
sales.orders と crm.orders の両方がレプリケーション範囲に含まれている場合、両方のテーブルは archive.orders にルーティングされます。TiCDC は changefeed の作成または更新を拒否し、CDC:ErrTableRouteConflict エラーを返します。
changefeed の実行中に、CREATE TABLE や RENAME TABLE などの DDL 文によって、現在レプリケーション範囲に含まれている 2 つの上流テーブルが同じターゲットテーブルにルーティングされるようになると、changefeed は失敗し、CDC:ErrTableRouteConflict エラーを返します。
上流テーブルが削除またはリネームされると、TiCDC はその上流テーブルとターゲットテーブルの間のルーティング関係を削除します。その後、新しい上流テーブルはそのターゲットテーブルを引き続き使用できます。ただし、任意の時点において、同じターゲットテーブルに対応できるのは、現在の changefeed によってレプリケートされている 1 つの上流テーブルのみです。