index rebuild online

SQL> select segment_name ,segment_type from user_segments where TABLESPACE_NAME='INDEX_TS';

SEGMENT_NAME
--------------------------------------------------------------------------------
SEGMENT_TYPE
------------------
EMP_IDX
INDEX

EMP_PK
INDEX

DEPT_PK
INDEX

SQL> select * from emp where empno='123';
select * from emp where empno='123'
*
ERROR at line 1:
ORA-00376: file 10 cannot be read at this time
ORA-01110: data file 10: '/u01/oradata/index_ts01.ora'

SQL> create tablespace index_ts_temp datafile '/u01/oradata/index_ts_temp01.ora' size 128m;
connect
Tablespace created.

SQL> drop tablespace index_ts INCLUDING CONTENTS;
drop tablespace index_ts INCLUDING CONTENTS
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-02429: cannot drop index used for enforcement of unique/primary key

SQL> alter index DEPT_PK rebuild tablespace index_ts_temp;
alter index DEPT_PK rebuild tablespace index_ts_temp
*
ERROR at line 1:
ORA-00376: file 10 cannot be read at this time
ORA-01110: data file 10: '/u01/oradata/index_ts01.ora'
 



因为不是在线rebuild ,所以会读取原来index 的数据

SQL> alter index DEPT_PK rebuild tablespace index_ts_temp online;

Index altered.

加上online 表示不读取原来index 的数据,直接从table 里面读取数据重新建立 index

 

 

 

 

 

一、前一篇文章的案例中提到,索引损坏了,重建索引时,直接rebuild报错,而rebuild online则可以,这主要是两者重建索引

时的扫描方式不同,rebuild用的是“INDEX FAST FULL SCAN”,rebuild online用的是“TABLE ACCESS FULL”:
SQL> explain plan for
  2  alter index ind_test_id rebuild;
 
Explained.
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Plan hash value: 187312216
 
--------------------------------------------------------------------------------------
| Id  | Operation              | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | ALTER INDEX STATEMENT  |             |   115K|   565K|    78   (2)| 00:00:10 |
|   1 |  INDEX BUILD NON UNIQUE| IND_TEST_ID |       |       |            |          |
|   2 |   SORT CREATE INDEX    |             |   115K|   565K|            |          |
|   3 |    INDEX FAST FULL SCAN| IND_TEST_ID |       |       |            |          |
--------------------------------------------------------------------------------------
 
10 rows selected.
 
SQL> explain plan for
  2  alter index ind_test_id rebuild online;
 
Explained.
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Plan hash value: 3365522411
 
--------------------------------------------------------------------------------------
| Id  | Operation              | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | ALTER INDEX STATEMENT  |             |   115K|   565K|    78   (2)| 00:00:10 |
|   1 |  INDEX BUILD NON UNIQUE| IND_TEST_ID |       |       |            |          |
|   2 |   SORT CREATE INDEX    |             |   115K|   565K|            |          |
|   3 |    TABLE ACCESS FULL   | TEST        |   115K|   565K|    78   (2)| 00:00:10 |
--------------------------------------------------------------------------------------
 
10 rows selected.


二、rebuild index online在执行期间不会阻塞DML操作,但在开始和结束阶段,需要请求模式为4的TM锁。因此,如果在rebuild index online开始前或结束时,有其它长时间的事物在运行,很有可能就造成大量的锁等待。具体可以参考:
rebuild index online的锁机制浅析
11G中有所不同:
rebuild index online的锁机制浅析(续)

这里可以通过设置10626事件,避免阻塞该表上的其它DML操作,但在rebuild index online开始、结束阶段有其它事物未完成,则会失败,报ORA-00051: timeout occurred while waiting for a resource 错误:
(以下测试在9208、10203中测试通过,在10201中等待几秒后,直接报ORA-00051,之后再想重建则报ORA-08104,处理方法见后面,因而设置该事件还需谨慎)
会话一:SQL> select max(sid) from v$mystat;
 
  MAX(SID)
----------
        82
 
SQL> delete from test_ls where id=1;
 
1 row deleted.


会话二:SQL> select max(sid) from v$mystat;
 
  MAX(SID)
----------
        70
 
SQL> alter session set events '10626 trace name context forever';
 
Session altered.
 
SQL> alter index IND_TEST_ID rebuild online;


此时会话二会话被阻塞。

会话三:SQL> delete from test_ls where id=3;
 
1 row deleted.
 
SQL> commit;
 
Commit complete.
 
SQL> select * from test_ls where id=3;
 
no rows selected


会话三的DML操作并不会被阻塞。

会话一rollback后,会话二报错:alter index IND_TEST_ID rebuild online
*
ERROR at line 1:
ORA-00051: timeout occurred while waiting for a resource


增加表的数据量,同样可以测出在rebuild online结束时,如果该表上还有其它事物未完成,则报错,如果无其它事物,索引可以重建成功,期间都不会阻塞其它DML操作。

三、rebuild onlie时,如果发生意外中断,很容易造成ORA-08104错误,之后再想rebuild、drop索引都会报错。10G之前需要等待SMON去清理,10G以后可以使用DBMS_REPAIR.ONLINE_INDEX_CLEAN进行手工清理:SQL> alter index IND_TEST_ID rebuild online;
alter index IND_TEST_ID rebuild online
*
ERROR at line 1:
ORA-08104: this index object 93996 is being online built or rebuilt
 
SQL> DECLARE
  2    RetVal BOOLEAN;
  3    OBJECT_ID BINARY_INTEGER;
  4    WAIT_FOR_LOCK BINARY_INTEGER;
  5 
  6  BEGIN
  7    OBJECT_ID := 93996;
  8    WAIT_FOR_LOCK := NULL;
  9 
 10    RetVal := SYS.DBMS_REPAIR.ONLINE_INDEX_CLEAN ();
 11    COMMIT;
 12  END;
 13  / 
 
PL/SQL procedure successfully completed.
 
SQL> alter index ind_test_id rebuild online;
 
Index altered.

你可能感兴趣的:(sql,Access)