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; 

 

 

-------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM