上篇文章介绍了迁移表、索引对象的操作:
http://blog.csdn.net/bisal/article/details/50804714
发现漏了一个细节,就是表、LOB对象移动后索引的状态。
1.创建测试表
CREATE TABLE tbl_able(id NUMBER PRIMARY KEY, con CLOB);
该表有一个CLOB的大对象。
SELECT * FROM user_tables WHERE table_name='TBL_ABLE';
SELECT * FROM user_indexes WHERE table_name='TBL_ABLE';
TBL_ABLE表存在于用户默认表空间TEST_TBS中。
user_indexes中保存两条TBL_ABLE的记录,一条是LOB类型的SYS_IL0000124396C00002$$,一条是主键索引SYS_C0055438,都存储于TEST_TBS表空间。
2.将表移至USERS表空间
ALTER TABLE tbl_able MOVE TABLESPACE USERS;
此时查看user_indexes,LOB对象SYS_IL0000124401C00002$$的状态仍是VALID,但主键索引SYS_C0055439的状态变为了UNUSABLE,且两者所处的表空间仍是TEST_TBS。
此时INSERT操作会提示:
ORA-01502:索引’SYS_C0055439’或这类索引的分区处于不可用状态
3.移动索引对象
ALTER INDEX SYS_C0055439 REBUILD TABLESPACE USERS;
将主键索引移至USERS表空间,且此时状态是VALID,LOB对象SYS_IL0000124401C00002$$没有改变,状态仍是VALID。
ALTER TABLE TBL_ABLE MOVE LOB(con) store as (TABLESPACE USERS);
将LOB对象SYS_IL0000124401C00002$$移至USERS表空间,此时LOB对象状态是VALID,但主键索引状态现在却是UNUSABLE了。
这里我使用了11.2.0.1和11.2.0.4两个库版本测试,发现在11.2.0.4中执行alter table move或alter table move lob时将主键索引状态置为UNUSABLE,alert日志中会有记录:
Some indexes or index [sub]partitions of table XXX.TBL_ABLE have been marked unusable
标记了索引错误,这和INSERT操作报错ORA-01502的描述不谋而合,但11.2.0.1版本的alert日志中没有任何标记。
4.让索引重新生效
ALTER INDEX SYS_C0055439 REBUILD;
重建索引,此时才能改为VALID状态。
总结:
对于对象移动表空间的操作,要关注索引等附属信息的有效性,对于LOB对象的移动,也可能会导致索引状态的失效。