Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions dm/dm-compatibility-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,22 @@ TiDB Data Migration (DM) 数据迁移工具可以将数据从不同类型的数
从 v8.5.6 开始,DM 以**实验特性**支持同步包含外键约束的表。该支持包括以下改进:

- **安全模式**:在安全模式执行期间,DM 会在每个批次中设置 `foreign_key_checks=0`,并对未修改主键或唯一键值的 `UPDATE` 语句跳过冗余的 `DELETE` 步骤。这可以防止 `REPLACE INTO`(其内部执行为 `DELETE` + `INSERT`)在子表行上触发非预期的 `ON DELETE CASCADE` 效果。详情参见 [DM 安全模式](/dm/dm-safe-mode.md#外键处理-从-v856-版本开始引入)。
- **多 worker 因果关系**:当 `worker-count > 1` 时,DM 会在任务启动时从下游 schema 中读取外键关系并注入因果键。这可确保父表行的 DML 操作先于其依赖的子表行操作完成,从而在多个 worker 之间保持 binlog 顺序。
- **多 worker 因果关系**:当 `foreign_key_checks=1` 且 `worker-count > 1` 时,DM 会在任务启动时从下游 schema 中读取外键关系并注入因果键。这可确保父表行的 DML 操作先于其依赖的子表行操作完成,从而在多个 worker 之间保持 binlog 顺序。从 v8.5.7 开始,在此模式下,DM 支持静态的一对一路由,例如 schema 或表重命名。

> **注意:**
>
> 在迁移包含外键的表之前,请确保上游 schema 使用标准的外键定义。例如,子表外键应引用父表中的完整主键或唯一键。非标准定义(例如仅引用复合主键的一部分)可能会导致上游数据库中的级联行为不一致。DM 不会在同步过程中修正此类 schema 问题。

同步包含外键约束的表存在以下限制:

- 在安全模式下,DM 不支持修改主键或唯一键值的 `UPDATE` 语句。任务会暂停,并报错:`safe-mode update with foreign_key_checks=1 and PK/UK changes is not supported`。如需同步此类语句,请将 `safe-mode` 设置为 `false`。
- 当你在安全模式下启用 `foreign_key_checks=1` 时,DM 不支持修改主键或唯一键值的 `UPDATE` 语句。DM 会暂停任务,并报错:`safe-mode update with foreign_key_checks=1 and PK/UK changes is not supported`。如需同步此类语句,请将 `safe-mode` 设置为 `false`。
- 当 `foreign_key_checks=1` 时,DM 不支持在同步过程中执行创建、修改或删除外键约束的 DDL 语句。
- 当 `worker-count > 1` 时,不支持表路由。如果对包含外键的表使用表路由,请将 `worker-count` 设置为 `1`。
- 黑白名单过滤 (Block & Allow List) 必须包含外键依赖链中的所有祖先表。如果祖先表被过滤,在增量复制期间任务会报错并暂停。
- 源端与下游的外键元数据必须保持一致。如果检测到不一致,请运行 `binlog-schema update --from-target` 以重新同步元数据。
- 当 `UPDATE` 修改主键或唯一键值时,安全模式下无法正确同步 `ON UPDATE CASCADE`。这是因为 DM 会将此类语句改写为 `DELETE` + `REPLACE`,从而触发 `ON DELETE` 行为而不是 `ON UPDATE` 行为。在这种情况下,DM 会拒绝该语句并暂停任务。未修改键值的 `UPDATE` 语句可以被正确同步。
- 从 v8.5.7 开始,当 `foreign_key_checks=1` 且 `worker-count > 1` 时,DM 仅支持对包含外键的表使用静态一对一路由规则。在此模式下,DM 仍会拒绝将任务中的多个源表映射到同一个目标表的路由规则。对于非一对一路由,请将 `worker-count` 设置为 `1` 或修改路由规则。
- 当 `foreign_key_checks=1` 时,DM 不支持 `syncer.compact` 或 `syncer.multiple-rows`,因为这些选项可能会改变 DML 语句边界和外键执行语义。
- 当 `foreign_key_checks=1` 且 `worker-count > 1` 时,DM 会拒绝可能改变外键因果关系语义的热更新配置,包括更新 `worker-count`、`case-sensitive`、路由规则、`block-allow-list` 或 `black-white-list` 规则、binlog 事件过滤规则以及 `foreign_key_checks`。如需更改这些设置,请停止任务并使用修改后的配置重新启动任务。
- 当 `foreign_key_checks=1` 时,`block-allow-list` 必须包含外键依赖链中的所有祖先表。如果过滤掉祖先表,DM 会在增量复制期间报错并暂停任务。
- 当 `foreign_key_checks=1` 时,源端与下游的外键元信息必须保持一致。如果 DM 检测到不一致,请运行 `binlog-schema update --from-target` 以重新同步元信息。
- 当你在安全模式下启用 `foreign_key_checks=1` 时,如果某个 `UPDATE` 修改了主键或唯一键值,DM 无法正确同步 `ON UPDATE CASCADE`。这是因为 DM 会将此类语句改写为 `DELETE` + `REPLACE`,从而触发 `ON DELETE` 行为而不是 `ON UPDATE` 行为。在这种情况下,DM 会拒绝该语句并暂停任务。DM 可以正确同步未修改键值的 `UPDATE` 语句。

在 v8.5.6 之前的版本中,DM 会在下游创建外键约束,但由于其将会话变量 [`foreign_key_checks=OFF`](/system-variables.md#foreign_key_checks),这些约束不会被强制执行。因此,级联操作不会被同步到下游。

Expand Down
4 changes: 3 additions & 1 deletion dm/dm-safe-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ REPLACE INTO dummydb.dummytbl (id, int_value, ...) VALUES (123, 888999, ...); -

### 多 worker 外键因果关系

当你将 `worker-count` 设置为大于 1 且同步任务包含带有外键的表时,DM 会在任务启动时从下游的 `CREATE TABLE` schema 中读取外键关系。对于每个 DML 操作,DM 会基于这些关系注入因果键,从而确保父表行及其依赖的子表行的操作被分配到同一个 DML worker 队列中。
如果 `foreign_key_checks=1`、`worker-count > 1`,且同步任务包含带有外键的表,DM 会在任务启动时从下游的 `CREATE TABLE` schema 中读取外键关系。对于每个 DML 操作,DM 会基于这些关系注入因果键,从而确保 DM 将父表行及其依赖的子表行的操作分配到同一个 DML worker 队列中。

从 v8.5.7 开始,在此模式下,DM 支持静态的一对一路由,例如 schema 或表重命名。DM 仍然拒绝将任务中的多个源表映射到同一个目标表的路由规则。

详细限制参见 [DM 兼容性目录](/dm/dm-compatibility-catalog.md#外键-cascade-操作)。

Expand Down
Loading