expdp数据迁移序列值导入失败,导致新增数据违反唯一约束,调整所有序列值

记录一次expdp数据迁移踩到的坑
最近给用户做了一次数据迁移,采用expdp数据泵,由于初出茅庐经验不足犯下了一个低级错误,分享给大家参考学习~~
环境
旧库:
windows
oracle 11g
新库:
centos7.8
oracle 11g rac
数据大小:压缩后10g
实施演练:
2020年09月03日
集群数据库为空库
将旧库数据还原至集群

导入脚本:
impdp system/oracle directory=expdp dumpfile=20200903.dmp full=y logfile=20200903.log cluster=n table_exists_action=replace
验证测试:
应用方验证测试正常。

正式实施:
2020年09月11日22点
采用了如下相同方法还原
导入脚本:
impdp system/oracle directory=expdp dumpfile=20200911.dmp full=y logfile=20200911.log cluster=n table_exists_action=replace

应用方测试:
应用反馈有序列值发生了变化,当时手动修改处理了。没过多关注。

问题出现

周一 新库业务正式启用
2020年09月14日9点10
问题陆续出现,业务群反馈无法新增数据,违反唯一条件。

问题排查:
经过和应用方探讨得知表中数据大量使用了序列作为主键。
仔细检查导入日志:
因为用了table_exists_action=replace参数,表数据已存在都会被替换,这个告警是正常告警。
第一次检查也觉得是正常的。
当这次排查时再次看到:
ORA-31684: Object type SEQUENCE:“xxx”.“xx_ID” already exists
这让我引起了怀疑
果然~
序列有一定的特殊性,此次导入前已经存在的序列,还原时是无法导入替换的,最新序列值恢复失败(举个例子,序列"xx"."xx_ID"的值在9月3日第一导入时是100、老库(原来的生产库)9月3日到9月11日这段时间办理业务 产生了新的一些数据(假设序列值最大值已经到110),新库在正式启用前是个静态库、没有数据更新),9月11日导入后,序列对应的表里主键值(序列值最大值)是110、但是数据库缓存里的下一个值还是101(实际上101为主键的这行记录已经有了),导致该部分表无法插入新数据。

还有同义词、包、函数、存储过程这些也会导入失败,在已存在的情况下。

问题反思:
由于以前做expdp迁移,全库导出导入,覆盖导入,用的同一方法,未遇到过此类问题,再次是对数据泵没有完全熟悉。本次在做迁移时,直接覆盖导入,操作前未将旧数据全部DROP,序列导入失败导致的杯具。

解决方案:
步骤1:调整所有用户序列的增长步长为10000:
将库中所有非默认用户的序列值+10000(加大最大值),再插入数据时则不会再出现唯一约束;
SELECT ‘Alter Sequence ‘||sequence_owner||’.’|| SEQUENCE_NAME || ’ Increment By ’ || to_char(10000)||’;’ from DBA_SEQUENCES
WHERE SEQUENCE_OWNER in
(select b.username from dba_users b
where b.account_status = ‘OPEN’ and b.username not in(‘SYS’, ‘SYSTEM’, ‘SYSMAN’, ‘MGMT_VIEW’, ‘DBSNMP’, ‘SAMPLE_DBA’))

步骤2:调整增长步长为1
SELECT ‘Alter Sequence ‘||sequence_owner||’.’|| SEQUENCE_NAME || ’ Increment By ’ || to_char(1)||’;’ from DBA_SEQUENCES
WHERE SEQUENCE_OWNER in
(select b.username from dba_users b
where b.account_status = ‘OPEN’ and b.username not in(‘SYS’, ‘SYSTEM’, ‘SYSMAN’, ‘MGMT_VIEW’, ‘DBSNMP’, ‘SAMPLE_DBA’))

步骤3:处理后观察验证业务已恢复正常。

由于 同义词、包、函数、存储过程等数据库对象,在9月3日到9月11日之间没有主动做过修改,也没有影响;

总结:
本次事故主要由于个人经验不足,犯下的低级错误,实施前没有写好实施文档,同时公司对我太过信任没有做到审核疏忽导致。

expdp做数据迁移前建议
导出前一定要确保停掉所有应用程序、停数据库监听、杀掉客户端进程或会话;
在已经有数据的情况下,一定要先drop user XXX cascade; 然后重新导入。
避免无必要的麻烦。
供大家参考,吸取经验。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值