note-taker:Ethan_Yang
recording time: 2019/09/23
number of docs:10
【前言】
大家都知道,在数据库日常运维中,数据库中一些对象(如:Package、Procedure、Function、View、同义词等会失效,状态为INVALID,需定期检查数据库中存在哪些失效对象。自动失效的对象,一般会在下次调用的时候,会被重新编译,所以一般也不需要人工干预。对于存在异常的对象需要重新编译了;还有一个场景就是数据迁移导也会导致无效对象的产生。
最近做了一次oracle数据库版本升级,版本有11.2.0.4版本升级到两节点RAC架构的12c版本。升级完后例行排查问题,使用如下命令发现升级后的失效对象激增,这是啥原因,怎么解决,本文将进行解答。
本文将回答如下问题:
- 为什么对象突然会失效?
- 如何快速、高效的编译失效对象?
- 如何编辑分区表的无效对象?
一、 对象为啥突然失效
数据库对象失效,大致归纳如下原因:
1: 被引用对象结构发生变化
被引用对象的结构发生改变时,其相关的依赖对象会变为INVALID状态。
数据库中的对象(存储过程,函数,包,视图,触发器),它们往往需要直接或者间接的引用其它对象,对象的依赖包括直接和间接二种,其中直接依赖是指存储对象直接依赖于被引用对象,而间接依赖是指对象间接依赖于被引用对象。
要查看被引用的对象,可以通过下面SQL查看
select * from dba_dependencies where name='&objectname';
select * from all_dependencies where name='&objectname';
select * from user_dependencies where name='&objectname';
实际生产中,不管视图,像存储过程,函数、包等,只是引用的对象发生了变化,均会导致调用对象失效,但并不影响调用,原因为ORACLE在调用时会自动重新编译对象;
Oracle 会自动维护分区索引,对于全局索引,如果在对分区表进行truncate/drop/exchange 操作分区时,此时若没有使用update index,则会导致全局索引失效,需要重建。后续会着重分析下哪些情况下会导致分区表的全局索引和局部索引失效。
注意:
如果对象变化后导致编译有错误,那么此时调用对象时重新编译后也是错误并处于失效状态,调用会出错。
2:被编辑对象出错
发布SQL脚本时(包、存储过程、函数等),测试不充分编译时出错,这时对象变为无效。
3: 数据库升级、迁移时,出现大量无效对象;
个人推断为:数据升级或迁移时,对象之间倚赖关系被破坏,导致被引用对象失效;看过数据泵导出导入过程的朋友都知道,日志中的对象生成顺序、命令执行顺序是不一致的,尤