数据文件offline后unusable索引造成的问题

最近在做一个oracle入库速度测试时,想到将最近一个小时的索引放到内存中(表是按小时分区)是不是会提升入库的速度,索引的维护对io是一个不小的开销;
不过这个方案如果要使用的话数据库必须是 oracle 12c,因为在当前小时结束后,需要将相关索引移出内存,让下一个小时的索引留在内存,这样内存的使用情况基本是一个定量;
而在移动的过程中不能对业务有影响,这样需要用到12c的新功能,在线移动数据文件。

测试的结果是入库速度有很明显的提升,入库速度是之前的几倍,但这个不是本文的重点;本文的重点是在测试的过程中发现的一个小问题,不确定是不是bug(oracle 11.2.0.4也有这个问题),以下是过程。

1.准备工作

创建表空间、用户等

  1. create tablespace dasong datafile '/oradata/oracle/dasong.dbf' size 100m;
    create tablespace dasong_idx2 datafile '/oradata/oracle/dasong_idx2.dbf' size 100m;
    create tablespace dasong_idx3 datafile '/oradata/oracle/dasong_idx3.dbf' size 100m;

    create user dasong identified by dasong
    default tablespace dasong
    temporary tablespace temp;

    grant dba to dasong;
    grant create session to dasong;
    grant resource to dasong;
    grant debug connect session to dasong;
    grant debug any procedure to dasong;
    grant select_catalog_role to dasong;

2.创建表、索引,并插入数据

  1. create table t_idx_offline_test
    (
      c1 number,
      c2 number,
      c3 number
    )
    partition by range(c1) interval(1000)
    (
      partition part_0 values less than(0)
    ) tablespace dasong;

    create index idx_test_c2 on t_idx_offline_test(c2) tablespace dasong_idx2 local;
    create index idx_test_c3 on t_idx_offline_test(c3) tablespace dasong_idx3 local;

    insert into t_idx_offline_test
    select rownum, rownum+1, rownum+2 from dual connect by rownum<10000;
    commit;

3.offline数据文件

  1. alter database datafile '/oradata/oracle/dasong_idx2.dbf' offline for drop;

数据文件offline不会影响索引分区的状态,分区相关的段也是存在的,索引并没有察觉到相关的数据文件已离线

  1. select * from user_ind_partitions;

  1. select * from user_segments;

4.rebuild索引分区

  1. alter index idx_test_c2 rebuild partition sys_p872 tablespace dasong_idx3;

原索引所在数据文件如果不可用,则rebuild失败,因为rebuild会从原索引中读数据,暂不知道怎么样绕过

  1. SQL Error: ORA-00376: file 10 cannot be read at this time
    ORA-01110: data file 10: '/oradata/oracle/dasong_idx2.dbf'
    00376. 00000 -  "file %s cannot be read at this time"
    *Cause:    attempting to read from a file that is not readable. Most likely
               the file is offline.
    *Action:   Check the state of the file. Bring it online

先将原来索引分区unusable(SYS_P872)

  1. alter index idx_test_c2 modify partition sys_p872 unusable;

索引分区SYS_P872状态变成UNUSABLE

分区SYS_P872对应的段消失,多出了一个10.130(这个是原来的SYS_P872对应的段)

现在rebuild索引分区 到 其它表空间(dasong_idx3),可以成功

  1. alter index idx_test_c2 rebuild partition sys_p872 tablespace dasong_idx3;

rebuild成功可以看到索引分区状态为usable,tablespace是dasong_idx3

对应的新段在dasong_idx3表空间中,原来的10.130并不没有消失(即使将数据文件online,重启数据库,10.130也不会消失)

5.temporary段处理

所有使用索引unusable的操作都会使索引原来的分区段变成temporary(unusable索引、删除索引、exchange索引分区对应的数据分区 等);
除非删除表空间,其它常规手段都不会删除temporary段(其实此时索引对应的段应该是已经没有了,或是访问不到的,因为数据文件不可用,此时看到的只是元数据)

  1. alter index idx_test_c2 unusable;
  2. alter index idx_test_c2 modify default attributes tablespace dasong_idx3;

  1. drop tablespace dasong_idx2 including contents and datafiles;

索引idx_test_c2有一个分区在dasong_idx3分区中,所以删除表空间会报错(rebuild之前应该能删除掉表空间,但是including也会把索引删除,这不是我想要的结果)

  1. SQL Error: ORA-14405: partitioned index contains partitions in a different tablespace
    14405. 00000 -  "partitioned index contains partitions in a different tablespace"
    *Cause:    An attempt was made to drop a tablespace which contains indexes
               whose partitions are not completely contained in this tablespace,
               and which are defined on the tables which are completely contained
               in this tablespace.
    *Action:   find indexes with partitions which span the tablespace being
               dropped and some other tablespace(s). Drop these indexes, or move
               the index partitions to a different tablespace, or find the tables
               on which the indexes are defined, and drop (or move) them.

即使 手动删除seg$内容(不确定会不会造成其它问题),user_segments中不再有相关的temporary段,此时删除表空间dasong_idx2还是会报上面的错,说明数据字典没有清理完全,还是有一部分跟dasong_idx2相关(数据库还是认为dasong_idx2有索引数据)

  1. delete from seg$ where file#=10 and type#=3;
    commit;

6.删除索引、删除表空间

最后只能先删除索引,再删除表空间,才能清理完对应的数据字典数据。

  1. drop index idx_test_c2;
    drop tablespace dasong_idx2 including contents and datafiles;

暂时没有想出其它的方法来解决这个问题,不过temporary没有清理,也不会影响索引部分分区的rebuild(先unusable,再rebuild),只是看起来比较不舒服,如果可以接受这个的话,此方案还是可以考滤的,毕竟入库速度有好几倍的提升。

时间: 2024-10-24 16:12:44

数据文件offline后unusable索引造成的问题的相关文章

[20161019]数据文件offline后恢复到那个scn

[20161019]数据文件offline后恢复到那个scn号.txt --前一天别人问的问题,如果数据文件offline时,online要恢复,一般恢复到scn是多少,是offline时的scn吗? --总不见得如果长时间offline,要应用许多归档日志吧,通过测试说明问题: 1.环境: SYS@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ----------------------------

[20161019]数据文件offline与open resetlog

[20161019]数据文件offline与open resetlog.txt --上午做了数据文件offline后恢复到那个scn号,恢复到该数据文件的LAST_CHANGE#的scn值. --如果数据文件做了offline,在以后数据库做了open resetlog后,如何online呢?如果归档存在没有问题, --但是10g开始支持跨resetlog的恢复.自己以前也做了类似的测试. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING            

20160331数据文件offline与open resetlogs2

[20160331]数据文件offline与open resetlogs3.txt --接上面的测试.链接: --关机做一个冷备份,便于重复测试.取出冷备份,重复测试: --做一些必要的清理清除归档. 1.环境: SYS@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- ----------------------

临时数据文件 offline 对于导入导出的影响

临时数据文件 offline 对于导入导出的影响 sys@ORACL> alter database tempfile 'd:\oracle\oradata\oracl\temp01.dbf' offline; 数据库已更改. sys@ORACL> ================================================tempfile offline的情况. 1 导出少量数据时,没有报错,当导出大量数据时,会报EXP-00068: 表空间 TEMP 脱机 C:\Use

[20161012]数据文件offline马上执行recover

[20161012]数据文件offline马上执行recover.txt --前几天看的1篇文章,提到数据文件offline,应该养成随手执行recover习惯.保证下一次online时,不需要恢复. --如果offline很久,忘记online了,而归档日志已经不存在,该如何跳过应用日志,online数据文件呢? --以前也做过一些测试,再重复测试看看.(注意:这样恢复存在数据丢失的风险) 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING           

[20151028]理解数据文件offline+drop.txt

[20151028]理解数据文件offline+drop.txt --前几天做删除数据文件的恢复测试,自己在理解offline drop的方式存在错误,做一个记录: The ALTER DATABASE DATAFILE <datafile name> OFFLINE DROP command, is not meant to allow you to remove a datafile. What the command really means is that you are offlin

【故障处理】DG环境主库丢失归档情况下数据文件的恢复

[故障处理]DG环境主库丢失归档情况下数据文件的恢复 1  BLOG文档结构图     2  前言部分   2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① BBED的编译 ② BBED修改文件头让其跳过归档从而可以ONLINE(重点) ③ OS命名格式转换为ASM的命名格式 ④ DG环境中备库丢失数据文件的情况下的处理过程(重点) ⑤ 数据文件OFFLINE后应立即做一次RECOVER操作 ⑥ BBED环境

数据文件、表空间offline用法及区别

对数据库的脱机包括数据文件的脱机和对表空间的脱机,表空间脱机实际就是表空间对应的所有数据文件脱机. 1.         数据文件OFFLINE 数据文件添加到表空间之后不能够被删除的,没有语法支持这么做,如果想不使用该数据文件,唯一是将数据文件设置为OFFLINE状态.执行以下步骤将数据文件设置为OFFLINE状态: 1)         如果是归档模式可以执行如下SQL设置数据文件的状态为OFFLINE: ALTER DATABASE DATAFILE 'XXXX.DBF' OFFLINE;

[20160329]bbed修复offline的数据文件.txt

[20160329]bbed修复offline的数据文件.txt --测试数据库,不小心将一个数据文件offline了,archivelog也删除了(主要磁盘空间紧张,做了一次整理). --自己测试修复看看,顺便做一个记录. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- --------