oracle alter logging,Oracle alter index rebuild 说明

后续操作:

session 1:commit

SYS@anqing2(rac2)> commit;

Commit complete.

查看lock信息:

SYS@anqing2(rac2)> select sid,type,id1,id2,lmode,request,block from v$lock where type in('DL','TM','TX');

SID TYID1ID2LMODEREQUESTBLOCK

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

147 DL533660302

147 DL533660302

147 TM533660242

147 TM533860402

143 TM533660301

143 TX1048602287602

147 TX983080291602

这里还有两个锁,147是我们的rebuild online。143是我们之前session 3的update DML。

这里要注意的是,如果我们的session 3不commit,那么我们的rebuild online还是不会结束。 因为rebuild online在开始和结束的时候需要申请去拿TM 4的lock。 现在rebuild online的被我们的session 3阻止了。 在开始是被session 1阻止了。

我们在session 3提交一下,在查看lock:

SYS@anqing2(rac2)> commit;

Commit complete.

SYS@anqing2(rac2)> select sid,type,id1,id2,lmode,request,block from v$lock where type in('DL','TM','TX');

no rows selected

rebuild结束

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

Index altered.

Elapsed: 00:16:44.86

由此可见rebuild online是个需要谨慎使用的命令。

3.3.2场景2

在前面说过, kill掉正在rebuild online的session。 可能会导致在下次rebuild index或者drop,analyze的时候报ORA-08104的错误。 因为在异常终止online rebuild操作的时候,没来得及清理相应的临时段和标志位,系统认为online rebuild操作还在进行造成的。

在这里我们就模拟一下这个操作。

在rebuild online的时候,按下ctrl + c结束:

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

alter index idx_rbt_id rebuild online

*

ERROR at line 1:

ORA-01013: user requested cancel of current operation

Elapsed: 00:00:01.78

SYS@anqing2(rac2)> exec dbms_stats.gather_table_stats('SYS','RB_TEST');

PL/SQL procedure successfully completed.

Elapsed: 00:00:07.02

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

Index altered.

Elapsed: 00:00:09.38

没有报错。把数据量弄大一点。在试试

SYS@anqing2(rac2)> insert into rb_test select * from rb_test;

1000000 rows created.

Elapsed: 00:00:23.68

SYS@anqing2(rac2)> commit;

Commit complete.

Elapsed: 00:00:00.08

SYS@anqing2(rac2)> insert into rb_test select * from rb_test;

2000000 rows created.

Elapsed: 00:01:54.36

SYS@anqing2(rac2)> commit;

Commit complete.

Elapsed: 00:00:00.00

用kill session的方法试试:

SYS@anqing2(rac2)> alter system kill session '147,31436';

System altered.

Elapsed: 00:00:01.01

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

alter index idx_rbt_id rebuild online

*

ERROR at line 1:

ORA-00028: your session has been killed

Elapsed: 00:00:10.89

还是没有报错:

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

Index altered.

Elapsed: 00:00:51.65

比较顽强啊。有点小崩溃。再来:

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

启动rebuild online之后,直接把ssh强行关闭。

在次ssh过去,尝试rebuild online:

SYS@anqing2(rac2)> alter index idx_rbt_id rebuild online;

alter index idx_rbt_id rebuild online

*

ERROR at line 1:

ORA-08104: this index object53367is being online built or rebuilt

终于报错了。 不容易啊。 不过这个测试也说明了,在rebuild online期间不能强行关闭ssh。如果在期间断网的话,估计效果相当。

查看Flag:

SYS@anqing2(rac2)> select obj#,flags from ind$ where obj#=53367;

OBJ#FLAGS

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

53367514

根据NiGoo blog上的说明,可以通过ind$的flags查看是什么类型的标志。

sql.bsq是个总的说明,在dcore.bsq里找到了ind$的创建SQL:

/* mutable flags: anything permanent should go into property */

/* unusable (dls) : 0×01 */

/* analyzed : 0×02 */

/* no logging : 0×04 */

/* index is currently being built : 0×08 */

/* index creation was incomplete : 0×10 */

/* key compression enabled : 0×20 */

/* user-specified stats : 0×40 */

/* secondary index on IOT : 0×80 */

/* index is being online built : 0×100 */

/* index is being online rebuilt : 0×200 */

/* index is disabled : 0×400 */

/* global stats : 0×800 */

/* fake index(internal) : 0×1000 */

/* index on UROWID column(s) : 0×2000 */

/* index with large key : 0×4000 */

/* move partitioned rows in base table : 0×8000 */

/* index usage monitoring enabled : 0×10000 */

这里的0×200等是十六进制来表示的。 Flags是514, 其16进制是是202,514=0×202,表示该索引状态为index is being online rebuilt : 0×200 + analyzed : 0×02

在上面,我们说减去512. 512的16进制是200.对应的是:/* index is being online rebuilt : 0×200 */。 所以,我们在rebuild的时候,会对flags加上512.

MOS 803008.1上的说明:

SMON should cleanup the failed online index rebuild operation and so correct this. However, if the table is highly active with transactions, SMON may not be able to get the required lock and so the index will not get cleaned up. In such situations, you can manually cleanup the failed index rebuild using the DBMS_REPAIR.ONLINE_INDEX_CLEAN procedure.

To do this, if activity on the problem table can be stopped, then simply execute:

connect / as sysdba

select dbms_repar.online_index_clean() from dual;

exit

不过这个命令执行没有成功:

SYS@anqing2(rac2)> select dbms_repair.online_index_clean(53367) from dual;

select dbms_repair.online_index_clean(53367) from dual

*

ERROR at line 1:

ORA-06552: PL/SQL: Statement ignored

ORA-06553: PLS-382: expression is of wrong type

纠结中...

If activity on the table cannot be stopped,then it may be possible to resolve the problem using the following PL/SQL block:

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;

/

或者:

DECLARE

RetVal BOOLEAN;

OBJECT_ID BINARY_INTEGER;

WAIT_FOR_LOCK BINARY_INTEGER;

BEGIN

OBJECT_ID := 53367;

WAIT_FOR_LOCK := NULL;

RetVal := SYS.DBMS_REPAIR.ONLINE_INDEX_CLEAN ();

COMMIT;

END;

/

SYS@anqing2(rac2)>select obj#,flags from ind$ where obj#=53367;

OBJ#FLAGS

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

533672

在这个测试上也是相当的纠结。 之前产生了ORA-08104的错误,但是如果之后没有其他的DML来操作这张表,那么online rebuild产生的lock一段时间之后就会释放掉,然后ind$的flag也会变成2.即正常状态。

如果事务A阻止online rebuild申请TM 4锁,那么之前所有的事务都会挂住,当事务A commit之后,相关的锁会释放,索引也会变成正常状态。

在执行clean命令的时候,可能会遇到:

ORA-00054: resource busy and acquire with NOWAIT specified

多执行几次就ok了。 应该也是和这个锁有关。

可能还是环境模拟的有问题。 这个测试总感觉怪怪的。 纠结啊。0b1331709591d260c1c78e86d0c51c18.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值