预计阅读时间:16分钟

《程序媛记一次在线创建索引被kill案例及应对措施》介绍的是,执行create index ... online的进程被kill,和相关可引起问题的场景,以及相应的解决方案,

对于这类问题,解决的主要方法有:

针对上图几种方法,方法一使用存储过程dbms_repair.online_index_clean进行清理,这种方式不仅可以清理所有处于online built的索引,还可以指定具体的object_id。清理所有在线索引的语法:declare

isClean boolean;

begin

isClean := FALSE;

while isClean=FALSE loop

isClean := dbms_repair.online_index_clean(dbms_repair.all_index_id,

dbms_repair.lock_wait);

dbms_lock.sleep(2);

end loop;

exception

when others then

RAISE;

end;

/

指定具体object_id:declare

a boolean;

begin

a := dbms_repair.online_index_clean(1760,dbms_repair.lock_wait);

end;

/但该方法具有版本限制,根据官方mos资料,在10.2及以上版本中均可以使用该存储过程,而针对10.2之前的版本,9.2.0.7和10.1.0.4可通过打上bug3805539的patch后方可使用dbms_repair包。(具体参见mos文档:Bug 3805539 - Add DBMS_REPAIR.ONLINE_INDEX_CLEAN to manually clean up failed ONLINE builds (Doc ID 3805539.8))。

方法二使用ORADEBUG唤醒SMON进程进行清理主要步骤为:首先使用sys用户登录数据库,根据以下sql查出smon的pid:select pid,spid

from v$process p,v$bgprocess b

where b.paddr=p.addr and name='SMON';

然后进行:

ORADEBUG WAKEUP pid

-- pid为上条sql查出的pid值

方法三重启数据库实例由SMON进程清理,需要安排停机时间,停应用然后重启数据库,此时相关表上没有了DML操作,SMON进程会完成自动清理。方法四因需要手工修改数据库的内部数据字典,风险较大,不推荐在生产系统中使用,容易造成其他不可预见的问题。

除了上面的分享,一位好友,也分享了关于这问题,他所碰见的案例,

现象:

oracle 10.2.0.5中create index online的session被强行结束掉。

解决:

找到那个表上active的事务的session,kill之,再重新跑如下匿名块:DECLARE

isClean BOOLEAN;

BEGIN

isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN();

END;

/

之后,dba_objects和dba_indexes没有该索引,dba_objects中where object_name like 'SYS_JOURNAL%'也返回零行。这一点从《一张频繁DML的大表,如何正确地创建索引?》,10046的trace中可以看见,有对这些对象delete、drop的操作。

注意:

1. Sys_journal_xxxxx 中的xxxxx是该index的object_id。

2. 如上匿名块需要在那个表没有活动事务的情况下才能真正的运行成功,注意说的是真正的运行成功。真正的运行成功的标记是:

dba_objects和dba_indexes没有该索引。

dba_objects中where object_name like 'SYS_JOURNAL%'也返回零行。

但实际中,可能碰见到的情况是:当该表上有活动事务时,执行如上匿名块,执行了5分钟之后,报'PL/SQL procedure successfully completed.',但是 dba_objects和dba_indexes依然有该索引,dba_objects中where object_name like 'SYS_JOURNAL%'也返回有这一行。而且,该索引 drop 也drop不掉,rebuild也rebuild不掉。

MOS上,也有两篇文章,和这个主题相关,1. How to Cleanup and Rebuild an Interrupted Online Index Rebuild - ORA-8104 , ORA-8106 (文档 ID 272735.1)。

2. How To Find Out Temporary Table Sys_journal_xxxxx Is Created By Rebuilding Which Index (文档 ID 1324941.1)。

我将这两篇文章,copy如下,方便朋友们,结合着来看,充分理解这些的问题,注意:文章仅限于学习!

1. How to Cleanup and Rebuild an Interrupted Online Index Rebuild - ORA-8104 , ORA-8106 (Doc ID 272735.1)

Goal

Sometimes an online rebuild of an index reports an ORA-8104.  There can be many reasons for that.

For instance in a highly active database with many transactions the likelyhood of uncommitted transactions on a table is high. So if such a table needs to rebuild an index we may see this error

due to uncommitted transactions. In other cases we may see a dead process with an uncommitted transaction holding a lock on the table. This also prevents us from rebuilding the index. This is

all by design of the online rebuild functionality. However, we can't leave a database in this state forever so SMON has been designed to cleanup these cases.

A process could end up dead if it has been killed from the OS with the command kill -9.

If the process was killed while doing an:

ALTER INDEX REBUILD ONLINE;

then the index could end up in a state where it needs clearing up.

One would think a drop of the index would solve the problem. However,

that will only return an error:ORA-8104 'This index object %s is being online built or rebuilt.'

Solution

The solution is to use the ONLINE_INDEX_CLEAN procedure in the

DBMS_REPAIR package (see: PL/SQL Packages and Types Reference, 10.2)

If the index is IOT then go to : Doc ID 427626.1: ALTER TABLE MOVE ONLINE Cancelled - How to Cope if the Table is an IOT

To fix the problem:

==============

SMON will eventually cleanup the locked index so no actions are actually needed. However, letting SMON do the cleanup can be a bit of 'hit and miss' as SMON will try to cleanup every 60 minutes and if it cannot get a lock on the object with NOWAIT it will just try again later. In a highly active database with many transactions this can cause the rebuild to take a long time as SMON won't get the lock with NOWAIT. Other cases like uncommitted transactions

against the table will also result in SMON not rebuilding the index.

As long as the index is not rebuild all access to the index will result in ORA-8104 or ORA-8106.

So to solve this situation a manual cleanup can be done using the new function DBMS_REPAIR.ONLINE_INDEX_CLEAN()SQL> conn / as sysdba

SQL> DECLARE

isClean BOOLEAN;

BEGIN

isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN();

END;

/

2. How To Find Out Temporary Table Sys_journal_xxxxx Is Created By Rebuilding Which Index (Doc ID 1324941.1)

Goal

How to find out the temporary table SYS_JOURNAL_XXXXX which is created when rebuilding an index.

Solution

Create an index to be rebuilt online.Note:

The index rebuild should take enough time for the monitoring queries to return actual results.

CREATE TABLE 'ORACLE'.'ORDERS'

( 'ORDER_ID' NUMBER(12,0),

'ORDER_DATE' DATE

);

CREATE INDEX 'ORACLE'.'ORDERS_IND1' ON 'ORACLE'.'ORDERS' ('ORDER_ID');

begin

for idx in 1 .. 1000000 loop

insert into oracle.orders values(idx,sysdate);

commit;

end loop;

end;

/

alter index oracle.orders_ind1 rebuild online;

Monitor the index rebuilt from a different session as SYSDBA:

NOTE:

If required for this example, you can just re-execute the 'alter index rebuild online;'

for any of the below queries that need to be executed during the index rebuild.

--  For formatting the output

column owner format a10

column object_name format a20

column object_id format 9999999999

column temp_table_name format a20

--  Find all the indexes that are in the REBUILD ONLINE mode:

select obj# from sys.ind$ where bitand(flags, 512) = 512;

OBJ#

----------

90003

select OWNER,OBJECT_NAME,OBJECT_ID from dba_objects

where object_id =

(select obj# from sys.ind$ where bitand(flags, 512) = 512);

OWNER      OBJECT_NAME            OBJECT_ID

---------- -------------------- -----------

ORACLE     ORDERS_IND1                90003

select OWNER,OBJECT_NAME,OBJECT_ID from dba_objects where object_name like

'SYS_JOURNAL%';

OWNER      OBJECT_NAME            OBJECT_ID

---------- -------------------- -----------

ORACLE     SYS_JOURNAL_90003          90005

In this example you see:

INDEX 'ORACLE'.'ORDERS_IND1' object id is 90003.

The temp table being used to rebuild this index is named SYS_JOURNAL_90003.

So the naming rule is 'SYS_JOURNAL_'+OBJECT_ID.

You can find the relationship of objects and temp tables directly using the following query:select a.object_name, b.table_name temp_table_name

from   dba_objects a,

( select substr(object_name,13) as obj_id,

object_name as table_name

from dba_objects

where object_name like 'SYS_JOURNAL_%') b

where a.OBJECT_ID = b.obj_id;

OBJECT_NAME          TEMP_TABLE_NAME

-------------------- --------------------

ORDERS_IND1          SYS_JOURNAL_90003

通过这些文章的介绍,想必朋友们,会对索引的创建,有了新的认识,至少对于频繁DML的大表,创建索引的需求,思考一下,考虑有什么影响、风险,文章的目的,就达到了。

oracle索引online样例,在线创建索引的问题案例相关推荐

  1. 程序媛记一次在线创建索引被kill案例及应对措施

    关注我们获得更多内容 作者 | 李晴晴,云和恩墨西区技术顾问,有多年数据库服务经验,主要服务于电网.政府.银行等行业客户,擅长SQL审核.性能优化.数据库升级. 摘要 索引是 Oracle 数据库中十 ...

  2. SQL 创建索引的作用以及如何创建索引

    SQL 创建索引的作用以及如何创建索引 SQL 创建索引的作用 一.使用索引的优点: 1.通过唯一性索引(unique)可确保数据的唯一性 2.加快数据的检索速度 3.加快表之间的连接 4.减少分组和 ...

  3. oracle样例数据库,创建和准备Oracle样例数据库

    一 创建Oracle样例数据库 此处有一个Oracle创建数据库和表和插入数据的脚本: http://www.forta.com/books/0672336073/ 亦可在此下载: http://pa ...

  4. 如何在线创建索引或者重构索引

    重新创建(create)索引的主要原因是因为新的业务的发展的需要,而重组索引往往是因为索引的偏移膨胀或者是数据删除引起的稀疏状态,也就是有些人说的"碎片",这个情况下,我们就可以在 ...

  5. 怎么样在线创建索引或者重构索引

    重新创建(create)索引的主要原因是因为新的业务的发展的需要,而重组索引往往是因为索引的偏移膨胀或者是数据删除引起的稀疏状态,也就是有些人说的"碎片",这个情况下,我们就可以在 ...

  6. oracle索引大小暴增_Oracle创建索引前估算索引大小(dbms_space.create_index_cost)

    Oracle 创建索引前估算索引大小,在一个表的某个字段创建索引前估算其大小,最好的办法就是在测试库创建索引做预测.如果没有测试 Oracle 创建索引前估算索引大小 在一个表的某个字段创建索引前估算 ...

  7. SQL2K数据库开发二十二之索引操作在视图上创建索引

    1.在企业管理器中,右击要创建索引的视图,在弹出的菜单中选择"设计视图"命令进入视图设计器.         2.在视图设计器中显示了视图所包含的列,定义视图的SQL语句以及视图中 ...

  8. 什么情况创建索引?什么情况不创建索引?MySQL如何避免索引失效?

    哪些情况需要创建索引? 1.主键自动建立唯一索引: 2.频繁作为查询条件的字段: 3.查询中与其他表关联的字段,外键关系建索引: 4.排序的字段(非主键): 5.查询中统计或分组字段. tips: 单 ...

  9. kibana创建es索引_java操作es动态创建索引(按月生成),索引类型,索引别名

    第一步:判断索引是否存在: //判断索引是否已经存在String indexName = Constans.ES_INDEX_TIME+"_"+DateUtils.getDateS ...

最新文章

  1. 脑与认知科学2 脑神经电生理学下
  2. 内功重修之数据结构----数组
  3. 在RHEL 6.5上安装grid报错libcap.so.1
  4. Python 数据分析三剑客之 Matplotlib(四):线性图的绘制
  5. 草稿 前端开发 代码的编写习惯 缩进的意义 HTML的格式
  6. 【Java】Java_03第一个Java程序
  7. 【青梅快讯】快速迭代,最新版本Greenplum 6.10已发布
  8. 像中文的罗马音字体复制_罗马音大全可复制汉字下载
  9. 操作系统之进程通信:高级通信机制四大类
  10. 邓俊辉 数据结构 第二章 向量 笔记
  11. jquery与ajax实现增删改查
  12. 木瓜从林。。。。。。。。。。。。。。。。。
  13. python数字图像处理以及绘图
  14. 取模 乘法和除法运算在CPU和GPU上的效率
  15. WEB、FTP服务器的搭建
  16. 哈工大计算机网络第一章——计算机网络概述复习
  17. CPU占用率爆满,服务器遭遇挖矿如何排查
  18. incr、incrby、decr、decrby命令的作用和用法
  19. 爱之树(二叉树建树+搜索)
  20. MySQL UUID函数的详解

热门文章

  1. angular日期输入框html,html5 – Angular2:日期格式文本框ngModel不起作用
  2. html怎么根据控IE制台找错误,IE调试网页之三:控制台查看错误和状态
  3. LeetCode-----旋转数组的最小数字
  4. Chrome 插件开发与本地程序交互流程
  5. Intel 中断和异常处理 - 目录
  6. numactl:NETLINK示例源码
  7. 初识:如何实现利用C语言代码封装成可以安装的windows软件?
  8. web前端基础(13js语法基础)
  9. 心率 心律 脉率的区别
  10. python解释器安装步骤_Python 解释器