教你如何成為Oracle 10g OCP - 第九章 物件管理(3)

tolywang發表於2011-01-27


分割槽表及分割槽索引的管理 --

http://space.itpub.net/35489/viewspace-668041

local 索引的維護會在oracle 操作表分割槽的時候自動進行,需要注意的是global
索引,當global索引所在表執行alter table 涉及下列操作時,會導致該索引失效:
 ADD PARTITION | SUBPARTITION
 COALESCE PARTITION | SUBPARTITION
 DROP PARTITION | SUBPARTITION
 EXCHANGE PARTITION | SUBPARTITION
 MERGE PARTITION | SUBPARTITION
 MOVE PARTITION | SUBPARTITION
 SPLIT PARTITION | SUBPARTITION
 TRUNCATE PARTITION | SUBPARTITION

因此,建議使用者在執行上述操作sql 語句後附加update indexes 子句,oracle
即會自動維護全域性索引,當然,需要注意這中間有一個平衡,你要平衡操作ddl的
時間和重建索引哪個時間更少,以決定是否需要附加update indexes 子句。

 


分割槽表的管理 --


1. 增加表分割槽(add partition) 

增加表分割槽適用於所有的分割槽形式,語法:alter table tab_name add partition..


對於像list,range 這種存在範圍值的分割槽,所要增加的分割槽值必須要大於當前分
區中的最大值(但是如果當前存在maxvalue 或default 的分割槽,add partition
會報錯,這種情況只能使用split,後面會講到),hash 分割槽則無此限制。
例子:
alter table test_range add partition p6 values less than (120000) tablespace tbs06 ;
alter table test_list add partition p12 values ('50','100') tablespace tbs02 ;
alter table test_hash add partition ; 

注意:

(1)、對於hash 分割槽,當你執行add partition 操作的時候,oracle 會自動選擇一個
分割槽,並重新分配部分記錄到新建的分割槽,這也意味著有可能帶來一些IO 操作,但
是執行操作的過程可能很快結束,只是資料重新分配還在後臺進行,具體參考:
http://www.itpub.net/thread-1390083-1-1.html

(2)、執行alter table add partition 時未指定update indexes 子句:
  如果是range/list分割槽,其local 索引和global 索引不會受影響(未發生資料移動);
  如果是hash 分割槽,新加分割槽及有資料移動的分割槽的local 索引和global索引會被
  置為unuseable,需要重新編譯。具體可以參考測試:
http://space.itpub.net/35489/viewspace-684473   

(3)、複合分割槽完全適用上述所述規則。

 


2. 拆分表分割槽(split partition) 

比較常用的split是對default或maxvalue進行拆分,不過如果你發現非maxvalue/
default分割槽某分割槽過大,也可以透過split的方式對這些分割槽進行拆分。

該命令的語法針對不同分割槽有不同的形式:
range partition : alter table tbname split partition ptname at (value) into (partition newpt1
tbs_clause,partition newpt2 tbs_clause);
list partition : alter table tbname split partition ptname values (v1,v2...vn) into (partition newpt1
tbs_clause,partition newpt2 tbs_clause);
上述兩項,如果是操作子分割槽,則將partition 關鍵字換成subpartition 即可。舊分割槽
中符合新定義值的記錄會儲存到指定的第一個分割槽中,其它的記錄儲存到第二個分割槽。

例子:

CREATE TABLE DFMS.TEST04
PARTITION BY RANGE(OBJECT_ID)

  PARTITION P1 VALUES LESS THAN (2000)  TABLESPACE TBS01, 
  PARTITION P2 VALUES LESS THAN (8000)  TABLESPACE TBS02,
  PARTITION P3 VALUES LESS THAN (20000) TABLESPACE TBS03,
  PARTITION P4 VALUES LESS THAN (40000) TABLESPACE TBS04,
  PARTITION PMAX VALUES LESS THAN (MAXVALUE)  TABLESPACE TBS05
)
AS SELECT * FROM DBA_OBJECTS ;


alter table test04 split partition pmax at (80000) into 
(partition p5 tablespace log_data ,
 partition pmax  tablespace log_data); 

備註: 這裡的pmax並不是舊的pmax, 其實這裡的pmax也可以寫成p6, 只是
新的pmax(或p6)對應的值都是maxvalue(值範圍不變,名字可以任意起) .


a. split partition/subpartition不能用於hash分割槽或hash子分割槽。
b. split partition/subpartition 視被分割的分割槽資料量多少,可能需要花費
不小的代價,相當於該分割槽資料的全掃描,除了:
 (1). split後的兩個分割槽中,至少一個是空的,且非空那個分割槽的儲存屬性
與split前的儲存屬性完全相同。
 (2). 如果split的分割槽包含blob欄位,split後非空的那個分割槽中欄位的儲存屬性
也必須與split前的儲存屬性完全相同。

 


split分割槽對於索引的影響:

A. split新分割槽中有資料時

拆分(split)後, 舊分割槽中符合less than 80000的留在了第一個分割槽p5(新分割槽),
其他的都存在第二個分割槽(新的pmax分割槽)。 由於這裡觸發了資料的移動,global
index 變成UNUSABLE(失效),因為發生資料移動的只是新的p5和pmax分割槽,所以
本地索引分割槽中p5及pmax對應的本地索引變成無效UNUSABLE, 其他分割槽還是USABLE.

alter index PK_ID rebuild online; 
alter index IDX1_TEST04 rebuild partition p5 online; 
alter index IDX1_TEST04 rebuild partition pmax online;
查詢dba_indexes及dba_ind_partitions可以看到索引變成valid及USABLE狀態了。

B. split新分割槽中沒有資料時

比如我們再加入一個分割槽,表中值最大是100000,所以新的pmax中沒有資料。
alter table test04 split partition pmax at (200000) into 
(partition p6 tablespace log_data , partition pmax  tablespace log_data); 
檢視global index及local index可以看到全域性索引及每個本地索引分割槽都是
USABLE, 這是因為沒有觸發資料移動 。 注意因為這裡是表空間沒有變化,
如果非空的分割槽儲存屬性和原來的儲存屬性不一樣,也會發生資料移動,也會導致
索引失效。

雖然存在幾種情況,但是我們在做完一些分割槽表的操作後,最好都能查詢一下全域性
及本地分割槽索引的狀態,以免出現異常。 

 

3. Drop表分割槽(drop partition) 

刪除表分割槽包含兩種操作,分別是:
a. 刪除分割槽:  alter table table_name drop partition [partition_name] ;
b. 刪除子分割槽:alter table table_name drop subpartition [subpartition_name] ; 
除了hash分割槽和hash子分割槽外,其他的分割槽格式都可以支援這項操作。drop partition
時該分割槽記憶體儲的資料也將同時刪除。

如果使用者只是想刪除指定的分割槽但保留資料,你應該使用merge partition .

同樣,如果執行drop partition時候沒有指定update indexes子句時,可能對全域性
及本地分割槽索引造成影響。如果刪除的分割槽沒有資料,不涉及到資料變化,那麼
全域性及本地分割槽索引不受到影響(不失效); 如果刪除的分割槽有資料,既不保留分割槽
也不保留資料,那麼刪除分割槽時對應的本地索引分割槽也同時被刪除,不受影響,但是
全域性索引會失效。具體測試見:
http://space.itpub.net/35489/viewspace-684473 

 

4. 截斷表分割槽(Truncate Partition)

Truncate partition 就像truncate table 一樣,直接從頭部截斷資料。在不指
定update indexes 子句的情況下,truncate partition 也會造成分割槽所在表的
global 索引失效。語法非常簡單:
alter table tbname truncate partition/subpartition ptname;

alter table test04 truncate partition p6 ;
查詢
select * from dba_indexes where index_name='PK_ID' ;
select * from dba_ind_partitions where index_name='IDX1_TEST04' ;
發現global index索引失效,本地分割槽索引狀態都是USABLE, 當然如果這個分割槽
中本來就沒有資料,那麼本地及全域性索引都不受影響。 

 

5. 合併表分割槽(Merge Partition)
將兩個分割槽合併為一個,適用於除hash分割槽外的其他分割槽形式(hash分割槽採用
coalesce partition), 需要注意的是要合併的兩個分割槽必須是連續的,這是
由分割槽本身的特性決定的。

語法:
alter table tab_name merge partitions/subpartitions pt1,pt2
into partition/subpartition pt3 ; 

同樣也可以接update indexes子句以避免單獨執行造成索引失效的問題。

例子:
alter table test04 merge partitions p4,p5 into partition p4
tablespace log_data ;
ORA-14275: 不能將下界分割槽作為結果分割槽重用 

alter table test04 merge partitions p4,p5 into partition p7
tablespace log_data ; 
名稱修改為新的p7, 建立完成後,因為僅僅是合併分割槽,沒有發生資料移動,
所以全域性及本地分割槽索引都沒有受到影響。

 

6. 修改list表分割槽 - add/drop values

alter table tab_name modify partition/subpartition part_name add
values (v1,v2,v3.....vn) ; 

例子:
alter table test06 modify partition p3 add values(29,31) ; 

需要注意的是,新增的新value不能存在於當前任何分割槽list值中,當前表中也不能
存在資料為新加入的value的記錄,特別是當我們建立了default分割槽的時候,有必
要先檢查一下當前表不存在要新增的值,不然命令執行會報錯。

注意: 增加新的list值不會影響表中原有的記錄,不會對index造成影響。 

drop values正好相反,該命令是用來刪除指定分割槽的value值,語法:
alter table tab_name modify partition/subpartition part_name drop value(v1,v2...vn);
同樣在刪除list分割槽value列值的時候,也必須確認當前分割槽存在指定的value值,
但是沒有任何應用該值的記錄(即對應這個value沒有資料存在表中)。  

alter table test06 modify partition p3 drop values(29) ;  

 

7.  移動表分割槽(move partition)

和move table的操作很類似,有時也非常有用,比如降低行遷移,經常用來修改分割槽
所在表空間。
alter table test04 move partition t3 tablespace tbs05 ;

和move table一樣,move partition/subpartition會鎖表,如果沒有指定update
indexes的話,則被移動分割槽所在的local index以及全域性索引都會失效,需要進行
rebuild.

 

8.  重新命名錶分割槽(Rename partition) 
alter table tab_name rename partition part_name to new_part_name ;
例子:
alter table test04  rename partition p3 to p12 ;


9.  修改表分割槽當前屬性(Rename partition) ,
即修改即生效,不過所在表空間改不了(需要用到move partition). 比較少用。


10.  修改表分割槽預設屬性(Rename partition)
對於當前表和分割槽的儲存引數沒有影響,只有修改過之後,當你下次再新增分割槽
時,在非手工顯式指定分割槽引數的情況下,新分割槽預設使用你當前指定的儲存引數。

A. 修改表屬性,適用於range,list,hash分割槽形式(hash分割槽只能修改預設表空間引數)
例如:
alter table test04 modify default attributes tablespace tbs001 ;
B. 修改分割槽屬性,適用於組合分割槽
例如:
alter table test04 modify default attributes for partition p5 tablespace tbs003;

 

分割(splitting),移除(dropping ),及融合(merging)等操作不適用於
雜湊分割槽。但對雜湊分割槽可以進行新增(add)及接合(coalesce)操作。

 

 

分割槽索引的管理 -- 


A. 增加索引分割槽 (add index partition)
注意: 增加索引分割槽僅僅是針對非local分割槽索引而言的。

alter index idx_name add partition part_name tablespace xxx ;
增加分割槽只能用於hash的global索引(如果想為range型別的索引增加分割槽,不要
用add, 使用split)。add partition無法新增local索引分割槽,因為local分割槽是
由索引所在基表來維護的(分割槽表在增加分割槽的時候index分割槽也會自動增加)。

例子:alter index idx_test03_id add partition p8 tablespace tbs8;


B. 刪除索引分割槽(drop index partitions)
alter index idx_name drop partition part_name ;
這裡是刪除索引的分割槽,索引分割槽的資料不會刪除,會轉移。

要注意的是,索引必須擁有一個maxvalue的分割槽,該分割槽無法刪除。另外,刪除
的索引分割槽中包含資料,分割槽被刪除後,會造成相鄰的higher分割槽失效,需要手工
編譯。因為索引中資料都是經過排序的,drop partition刪除的是索引的分割槽,但
對應的索引資料還需要有地方存放(不然索引就不準確了),於是就只好儲存到比它
更高區間值的索引分割槽裡去了,那個分割槽莫名其妙多了資料,自然狀態就變成不可
用了。


C. 重新rebuild索引分割槽
alter index idx_name rebuild partition/subpartition part_name ;
其中global索引只支援range分割槽,local索引沒有限制。一般對於索引進行
rebuild都是在對分割槽表進行一些操作導致資料移動後進行,如果分割槽表操作
指定了update indexes子句,無效索引分割槽自動rebuild .

對於local索引分割槽,還可以使用下面的命令方式:
alter table tab_name modify partition/subpartition part_name
rebuild unusable local index ; 

檢視分割槽索引是否失效的檢視: dba_ind_partitions

 

D. 重新命名索引分割槽
語法:
alter index idx_name rename partition/subpartition ptname to ptnewname ;
global索引只支援range分割槽,local索引沒有限制。
 

E. Split索引分割槽
alter index idx_name split partition ptname at (value)
into (partition pt1 tableclause, partition pt2 tbsclause) ;

例子:
alter index idx_test04_id split partition i_p8 at (2000) into
  (partition i_p8 tablespace tbs02
   partition i_p9 tablespace tbs05); 


F. 修改索引分割槽預設屬性
與修改表分割槽的操作類似,不過對於global索引,只能修改range分割槽,local
索引無限制。
alter index idx_name modify default attributes for partition ptname ;


G. 修改索引分割槽當前屬性 
類似表分割槽當前屬性。


-------------------------------------------------
會導致global index及local index失效的測試:
http://space.itpub.net/35489/viewspace-684473 

分割槽表及分割槽索引[final]
http://space.itpub.net/35489/viewspace-668041
-------------------------------------------------

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-686378/,如需轉載,請註明出處,否則將追究法律責任。

相關文章