外键依赖检查

最近更新时间:2026-02-05 16:42:00

我的收藏
在 DTS 数据迁移过程中,系统会对源库的外键依赖关系进行校验,确保迁移任务能够正确处理外键约束,保证数据一致性。
说明:
适用范围:MySQL/MariaDB/Percona/TDSQL-C MySQL/TDSQL MySQL/TDSQL Boundless 之间的数据迁移。

检查详情

存在特殊外键规则:DTS 默认支持 RESTRICTNO ACTION,如果源库中存在 CASCADESET NULLSET DEFAULT 三种外键数据,则预检查显示失败。
关联表不齐全:部分库表迁移时,有外键依赖的表未勾选齐全,则预检查显示失败。


外键规则说明

MySQL 系列的数据库在设置外键时,删除和更新支持以下规则。
规则
说明
RESTRICT
父表进行删除或更新记录时,如果子表中有关联该父表的记录,则拒绝该父表的删除请求。
NO ACTION
与 RESTRICT 相同,先检查外键约束再执行操作。
CASCADE
父表进行删除或更新记录时,子表同步删除或更新关联记录。
SET NULL
父表进行删除或更新记录时,子表会将关联记录的外键字段所在列设为 NULL(子表外键不能设为 NOT NULL)。
SET DEFAULT
父表进行删除或更新记录时,子表将外键列设为默认值(InnoDB 不支持)。

示例数据

-- 订单表(父表)
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_name VARCHAR(50)
);

-- 订单明细表(子表)
CREATE TABLE order_items (
id INT PRIMARY KEY,
order_id INT,
product_name VARCHAR(100),
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE
);

-- 插入测试数据
INSERT INTO orders VALUES (100, '张三');
INSERT INTO order_items VALUES (1, 100, 'iPhone 15');
INSERT INTO order_items VALUES (2, 100, '手机壳');
INSERT INTO order_items VALUES (3, 100, '充电器');

修复方法

存在特殊外键规则
关联表不齐全
DTS 默认支持 RESTRICTNO ACTION,当源库存在 CASCADESET NULLSET DEFAULT 类型的外键时,校验系统会提示报错,您可以选择以下任一方案进行修复。

方案一:屏蔽外键依赖检查报错

1. 在数据迁移操作中的校验任务页面,单击查看详情,查看校验项详情。

2. 选择屏蔽外键依赖检查报错,忽略校验报错,继续迁移任务。

说明:
由于 DTS 通过 binlog 同步数据变更,DTS 只同步用户执行的 SQL,级联操作不会被 binlog 记录,因此目标库不会执行级联操作,从而导致源库父表的删除或更新操作可能导致目标库与源库数据不一致。
示例说明(以CASCADE为例)
当源库使用CASCADE等级联规则时,删除父表记录会自动级联删除子表的关联记录。但 binlog 只记录用户执行的 SQL 语句(例如,DELETE FROM orders WHERE id = 100),不会记录级联操作自动删除的子表记录。如果未开启外键依赖迁移,DTS 只会同步父表的删除操作,子表的级联删除不会被同步,从而导致:
源库:父表和子表记录都被删除。
目标库:仅父表记录被删除,子表记录仍然存在。
最终造成源库和目标库数据不一致。
2.1 源库和目标库已同步完成。
SELECT * FROM orders;
+-----+---------------+
| id | customer_name |
+-----+---------------+
| 100 | 张三 |
+-----+---------------+

SELECT * FROM order_items;
+----+----------+--------------+
| id | order_id | product_name |
+----+----------+--------------+
| 1 | 100 | iPhone 15 |
| 2 | 100 | 手机壳 |
| 3 | 100 | 充电器 |
+----+----------+--------------+
2.2 源库删除数据(触发级联删除)。
DELETE FROM orders WHERE id = 100;
-- Query OK, 1 row affected
SELECT * FROM orders;
-- Empty set
SELECT * FROM order_items;
-- Empty set ← 3 条记录全部被级联删除
# binlog 只记录:DELETE FROM orders WHERE id = 100
(级联删除的 3 条 order_items 不会记录在 binlog 中)
2.3 目标库同步上一步删除数据操作(未执行级联删除)。
DELETE FROM orders WHERE id = 100;
-- Query OK, 1 row affected
# 目标库执行结果
SELECT * FROM orders;
-- Empty set
SELECT * FROM order_items;
+----+----------+--------------+
| id | order_id | product_name |
+----+----------+--------------+
| 1 | 100 | iPhone 15 | ← 未被删除!
| 2 | 100 | 手机壳 | ← 未被删除!
| 3 | 100 | 充电器 | ← 未被删除!
+----+----------+--------------+
2.4 结果显示 DTS 只会同步父表的删除操作到目标库,而子表的级联删除不会被同步,从而导致源库和目标库数据不一致。
3. 确认无误后勾选风险知会,单击确认
4. 重新执行校验任务。

方案二:开启迁移外键依赖关系

1. 在数据迁移操作中的校验任务页面,单击查看详情,查看校验项详情。
2. 选择迁移外键依赖关系,继续迁移任务。
开启迁移外键依赖关系后,支持迁移 CASCADESET NULLSET DEFAULT 类型的外键依赖关系。
说明:
1. DTS 仅在任务发起时检查外键依赖关系,保证存量数据迁移到目标库的一致性。
2. 任务迁移过程中请勿修改源库中的外键依赖规则,否则将导致目标库数据与源库不一致。
例如,在迁移过程中,将源库外键规则从 CASCADE 修改为 NO ACTION,目标库中父表的更新及删除操作仍会影响子表。
3. 当外键规则为 CASCADESET NULL 时,勾选迁移外键依赖关系后,在全量迁移阶段会对源库短暂加表锁,影响时间约5-10秒。
4. 为保证数据的一致性,增量同步阶段对外键相关表的数据传输将从行级同步降级为表级同步,性能会有所下降。
3. 确认无误后勾选风险知会,单击确认
4. 重新执行校验任务。

方案三:修改源库外键规则

Windows 操作指导(DMC 平台)
2. 在左侧目标树上选中要修改的表,在打开的表编辑界面上,单击外键页签,修改外键参数,如下图所示。

3. 修改完成后,单击提交
4. 重新执行校验任务。
Linux 操作指导(命令行)
2. 删除原有的外键设置。
alter table `表名称1` drop foreign key `外键名称1`;
3. 重新添加外键设置。
alter table `表名称1` add constraint `外键名称2` foreign key `表名称1`(`列名1`) references `表名称2`(`列名1`)
on update no action on delete no action;
4. 重新执行校验任务。
当部分库表迁移时,有外键依赖的表必须全部选择,否则校验会失败。
1. DTS 控制台,选择对应的迁移任务,在操作列选择更多 > 修改
2. 迁移对象中勾选具有关联关系的所有表(包括父表和子表)。
3. 重新执行校验任务。