1. 程式人生 > 其它 >關於降低高水位線的嘗試(r3筆記47天)

關於降低高水位線的嘗試(r3筆記47天)

在前一段時間,生產環境中有幾個很大的分割槽表,由於存在太多的碎片,導致表裡的資料就幾十條,但是查詢的時候特別慢。很明顯是高水位線導致的問題。 一般來說這類問題,使用備份->truncate->insert的方式比較保守,不適用於線上操作。 而在10g開始的一個新特性shrink算是一個比較理想的方案,按照新特性的預期,速度也是很快的,而且是線上操作。可以分批釋放表中的冗餘空間。 所以做了一個嘗試,在生產系統中使用這個新特性來降低高水位線。 生產中的表pub_log,sub_log都是分割槽表,分割槽數不多,幾十個左右。 首先使用shrink需要先設定表為enable rowmovement,這個操作會導致和這個表對應的包體失效。 可以使用shrink space compact先來壓縮空間,然後在空閒時段使用shrink space來降低高水位線,但是shrink的操作對於基於函式的索引還是受限的。所以使用的時候需要考量一下。 需要降低高水位線的表是PUB_LOG,SUB_LOG,所在在簡單準備之後,寫了如下的指令碼。


alter  session force parallel ddl parallel 8;  --設定了並行
alter table PUB_LOG enable row movement;   --啟用row movement
alter table PUB_LOG shrink space compact;    --先壓縮表的空間
alter table PUB_LOG shrink space;        --降低表的高水位線
alter index  PUB_LOG_PK shrink space compact;   --對索引也可以設定同樣的操作。
alter index PUB_LOG_PK  shrink space; 
alter table PUB_LOG disable  row movement;  

alter table SUB_LOG enable row movement; 
alter  table SUB_LOG shrink space compact; 
alter table SUB_LOG shrink space  ; 
alter index SUB_LOG_PK shrink space compact; 
alter index SUB_LOG_PK  shrink space; 
alter index SUB_LOG_1IX shrink space compact; 
alter index  SUB_LOG_1IX shrink space ; 
alter table SUB_LOG disable row  movement; 

在測試環境中做測試的時候,時間還是很快的,在5分鐘以內完成了所有的操作。 然後指令碼提交給客戶去執行,結果晚上就接到電話,說第一步操作 alter table PUB_LOG shrink space compact 執行了快3個小時,還沒有執行完。客戶最後kill了那個session. 在第二天查這個問題的時候發現,在shrink space compact的同時,有幾個session正在執行update,delete操作,執行還是比較頻繁的。 看來shrink的操作還是需要謹慎,在生產環境中可能涉及的操作場景更為複雜。最後評估之後還是轉為truncate的方式了。 truncate的操作步驟比較老套,但是在操作的時候還是有不少的細節。 首先是備份 可以使用exp/expdp的方式,如果資料量不大,可以採用使用表級備份。 我先嚐試了exp的方式,結果發現還是有一些問題,表裡只有68條資料,但是exp的時候,用了1分鐘左右。 Export terminated successfully without warnings. real 1m7.111s user 0m0.104s sys 0m0.065s

檢視對應的索引情況,看來還是受到高水位線的影響。


INDEX_NAME             TABLESPACE  INDEX_TYPE  UNIQUENES  PAR  COLUMN_LIST                      TABLE_TYPE STATUS   NUM_ROWS LAST_ANAL  G
---------------------- ---------- ---------- --------- ---  ------------------------------ ---------- ------ ---------- ---------  -
PUB_LOG_PK               NORMAL      UNIQUE      YES  BUFFER_ID,PUB_TRX_ID,SOURCE_COMP_ID TABLE      N/A            15 23-OCT-14  N

select count(*)from pub_log 速度也是很慢的。 因為索引是buffer_id開頭,最後間接的使用索引,速度一下子就快了很多。 select count(*)from trb1_pub_log where buffer_id in(select buffer_id from trb1_pub_log group by buffer_id); COUNT(*) ---------- 68 Elapsed: 00:00:00.17 最後轉換為exp的方式,時間降低到5秒 time exp xxx/xxx tables=pub_log file=pub_log_bak.dmp query=' where buffer_id in (select buffer_id from pub_log group by buffer_id)' buffer=9102000 statistics=none grants=n indexes=n

real 0m5.064s user 0m0.039s sys 0m0.037s 到這一步其實也基本告一段落了,如果有些分割槽表含有lob欄位,匯出速度也還是會慢不少。 再次進行調整,發現使用表級備份還是不錯的。 create table tmp_bak_pub_log nologging as select * from pub_log where buffer_id in (select buffer_id from pub_log group by buffer_id) ; Elapsed: 00:00:01.69 create table tmp_bak_sub_log nologging as select * from sub_log where queue_id in (select queue_id from sub_log group by queue_id) ; --sub_log含有lob欄位,exp也還是慢不少,使用表級備份就快多了。 Elapsed: 00:00:00.58 備份完成之後,就是truncate truncate table pub_log reuse storage; truncate table sub_log reuse storage; 最後insert即可。 insert into pub_log select *from tmp_bak_pub_log; commit; insert into sub_log select *from tmp_bak_sub_log; commit; 總體來說,對於新特性的使用還是要做大量的測試,需要謹慎和保守,對於一些看似簡單的操作也可以精工出細活。