遇到这种问题一般分2种情况:
1.解决此类问题,业务允许重启数据库。
2. 在任何情况下解决问题,不准重启数据库。
方法一、
我在解决问题时,问了业务,最好不要重启数据库。所以就沿用dave的clean方法。
原文:http://blog.csdn.net/tianlesoftware/article/details/6538928
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;
/
或者:
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;
但是我今天早上来的时候,已经执行了一个通宵,还是没有反应,因为数据量有点大。总共70亿数据。
预估要执行2天,还不一定有把握。
方法二、
(我用重启方法,解决问题,重启耽误的时候只有2分钟。)
1.先查mv_index, 有一个sys_join_xxxxx的表, 先drop table sys_join_xxxx;
2.shutdown immedate (关闭之前,做好参数备份)
3.startup
4.打开数据库,发现已经好了一个表,(总共4个分区表)
5.再次重启,(有几个表,就重启几次。有点奇葩,估计是我还没有弄懂,但是问题确实是这样解决的)
6.重建索引
CREATE index idx_xx_phone on xx (phone) LOCAL PCTFREE 0 NOLOGGING UNUSABLE;
7.重建分区索引
DECLARE
v_partition_name VARCHAR2(100);
CURSOR v_cur IS SELECT partition_name FROM user_tab_partitions WHERE table_name =xxxx;
BEGIN
OPEN v_cur;
LOOP
FETCH v_cur INTO v_partition_name;
EXIT WHEN v_cur%NOTFOUND;
--EXECUTE IMMEDIATE 'ALTER INDEX IND_xx_PHONE REBUILD SUBPARTITION '||v_partition_name;
EXECUTE IMMEDIATE 'ALTER INDEX IDX_xxxx_PHONE REBUILD PARTITION '||v_partition_name;
END LOOP;
CLOSE v_cur;
END;
8.可以正常使用索引了。