点击蓝字,关注我们
作者简介
彭占元,2018年8月加入去哪儿网,现负责公司 PostgreSQL GreenPlum 运维工作,对数据库日常运维和日常调优有大量优化实践经验。
1 问题提出
近期在做多个数据源 DB 的数据向一个目标 DB 做数据迁移的过程中,遇到有外键约束的表,由于表之间数据的依赖关系和数据的导入顺序导致数据加载失败,因此记录了一下关于这类问题的解决思路。
testa 中 t1 表结构及数据如下:
当恢复数据时,由于数据导入顺序问题,可能会出现违反约束的报错。
比如,首先恢复的 t2 表中数据,此时会有如下的报错:
2 分析问题
这里数据本身并没有问题,只是当时恢复表数据时候首先恢复了 t2 表导致了违反外键约束的报错,此时我们可以首先禁用 t2 表上的外键约束并在加载对其进行验证。
通过查看系统表 pg_constraint,我们可以看到约束记录的状态为已验证。
3 解决问题
那么我们应该如何处理数据恢复中的外键约束问题并且使新数据和老数据都进行有效性验证呢?
方法1:删除外键
删除表中的所有外键
加载数据
重新创建外键,但使其无效,以避免增大 cost,现在数据会被验证
当系统功能负载较小时,验证约束
这样的方式,创建无效外键对后续新插入和更新的数据有约束作用,在外键检查时对之前存在的数据可以进行检查,从而保证所有的数据符合外键约束。
方法2:修改系统表状态
通过上面的测试我们可以知道,在对约束禁用期间,约束记录的状态为已验证,此时我们可以直接更新系统表 pg_constraint。
在这种情况下,这个约束将被完全验证,因为他在系统表中记录为无效。
方法3:约束延迟生效
这样做的缺点是它仅在一个事务中生效。因此,必须在事务中保证各表之间数据的约束。
4 小结
迁移数据时,如果涉及外键约束的多个表的导入(尤其来自多个数据源,原始数据不一定满足约束关系),灵活启用/禁用及验证外键约束,可使迁移后合并的数据切实满足外键约束,保证 DB 中的关系完整性。
END