识别无效对象和不可用对象

----------
pl/sql对象和视图可能变得“无效(invaid)”;索引可能变得“不可用(unusable)”
根据对象无效的原因,下次访问时,对象可能自动变得有效。
而对于不可用索引而言,无法采用自动方式,必须通过重新生成才能变得有效。
如果某个过程对象(如存储的pl/sql函数或视图)变为无效,那么dba不必执行任何操作。首次访问这个对象时,oracle会尝试进行重新编译,而且完全可能编译成功。
但是,如果某个索引由于某种原因变得不可用,那么必须始终在能够使用这额索引之前执行显示地修复操作。

----------------------------------------------------------无效对象--------------------------------------------------

命名的pl/sql对象的代码存储在数据字典中。他们可能是
过程;函数;触发器;包;对象类型
大多数过程对象都将引用数据对象(例如表)在编译过程对象时,编译器将检查其引用的数据对象,以便确认代码的定义正确无误。例如:如果代码引用列,则列存在,否则将无法编译代码。如果过程对象引用的任何数据对象在编译过程代码后发生了变化,则会将此过程标记为invalid。过程对象还可能因为更常见的原因而失败:编程人员犯下了简单的句法错误。在这种情况下,此对象创建时便是无效的,并且不能作用。
同样的情形也会发生在视图上,在创建之初,视图可能时完好的,但如果视图所基于的明细表的定义发生了变化,那么视图将失败。
oracle始终会自动重新编译无效的pl/sql对象和视图,但这不一定能够成功,orace建议执行手动修改,但并非一定要这样做。
如果编程人员编写的对象存在错误,那么对象在创建之初就存在错误,或者对象可能在创建一段时间之后变得无效。
dba_object视图(以及派生视图all_object,use_object)包含status列,理想状态下,它始终为valid。要识别数据库中所有无效对象,用户system的身份运行以下查询:
----------查询无效对象
select owner,object_name,object_type from dba_object where status='INVALID';
如果此查询列出了任何对象,那么,首先提出的问题时对象是否曾经有效过。相应的对象可能从不起作用,也不是必需的,此时,最恰当的做法时将其删除。但用户很可能无从判断对象是否有效,那么,首先采取的合理
步骤是尝试编译它。第一次访问无效对象时,oracle将尝试对其进行自动编译,但如果编译失败,则用户将受到错误消息。很明显,dba最好首先对其进行编译,如果存在错误,就可以在用户发现之前试着对其进行修复。即使在访问时对象真正执行了编译,执行编译期间也可能发生延迟。如果dba预先执行操作,避免了延迟,则性能将更加理想。
----------要修复无效对象,尝试对其进行编译。语法如下
1 alter object_type(对象类型) object_name(对象名称) compile;
例如,下面语句
alter procedure hr.add_reg compile;
将尝试编译hr模式中的add_reg过程,而下面语句
alter view rname compile;
将编译当前模式中的rname视图。如果编译成功,则问题将不复存在。如果失败,则需要弄清楚原因。
如果无法编译某个过程,则使用sql*plus命令show errors查看原因,但是视图不支持show errors.
通常,在确定编译错误的原因之初,应该使用dba_dependencies视图,desc dba_dependencies(依赖,依靠)
对于用owner和name标识的每个对象,其所依赖的每个对象将对应一行。例如,如果视图从十几个表中检索列,那么相应的列将分别在referenced_name(涉及,提及,参考,参照)中列出。如果视图无法编译,那么合理的做法是查看这些表。
-------重新编译多个无效对象
我们可能会遇到需要重新编译数百个或数千个无效对象的情况。通常,重新编译操作在应用程序升级之后进行,或者在应用补丁之后运行。我们不必单独重新编译这些无效对象,而是可以时用补充的实用程序脚本。
(1)在unix系统中可以运行下面的命令
sql>@?/rdbms/admin/utlrp
(2)在windows系统中则使用下面的命令
sql>@?\rdbms\admin\utlrp
这个脚本(应在以sysdba身份进行连接时运行)会试图编译所有无效的对象。如果在运行之后仍然存在无效的对象,那么可以认定有一些问题应当单独解决。

---------------------------------------------------不可用索引----------------------------------------------------------------------

索引由按照顺序排列的索引键值组成,其中每个索引键值都具有相关联的rowid。rowid是索引键引用的行的位置的物理指针。如果某个表的rowid发生变化,那么将索引标记为不可用。
索引变得不可用有多种原因,
最常见的原因可能是使用alter table.....move命令移动了表。表的移动操作会改变所有行的物理位置放置,因此索引条目会被指向错误的位置。oracle会发现这个错误,从而不允许使用该所索引。
在旧版本的oracle数据库中,因为会话会返回错误消息,所以用户容易检测到不可用的索引。执行sql语句时,如果会话视图使用不可用的索引,那么会立即返回一条错误消息,同时语句执行失败。
10g版本及更新版本的oracle数据库改变了这种方式。如果某条sql语句视图使用不可用的索引,那么这条语句会重新使用不需要该索引的执行计划。
这样,sql语句的执行总是会成功,不过代价可能是性能显著降低。
上述行为由实例参数skip_unusable_indexes控制,该参数默认设置为ture。对于索引有必要实施约束的情况则是一个例外:如果主键列上的索引变得不可用,那么会对dml命令锁定指定的表。
如果希望数据库实现旧版本中不可用索引导致返回错误消息的功能,那么可以执行命令alter system set skip_unusable_index=false;
------为了检测变得不可用的索引,需要查询dba_indexes视图:
sql>select owner,index_name from dba_indexes where status='UNUSALE';
如果rowid指针不再正确,那么将索引标记为不可用。
------为了修复不可用的索引
就必须使用alter index .... rebuild命令重新创建该索引。
执行这个命令会扫描指定的表,同时为每个索引键生成一个具有正确rowid指针的新索引。生成新的索引后,将会删除原有的不可用索引。
在重新生成索引的过程中,需要其他的存储空间;要作出预先规划,确保具有可用的空间。

rebuid命令的语法具有多种选项,其中较为重要的选项是tablespace,online以及nologging。
(1)在默认情况下,索引在其当前的表空间内重建,不过如果使用tablespace关键字指定了某个表空间,那么重建会移至这个表空间内进行。
(2)同样在默认情况下,重建过程会对dml命令锁定指定的表,不过使用online关键字可以避免这种状况。
(3)nologging关键字则指示oracle不为索引重建操作生成重做,这样能够更快速地完成重建,不过也意味着应当立即对包含指定索引的表空间进行备份。在备份表空间之前,因为需要使用还原和恢复,所以无法修复遭受介质损害的索引。

重建索引也可以是数据库正常维护中的一部分工作。随着时间的推移,尤其时在执行许多影响行键值的删除或更新操作的情况下,索引往往会变得不可用。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值