1. 程式人生 > >oracle資料量650G的表(有分割槽)資料刪除方案(分割槽交換技術)

oracle資料量650G的表(有分割槽)資料刪除方案(分割槽交換技術)

背景:650G的流程已辦記錄表太大,用delete刪除的話肯定是刪不動的,然後因為這個大表肯定是建了分割槽的,所以打算使用分割槽交換技術。

具體SQL如下:

------------------執行指令碼之前需要用資料泵把BPMS_RU_DONE_TASK匯出來------------------
------------------執行指令碼過程中使用者無法使用上報流程,查詢流程跟蹤------------------
------------------重要:SQL要一條條執行,千萬不要copy到命令視窗一下執行------------------

--先要把表rename的目的相對於把表離線,如果是線上的表很多操作是無法做的
drop table BPMS_RU_DONE_TASK_TEMP;
--如果rename執行失敗,則不要往下執行
rename  BPMS_RU_DONE_TASK to BPMS_RU_DONE_TASK_TEMP;

--刪除索引的原因是索引也是佔空間的,如果表的資料清理了,索引會產生很多碎片
drop index IND_BRDT_ACTIVITY_INS_ID3;
drop index IND_BRDT_CUR_NODE_INS_ID3;
drop index IND_BRDT_MAIN_PROCESS_INS_ID3;
drop index IND_BRDT_TRANS_ACTOR_ID3;
alter table BPMS_RU_DONE_TASK_TEMP drop constraint PK_BPMS_RU_DONE_TASK3;
drop index IND_PK_BPMS_RU_DONE_TASK3;

--準備使用分割槽交換技術
create table BK0403BPMS_RU_DONE_TASK
(
  done_task_id        VARCHAR2(40) not null,
  main_process_id     VARCHAR2(40),
  cur_process_id      VARCHAR2(40),
  cur_node_id         VARCHAR2(40),
  cur_node_name       VARCHAR2(60),
  main_process_ins_id VARCHAR2(40),
  cur_process_ins_id  VARCHAR2(40),
  cur_node_ins_id     VARCHAR2(40),
  activity_ins_id     VARCHAR2(40),
  status              NUMBER(2),
  trans_actor_id      VARCHAR2(40),
  actor_name          VARCHAR2(40),
  read_flag           NUMBER(1),
  back_flag           NUMBER(2),
  expiration          TIMESTAMP(6),
  urge_time           TIMESTAMP(6),
  urge_interval       NUMBER(20),
  urge_flag           NUMBER(1),
  note                VARCHAR2(4000),
  note_type           NUMBER(2),
  create_time         TIMESTAMP(6),
  version             NUMBER(20),
  task_complete_type  NUMBER(2) default -1,
  revoke_back_flag    NUMBER(1) default 1,
  modify_date         TIMESTAMP(6)
);

--要使用並行,BK0403BPMS_RU_DONE_TASK這個表裡面最初的記錄是需要保留的資料
--下面的業務邏輯需要相應的開發人員確認
alter table BK0403BPMS_RU_DONE_TASK nologging;

alter session enable parallel dml;
insert /*+ append parallel(16)*/ into BK0403BPMS_RU_DONE_TASK
  (done_task_id,
   main_process_id,
   cur_process_id,
   cur_node_id,
   cur_node_name,
   main_process_ins_id,
   cur_process_ins_id,
   cur_node_ins_id,
   activity_ins_id,
   status,
   trans_actor_id,
   actor_name,
   read_flag,
   back_flag,
   expiration,
   urge_time,
   urge_interval,
   urge_flag,
   note,
   note_type,
   create_time,
   version,
   task_complete_type,
   revoke_back_flag)
  select /*+ parallel(T,16) */
         done_task_id,
         main_process_id,
         cur_process_id,
         cur_node_id,
         cur_node_name,
         main_process_ins_id,
         cur_process_ins_id,
         cur_node_ins_id,
         activity_ins_id,
         status,
         trans_actor_id,
         actor_name,
         read_flag,
         back_flag,
         expiration,
         urge_time,
         urge_interval,
         urge_flag,
         note,
         note_type,
         create_time,
         version,
         task_complete_type,
         revoke_back_flag
    FROM BPMS_RU_DONE_TASK_TEMP T
   WHERE T.MAIN_PROCESS_ID = 'oneAssetProcess'
     AND T.STATUS = 1;
commit;

alter session disable parallel dml;
alter table BK0403BPMS_RU_DONE_TASK logging;
     
--進行分割槽交換
alter table BPMS_RU_DONE_TASK_TEMP exchange partition P_ONEASSETPROCESS with table BK0403BPMS_RU_DONE_TASK;

--使用並行建索引
create unique index INDU_BPMS_RU_DONE_TASK4 on BPMS_RU_DONE_TASK_TEMP (DONE_TASK_ID)  Nologging parallel 16;
alter table BPMS_RU_DONE_TASK_TEMP add constraint pk_BPMS_RU_DONE_TASK4 primary key (DONE_TASK_ID);

create index IND_BRDT_ACTIVITY_INS_ID4 on BPMS_RU_DONE_TASK_TEMP (ACTIVITY_INS_ID) Nologging parallel 16;
create index IND_BRDT_CUR_NODE_INS_ID4 on BPMS_RU_DONE_TASK_TEMP (CUR_NODE_INS_ID) Nologging parallel 16;
create index IND_BRDT_MAIN_PROCESS_INS_ID4 on BPMS_RU_DONE_TASK_TEMP (MAIN_PROCESS_INS_ID) Nologging parallel 16;
create index IND_BRDT_TRANS_ACTOR_ID4 on BPMS_RU_DONE_TASK_TEMP (TRANS_ACTOR_ID) Nologging parallel 16;

--一定要關閉索引的並行,要不然,資料庫明天一定會hang住
alter index INDU_BPMS_RU_DONE_TASK4 noparallel;
alter index IND_BRDT_ACTIVITY_INS_ID4 noparallel;
alter index IND_BRDT_CUR_NODE_INS_ID4 noparallel;
alter index IND_BRDT_MAIN_PROCESS_INS_ID4 noparallel;
alter index IND_BRDT_TRANS_ACTOR_ID4 noparallel;

alter table BPMS_RU_DONE_TASK_TEMP enable row movement;

--收集統計資訊的命令要在命令視窗執行
exec dbms_stats.gather_table_stats(user,'BPMS_RU_DONE_TASK_TEMP',cascade => true,degree => 32,no_invalidate=>FALSE,estimate_percent=> 80);

rename  BPMS_RU_DONE_TASK_TEMP to BPMS_RU_DONE_TASK;

--完成指令碼之後需要做驗證
1.下發和回退一個流程是否能成功。

2.檢查表和索引的並行度,如果沒有資料則是正常的,如果有資料則導回來
select s.table_name,s.degree from user_tables s where s.degree >1;

3.把各分割槽的資料導回來
select s.segment_name,s.partition_name,s.bytes/1024/1024/1024 from user_segments s
 where s.segment_name='BPMS_RU_DONE_TASK';