ITPub博客

首页 > 数据库 > Oracle > 数据库大版本升级27个约束消失之谜--技术人生系列第五十二期-我和数据中心的故事

数据库大版本升级27个约束消失之谜--技术人生系列第五十二期-我和数据中心的故事

Oracle 作者:记录每一次错误 时间:2018-12-04 17:02:04 0 删除 编辑

现象描述


数据库大版本升级的过程是相对复杂和繁琐的,非标准流程下100套系统可能会遇到100个不同的问题,这种问题相对好解决,那么本期的问题来了,

在使用EXPDP/IMPDP工具,从Oracle 10.2.0.4迁移到11.2.0.4之后,约束比对时发现,原生产环境10.2.0.4的数据库比 新生产11.2.0.4环境中多了27个约束:


select owner,CONSTRAINT_TYPE,STATUS,count(*) from dba_constraints where OWNER IN ( xxx,xxx) group by owner,CONSTRAINT_TYPE, STATUS;

select owner,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,STATUS from dba_constraints where CONSTRAINT_TYPE='?';

下面是原生产环境10.2.0.4中27个类型为?的约束的详细信息,你没有看错,不是乱码,确实是 ,源环境出现了 类型的约束。



 停下来想一想,假如遇到这个问题怎么办,希望本次分享给你提供一个解决思路,让你不要慌得一比。


从以上问题现象来看,很容易产生以下疑问:

|-  10.2.0.4 类型为?的约束是如何产生的

|-   迁移到 11.2.0.4 为什么没有 类型为?的约束,是丢弃了,还是 11G 不支持了?

|- 使用 EXPDP/IMPDP 工具能否迁移这种类型为? 的约束


约束类型为?的约束是如何产生的------第一招官方文档


Oracle 的官方对于 DBA_CONSTRAINTS 视图的解释来看, Oracle 10G 和11 G 都没有类型为?的约束:

  Oracle 10G 官方文档 DBA_CONSTRAINTS 的说明


  Oracle 11G 官方文档 ALL_CONSTRAINTS 的说明


由于官方文档并没有给出相应的解释。继续发功

约束类型为?的约束是如何产生的------第二招执行计划


Oracle 的官方对于 DBA_CONSTRAINTS 视图的解释来看, Oracle 10G 和11 G 都没有类型





我们可以通过下面方法跟踪查询 dba_constraints 视图的执行计划,看看会有什么发现:

SQL> SET AUTOT TRACE

SQL> select * from dba_constraints where constraint_type='?';


下面的执行计划,应该很容易看出来类型为?的约束是怎么来的了吧......,划重点注意红色框框

执行计划第 12步,查询 CDEF$ 基表时,下面相关联的过滤条件是 :

filter("C"."TYPE#"<>12 AND DECODE("C"."TYPE#",1,'C',2,'P',3,'U',4,'R',5,'V',6,'O',7,'C', '? ')='?' AND "C"."TYPE#"<>8)

也就是说,只要TYPE#不是1-7,12,8,其他值都被转换成了?。


所以,?类型约束的产生是由于DBA_CONSTRAINTS视图内部转换导致的,我们可以通过查询视图DBA_CONSTRAINTS的定义信息确认这一点:

SQL > select TEXT_LENGTH,text from dba_views where view_name='DBA_CONSTRAINTS';

可以看到type#确实做了DECODE转换:


那么,原生产10.2.0.4中的27个类型为?的约束,它的CDEF$.TYPE#值肯定不属于1-7,12,8,我们可以通过如下方式确认:

SQL> select CON# ,OBJ#,COLS,TYPE#  from CDEF$  where TYPE# not in (1,2,3,4,5,6,7,8,12);

可以看到,这些类型为?的约束,它的底层TYPE#其实是17:

那么,问题来了,这个CDEF$.TYPE#= 17的约束是什么约束, 怎么产生的?

通过查看下$ORACLE_HOME/rdbms/admin/sql.bsq数据字典cdef$的定义语句,可以看到,类型17是表示这个表上所有列加了附加日志:

从附加日志很容易联想到OGG,检查客户环境源端10.2.0.4确实配置了OGG,和客户确认后确实是在这些表上加了全列的附加日志。所以,到此问题原因就找到了。

知道CDEF$.TYPE#=17的约束的含义,重现就很简单了。

测试重现类型为17的约束


通过在表上添加所有列的附件日志,观察是否能重现类型为?的约束。

 - 10g环境,DBA_CONSTRAINTS视图可以查到类型为?的约束:

ALTER TABLE "SCOTT"."EE" ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS  ;
select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,status from dba_constraints where owner='SCOTT' AND TABLE_NAME='EE';

 - 11g环境,查询dba_constraints视图是无法找到类型为?的约束的

ALTER TABLE "SCOTT"."EE" ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS  ;

select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,status from dba_constraints where owner='SCOTT' AND TABLE_NAME='EE;

no rows...

但是查询cdef$基表确实是有TYPE#=17的约束的:

select owner,object_name,name constraint_name,cols,type#,enabled from cdef$ a,con$ b,dba_objects c where a.obj#=c.object_id and a.con#=b.con# and c.object_name='EE';

这就回到了最开始的问题,10G迁移到11G后,为什么DBA_CONSTRAINTS视图中找不到类型为?的约束,从上面的测试来看,TYPE#=17的约束就是类型为?的约束,只是11G在DBA_CONSTRAINTS视图中查询不到而已:

那,为什么11g的DBA_CONSTRAINTS视图查不到类型为?的约束  


为什么11g的DBA_CONSTRAINTS视图

查不到类型为?的约束


我们可以看下11G中视图DBA_CONSTRAINTS的定义,视图也是做了DECODE转换,但是多了过滤条件 (c.type# < 14 or c.type# > 17) /* don't include supplog cons*/, 也就是说Oracle把TYPE#=14-17的约束都排除掉了,所以即使CDEF$基表中存在TYPE=17的约束,DBA_CONSTRAINTS中就不会显示:

select TEXT_LENGTH,text from dba_views where view_name='DBA_CONSTRAINTS';

- 类型为?的约束如何删除:

直接删除表上的全列附加日志即可

alter table scott.ee drop supplemental log data (all) columns;


最后一个问题


使用EXPDP/IMPDP工具能否把这种类型为? 的约束从10g环境迁移到11g环境

答案是:可以,迁移到11g环境后,虽然通过dba_constraints视图查询不到,但是可以通过基表cdef$查询到,和原库比对是一致的,也是27个:

select owner,object_name,name constraint_name,cols,type#,enabled from cdef$ a,con$ b,dba_objects c where a.obj#=c.object_id and a.con#=b.con# and type#=17 and owner IN (XXX,XXX) order by 1,2,3;


总 结(文末重磅消息不要错过)


10g/11g 中,对表添加所有列的附加日志都会产生类型 17 的约束,只是通过 dba_constraints 视图查询有所区别:

  •   10g 环境,转换为 ? 显示

  •   11g 环境,类型为 17 的约束直接被排除,不显示。但是可以通过基表 cdef$ 可以查到。

  •   使用EXPDP/IMPDP工具是可以迁移这种约束的。只是对比的方法要做调整。

本文转载于中亦安图

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31547066/viewspace-2284109/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
性格开朗,有较强的学习能力,对oracle数据库的体系结构,搭建RAC,timesten,goldengate,分布式数据库,dataguard,系统调优有较深入的了解, 尤其是oracle优化,深入学习的主机命令,对数据库的优化,SQL语句的优化有深入的认识,目前正在shell脚本,mysql,以后会有计划学习大数据和python。

注册时间:2018-07-23

  • 博文量
    182
  • 访问量
    324313