你好,游客 登录 注册 搜索
背景:
阅读新闻

online rebulid index 异常终止遇到ORA-08104

[日期:2013-01-15] 来源:Linux社区  作者:wyzxg [字体: ]

解决一:

在10g中用dbms_repair.online_index_clean来清除创建索引的失败的遗留


DECLARE
  RetVal BOOLEAN;
  OBJECT_ID BINARY_INTEGER;
  WAIT_FOR_LOCK BINARY_INTEGER;

BEGIN
  OBJECT_ID := 67420;
--  我的数据库中非法索引的id为67420.
  WAIT_FOR_LOCK := NULL;

  RetVal := SYS.DBMS_REPAIR.ONLINE_INDEX_CLEAN ();
  COMMIT;
END;
/

注意:dbms_repair.online_index_clean这个函数一定要有返回值,否则会失败的

解决二:(这种方法没测试成功)

唤醒SMON:

WAKEUP command  :To wake up a process use

    ORADEBUG WAKEUP pid

For example to wake up SMON, first obtain the PID using

    SELECT pid FROM v$process
    WHERE addr =
    (
        SELECT paddr FROM v$bgprocess
        WHERE name = 'SMON'
    );


If the PID is 6 then send a wakeup call using

  sql > ORADEBUG WAKEUP 6

 

记录一下SMON的功能及其触发频率(9i):

 

Merging free extents or coalescing: every five minutes.

Cleaning up temporary segments: every two hours.

Updating SMON_SCN_TIME for used in time based flashback: every five minutes.

Cleaning up non existent objects in OBJ$: every 12 hours.

Cleaning up IND$ if online builder crashes: every hour.

Shrink undo segments:every 12 hours.

Transaction recovery only on startup.

Transaction rollback of dead transaction when posted by PMON, allowing the use of fast start parallel rollback if necessary.

解决方法三:

由于在做索引在线重建的时候,可能相关的表还在变化,Oracle需要记录这个索引的相关变化,因此Oracle会创建一张临时表来记录这些变化,等索引重建完成后再删除这张临时表,这张临时表的名字为SYS_JOURNAL_<INDEX的OBJECT_ID>。REBUILD ONLINE刚刚开始的时候就会去创建这张日志表,但是如果创建日志表的时候,发现这张表已经存在了,就可能会报ORA-8104,并无法继续做REBUILD ONLIE(普通的REBUILD会检查索引的FLAG标志和这张表,如果冲突,也会失败)。如果REBUILD ONLINE被中途杀掉了,那么这张表和IND$中的FLAGS不会被自动清除,必须由SMON来清除。而SMON每个小时会进行一次类似的清除工作,SMON做清除前首先要锁住日志表,如果这个索引相关的表还在变化,那么SMON可能无法锁住这张表,如果SMON锁表失败,就会放弃这次清理工作,等一个小时后再来清理。这样一来,在业务较为繁忙的生产系统上,可能SMON永远都没有机会清除这张日志表。

如果是9i的数据库就很麻烦了,如果系统smon进程无法清除,或者重启数据库也无法解决,那只有手工清除了日志表,并且修改索引的FLAGS。手工解决这个问题分为两个步骤:

1、手工删除日志表:

  首先找到这个索引的OBJECT_ID:

Select object_id from dba_objects where owner=<owner> and object_name=<index name>;

找到OBJECT_ID后,就可以知道表的名字了(SYS_JOURNAL_<OBJECT_ID>),直接DROP这张表。不过如果这张表上的DML比较频繁,DROP操作可能不会一次成功,需要不停的重试。

2、手工修改IND$:

  UPDATE IND$ SET FLAGS=FLAGS-512 WHERE OBJ#=<OBJECT_ID>;

手工清理要十分小心,一旦出错会导致数据字典错误。

解决方法四:

还有一种稳妥的办法是把应用停了,然后重启数据库,这样相关表上没有了DML操作,很快SMON就会完成自动清理。

参考文档:http://www.oraclefans.cn/forum/showtopic.jsp?rootid=14720&CPages=1


-----end----

linux
相关资讯       ORA-08104 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款