zoukankan      html  css  js  c++  java
  • truncate删除一个分区,测试全局索引是否失效

    目的,有一个清理数据的需求,需要删除历史的一个分区所有记录信息,但是存在主键global索引,如何更好的维护。

    如下测试流程一 提前创建好一个已时间created 字段作为分区键的范围分区表

    SQL> select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,HIGH_VALUE,TABLESPACE_NAME from dba_tab_partitions where TABLE_OWNER='TEST' and TABLE_NAME='A';TABLE_OWNER TABLE_NAME PARTITION_NAME HIGH_VALU
    --------------------------------------------------------------------------------

    TEST A PART_T01 TO_DATE(
    ' 2013-08-24 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST A SYS_P61 TO_DATE(' 2013-08-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA TEST A SYS_P62 TO_DATE(' 2019-05-12 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA 如下分区,是需要删除的,查询数据量 SQL> select count(*) from a partition(PART_T01); COUNT(*) ---------- 73384
    测试表存在主键约束
    SQL> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,STATUS from dba_constraints where owner='TEST' and TABLE_NAME='A'; OWNER CONSTRAINT_NAME C TABLE_NAME STATUS ------------------------------ - ------------------------------ -------- TEST PK_A_CC P A ENABLED SQL> select INDEX_NAME,TABLE_OWNER,TABLE_NAME,COLUMN_NAME from dba_ind_columns where table_owner='TEST' and table_name='A'; INDEX_NAME TABLE_OWNER TABLE_NAME COLUMN_NAME -------------------------------------------------------------------------------- PK_A_CC TEST A OBJECT_ID SQL> select INDEX_NAME,TABLE_OWNER,TABLE_NAME,status from dba_indexes where table_owner='TEST' and table_name='A'; INDEX_NAME TABLE_OWNER TABLE_NAME STATUS ------------------------------ -------------------------------- -------------------------------- -------- PK_A_CC TEST A VALID
    --如下,直接删除指定分区 alter table a truncate partition PART_T01; --主键global 全局索引失效 SQL> select INDEX_NAME,TABLE_OWNER,TABLE_NAME,status from dba_indexes where table_owner='TEST' and table_name='A'; INDEX_NAME TABLE_OWNER TABLE_NAME STATUS ------------------------------------------------------------------------------------------- PK_A_CC TEST A UNUSABLE 查询数据 SQL> select count(*) from a partition(PART_T01); COUNT(*) ---------- 0 SQL> select count(*) from a partition(SYS_P62); COUNT(*) ---------- 5 --恢复测试数据,再次测试,上述直接操作导致索引失效,不可取 insert into a select * from b where CREATED<TO_DATE('2013-08-24 00:00:00', 'YYYY-MM-DD HH24:MI:SS') and object_id>24056 * ERROR at line 1: ORA-01502: index 'TEST.PK_A_CC' or partition of such index is in unusable state SQL> alter index PK_A_CC rebuild; SQL> select INDEX_NAME,TABLE_OWNER,TABLE_NAME,status from dba_indexes where table_owner='TEST' and table_name='A'; INDEX_NAME TABLE_OWNER TABLE_NAME STATUS ------------------------------------------------------------------------------------------- PK_A_CC TEST A VALID insert into a select * from b where CREATED<TO_DATE('2013-08-24 00:00:00', 'YYYY-MM-DD HH24:MI:SS') and object_id>24056 commit;


    ************直接删除分区,可以删除数据,但是global索引会失效,实际工作不可取,另一种方式update global indexes,
    alter table a truncate partition PART_T01 update global indexes;
    但是这种模式,会申请什么样的锁资源,是否影响应用?******************************************************

    测试,update global indexes 资源申请锁资源!!!


    思路:1.查询再删除分区的一条记录
    2.进行删除操作;
    3.观察申请的对象tm锁资源
    4.上述操作回退,删除其它分区的一条记录;
    5.再次进行删除操作;
    6.总结
    1.查询再删除分区的一条记录
    select min(object_id) from a where CREATED<TO_DATE('2013-08-24 00:00:00', 'YYYY-MM-DD HH24:MI:SS') ; 24057 
     2.进行删除操作;
     session 1 delete a where object_id=24057; SQL> select sid from v$mystat where rownum=1; SID ---------- 312
    session 2 
    SQL> select sid from v$mystat where rownum=1;
          SID
    ----------
           332
    alter table a truncate partition PART_T01 update global indexes;
    ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
    SQL> alter session set ddl_lock_timeout=600;
    alter table a truncate partition PART_T01 update global indexes;
    
      3.观察申请的对象tm锁资源
     SQL> select type,sid,id1,id2,lmode,request,ctime from v$Lock where sid in(312,332); 
    TY SID ID1 ID2 LMODE REQUEST CTIME
    -- ---------- ---------- ---------- ---------- ---------- ----------
    AE
    332 100 0 4 0 142
    AE
    312 100 0 4 0 1283
    TM
    332 89807 0 3 0 19
    TM
    332 89808 0 0 6 19
    TM
    312 89807 0 3 0 151
    TM
    312 89808 0 3 0 151
    TX
    312 262156 8718 6 0 151
    7 rows selected.
    SQL
    > select owner,object_id,object_type from dba_objects where object_id in(89807,89808);
    OWNER OBJECT_ID OBJECT_TYPE
    ------------------------------ ---------- -------------------
    TEST
    89808 TABLE PARTITION
    TEST
    89807 TABLE
    dml 操作 申请 表对象TM3,表所在的分区TM3
    truncate 表global 维护索引操作,申请 表对象TM3号锁,分区对象TM6号锁
       4.上述操作回退,删除其它分区的一条记录;
     SQL> roll; 对其它分区的数据修改,观察此truncate 及全局维护索引是否有效 

    select min(object_id) from a where CREATED>TO_DATE('2013-08-24 00:00:00', 'YYYY-MM-DD HH24:MI:SS') ;

    2
    delete a
    where object_id=2;
        5.再次进行删除操作
     alter table a truncate partition PART_T01 update global indexes; Table truncated.
          6.总结  
    删除分区操作,使用如下方式,可以自动维护索引,保障索引是有效的;
    会申请删除分区的tm6,也就是说删除的分区字段将无法被dml操作数据;其它分区不受影响
    alter table a truncate partition PART_T01 update global indexes;
    

     

    -------------------------
  • 相关阅读:
    万网免费主机wordpress快速建站教程-域名绑定及备案
    java小算法—大衍数列
    Core Data使用之一(Swift): 保存
    Swift 添加到TableView实现动画效果
    Swift 动态创建提示框
    Swift分割字符串
    Swift去除两边的特定字符(空格或其它)
    windows 属性
    String 输出{}
    c# 正则表达式的用户
  • 原文地址:https://www.cnblogs.com/lvcha001/p/11930072.html
Copyright © 2011-2022 走看看