zoukankan      html  css  js  c++  java
  • 解决ORA01502 state unusable错误成因

    ORA-01502 state
      
      这个错误是由于索引失效造成的,重建索引后,问题就解决了。
      
      为了搞清楚索引为什么会失效,以及如何解决,我们做个测试:
      
      首先我们创建一个普通的测试表(非分区表):
      SQL> create table t(a number);
      
      Table created.
      
      SQL> select tablespace_name from user_segments where segment_name='T';
      
      TABLESPACE_NAME
      ------------------------------
      DATA_DYNAMIC
      
      SQL>
      
      然后,我们创建一个普通索引
      
      SQL> create index idxt on t(a);
      
      Index created.
      
      SQL> insert into t values(10);
      
      1 row created.
      
      SQL> set linesize 200
      SQL> select index_name,index_type,tablespace_name,table_type,status from user_indexes where index_name='IDXT';
      
      INDEX_NAME           INDEX_TYPE         TABLESPACE_NAME        TABLE_TYPE STATUS
      ------------------------------ --------------------------- ------------------------------ ----------- --------
      IDXT              NORMAL           DATA_DYNAMIC          TABLE    VALID
      
      SQL>
      
      模拟索引是失效的情况:
      SQL> alter table t move tablespace tools
       2 /
      
      Table altered.
      
      SQL> select index_name,index_type,tablespace_name,table_type,status from user_indexes where index_name='IDXT';
      
      INDEX_NAME           INDEX_TYPE         TABLESPACE_NAME        TABLE_TYPE STATUS
      ------------------------------ --------------------------- ------------------------------ ----------- --------
      IDXT              NORMAL           DATA_DYNAMIC          TABLE    UNUSABLE
      
      SQL>
      我们看到,当使用类似 alter table xxxxxx move tablespace xxxxxxx 命令后,索引就会失效。
      
      当然,作为测试,也可以直接使用alter index idxt unusable;命令使索引失效,例如:
      SQL> alter index idxt unusable;
      
      Index altered.
      
      SQL>
      
      在这种情况下,我们向表中插入数据看看是什么情况:
      SQL> insert into t values(11);
      insert into t values(11)
      *
      ERROR at line 1:
      ORA-01502: index 'MISC.IDXT' or partition of such index is in unusable state
      
      SQL>
      我们看到,这时就出现了常见的“ORA-01502: index 'XXXXXXXX' or partition of such index is in unusable state”错误。
      
      检查一下索引状态,我们会注意到索引已经是“UNUSABLE”了。
      SQL> select index_name,index_type,tablespace_name,table_type,status from user_indexes where index_name='IDXT';
      
      INDEX_NAME           INDEX_TYPE         TABLESPACE_NAME        TABLE_TYPE STATUS
      ------------------------------ --------------------------- ------------------------------ ----------- --------
      IDXT              NORMAL           DATA_DYNAMIC          TABLE    UNUSABLE
      
      SQL>
      
      对于普通表中的不同索引(非唯一索引),我们有两种方法解决这个问题。
      
      方法一:设置 skip_unusable_indexes=true;
      SQL> alter session set skip_unusable_indexes=true;
      
      Session altered.
      
      SQL> insert into t values(11);
      
      1 row created.
      
      SQL> commit;
      
      Commit complete.
      
      SQL> select * from t;
      
           A
      ----------
           1
           2
           3
           4
           5
          10
          11
      
      7 rows selected.
      
      SQL> select index_name,index_type,tablespace_name,table_type,status from user_indexes where index_name='IDXT';
      
      INDEX_NAME           INDEX_TYPE         TABLESPACE_NAME        TABLE_TYPE STATUS
      ------------------------------ --------------------------- ------------------------------ ----------- --------
      IDXT              NORMAL           DATA_DYNAMIC          TABLE    UNUSABLE
      
      SQL>
      现在我们看到,这个索引的状态虽然还是“UNUSABLE”但是,通过设置“alter session set skip_unusable_indexes=true;”,
      
      我们已经可以访问这个表了,但是请注意,这种情况下,这个索引是不可用的,也就是说优化器在考虑是否要使用索引时是不考虑这个所以的。
      
      方法二:通过常见所以彻底解决这个问题
      
      首先,先设置 “skip_unusable_indexes=false”,也就是不跳过失效索引
      SQL> alter session set skip_unusable_indexes=false;
      
      Session altered.
      
      SQL>
      
      然后重建这个失效的索引
      SQL> alter index idxt rebuild;
      
      Index altered.
      
      SQL> select index_name,index_type,tablespace_name,table_type,status from user_indexes where index_name='IDXT';
      
      INDEX_NAME           INDEX_TYPE         TABLESPACE_NAME        TABLE_TYPE STATUS
      ------------------------------ --------------------------- ------------------------------ ----------- --------
      IDXT              NORMAL           DATA_DYNAMIC          TABLE    VALID
      
      SQL>
      我们看到重建索引后,索引的状态就正常了。
      
      现在插入数据,看看是正常:
      SQL> insert into t values(12);
      
      1 row created.
      
      SQL> commit;
      
      Commit complete.
      
      SQL>
      看来,重建索引才是解决这类问题的彻底的方法。
  • 相关阅读:
    CentOS6.5 [ERROR] /usr/libexec/mysqld: Can't create/write to file '/var/lib/mysqld/mysqld.pid' (Errcode: 2)
    linux防火墙
    Linux磁盘分区与LVM详解
    LVM分区扩展空间
    linux 分区方法(超过2T的硬盘)
    linux异常处理:selinux配置错误导致无法重启
    linux网卡配置文件
    Zabbix4.0系统clone、mass update使用
    Zabbix系统配置日志监控告警--关键字触发
    Zabbix4.0系统配置事件通知
  • 原文地址:https://www.cnblogs.com/luluping/p/1684901.html
Copyright © 2011-2022 走看看