給Oracle 11g Interval分割槽進行重新命名
阿新 • • 發佈:2020-08-14
Oracle 11g 眾多新特性中,我最喜歡的就是分割槽表增強,眾所周知很多大問題“化整為零”之後就不是個問題,分割槽表就是一種非常好用的“化整為零”的手段。
還是說回正題吧,使用Interval分割槽不難,為分割槽/子分割槽的重新命名也不難,我的分割槽表大致定義如下:
1 2 3 4 5 6 7 8 |
CREATE TABLE Partition_Table
(
....
....
....
)
PARTITION BY RANGE( MSGDATE ) INTERVAL( NUMTOYMINTERVAL(1, 'MONTH' ) )
SUBPARTITION BY LIST( DAY_V )
|
分割槽和子分割槽的重新命名語法如下:
1 2 |
alter table <table_name> rename partition <partition_name> to <new_partition_name>;
alter table <table_name> rename subpartition <subpartition_name> to <new_subpartition_name>;
|
每當新資料觸發新建分割槽後,分割槽名字是系統給的,雖然不影響分割槽表的使用,但是看著很讓人迷茫:
1 2 3 4 5 6 7 |
select
table_name ,
partition_name,
subpartition_name ,
tablespace_name
from user_tab_subpartitions
where subpartition_name like 'SYS%' ;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME ------------------------------ --------------- ------------------ ------------------------------
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP100 FIREWALL16
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP101 FIREWALL17
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP102 FIREWALL18
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP103 FIREWALL19
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP104 FIREWALL20
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP105 FIREWALL21
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP106 FIREWALL22
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP107 FIREWALL23
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP108 FIREWALL24
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP109 FIREWALL25
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP110 FIREWALL26
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ --------------- ------------------ ------------------------------
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP111 FIREWALL27
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP112 FIREWALL28
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP113 FIREWALL29
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP114 FIREWALL30
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP115 FIREWALL31
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP85 FIREWALL01
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP86 FIREWALL02
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP87 FIREWALL03
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP88 FIREWALL04
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP89 FIREWALL05
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP90 FIREWALL06
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ --------------- ------------------ ------------------------------
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP91 FIREWALL07
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP92 FIREWALL08
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP93 FIREWALL09
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP94 FIREWALL10
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP95 FIREWALL11
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP96 FIREWALL12
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP97 FIREWALL13
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP98 FIREWALL14
P_MYSYSLOG_IL_2010 SYS_P116 SYS_SUBP99 FIREWALL15
|
將分割槽/子分割槽的名字改成得有意義才是王道。以下是用一個過程配合遊標來改分割槽名,重點是是從high_value欄位獲得該分割槽的範圍描述,其他沒什麼了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
declare
v_sql varchar (400);
v_table_name user_tab_partitions.table_name%type;
v_partition_name user_tab_partitions.partition_name%type;
v_high_value varchar (200);
v_tmp_partition_name user_tab_partitions.partition_name%type;
cursor cur is
select
table_name ,
partition_name ,
high_value
from user_tab_partitions
where partition_name like 'SYS%' ;
begin
open cur;
loop
fetch cur into v_table_name,v_partition_name,v_high_value;
exit when cur%notfound;
v_tmp_partition_name := substr(v_high_value,11,10);
v_tmp_partition_name := to_char( to_date(v_tmp_partition_name, 'yyyy-mm-dd' )-1 , 'yyyymm' );
v_sql := 'alter table ' ||v_table_name|| ' rename partition '
||v_partition_name
|| ' to P' ||v_tmp_partition_name;
dbms_output.put_line( v_sql );
execute immediate v_sql;
end loop;
close cur;
end ;
/
|
由於改分割槽名屬於DDL語句,對於忙碌的系統來說很容易遇到ORA-00054這個錯誤:
1 |
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
|
Oracle 11g 同時也引入了一個新特性——DDL Wait ,以前遇到這種情況要不就是找出那個該死的Transaction kill掉,要不就僱個人拼命堅持不懈地敲鍵盤跑這條DDL,直到成功執行,現在好了,這個人可以下崗了。只要設定ddl_lock_timeout這個引數就可以了,這個引數可以在例項級別和會話級別上設定,如果該值為0,遇到未提交事務時就會馬上報ORA-00054,如果設定為10,DDL語句會為這個事務最多等10秒,10秒內事務提交,DDL語句就會執行成功,否則10秒後再報ORA-00054。