Oracle Table Reorganization(shrink space)

Table Reorganization(shrink space)

標籤: 
Propose / 目標
1.move down the HWM (表格如果常異動 insert/update/delete,則會產生許多碎片)
2.releases unused extents.
 
Howto:
alter table mytable enable row movement;
alter table mytable shrink space compact <cascade>;
 
alter table mytable shrink space <cascade>;
 


 

Table Reorganization
1.static (table不能被DML)
 1.1 export -> drop -> import =>object id與data object id改變
 1.2 alter table hr.big1 move; => data object id變更
2.dynamic (table可以被DML)
 2.1 alter table hr.big1 shrink space compact; -> alter table hr.big1 shrink space; =>object id與data object id都沒有改變
 2.2 table ondefinition => object_id與data_object_id都變更,但其實是object_name變更才對.
 

要調整HWM可以藉由下面的指令達成
 
1. export / import 
2. alter table table_name move; (index會失效,MVIEW使用rowid會失效)
3. alter index index_table rebuild online; 
4. alter table table_name shrink space ; (only for Oracle 10g)
 
Shrink Space Syntax
 
shrink space 的兩個必要條件 
1. Enable row movement 
2. Table 所在的tablespace 不能使用在segment space management manaual 的tablespace, 必須為auto
 
執行shrink space 分成兩個階段 
1. compact : 透過insert / delete 將資料盡量排例在segment 前面.這個階段會造成rowid的改變,因此需要enable row movement.
 
alter table TABLE_NAME enable row movement;
 
2. HWM 調整:這個階段是調整HWM位置,釋放表格空間
 
alter table <TABLE_NAME> shrink space compact ; 只會執行第一階段 
alter table <TABLE_NAME> shrink space ; 兩個階段都會執行 
alter table <TABLE_NAME> shrink space cascade ; 同時處理相關index 空間 
alter index <INDEX_NAME> shrink space ; 回收index 空間 
alter table <TABLE_NAME> modify lob (<lob_clomun>) (shrink space);
 
 
由於alter table TABLE_NAME enable row movement 可能會使的引用該table的object( ex procedure,package,view…) 變成invalid,所以執行後最後執行一下utlrp.sql 或 utlprp.sql 來編譯一下invalid object , utlrp.sql 或 utlprp.sql放在$ORACLE_HOME/rdbms/admin 目錄下,或者執行UTL_RECOMP這個package
 
Shrink space script 
 
1. Normal Table
select'alter table '|| owner || '.' || table_name||' enable row movement;
'||chr(10)||'alter table '|| owner || '.'||table_name||' shrink space;'||chr(10)
from  dba_tables;
 
select'alter index '|| owner || '.' ||index_name||' shrink space;'||chr(10) from dba_indexes;
 
2. Partition Table
select 'alter table '|| owner || '.'  ||table_name||' enable row movement;'||chr(10)||
'alter table '|| owner || '.'||table_name||' shrink space;'||chr(10) from dba_tables
 
select 'alter index '|| owner || '.'||index_name||' shrink space;'||chr(10)
from dba_indexes where uniqueness='NONUNIQUE' ;
 
select 'alter table '|| owner || '.'||segment_name||' modify subpartition '||partition_name||' shrink space;'||chr(10)
from dba_segments where segment_type='TABLE SUBPARTITION' ;

 

 
————————————————————-
測試環境建置:
SQL>create table hr.test (A date , B number (10));
Insert 90000 records…
SQL>begin
   for v_number in 10000..100000 loop
        insert into hr.test values (sysdate , v_number);
        commit;
     end loop; 
end;
/
 
確認一下此Table的資料型態(要看一下搬移的資料難度,若都是Table的話,要搬移的話比較方便)
SQL>select segment_type , count(1) from dba_segments where tablespace_name=' users' group by segment_type;
 
 
計算Table size(刪除前的資料)
SQL>analyze table hr.test compute statistics;
SQL>select table_name,(blocks*8)||'kb' "size" from all_tables where table_name = 'TEST' and owner='HR';
 
刪除所有資料(這個時候空間還沒有Release出來,現在只是一個空的空間)
SQL>select segment_name , extent_id from dba_extents where segment_name like 'TEST' and owner='HR';
SQL>delete from hr.test;
SQL>commit;
 
Starting table shrinking:
SQL>alter table hr.test enable row movement;
SQL>alter table hr.test shrink space compact;
–僅透過delete/insert row的方式,將row搬移到更接近segment header的blocks,試圖製造出high water mark下有連續的empty blocks
–因為使用shrink space compact,並沒有移動high water mark與並沒有收回空間,所以table還可以被其他人進行dml,query
 
SQL>alter table hr.test shrink space;
–僅透過delete/insert row的方式,將row搬移到更接近segment header的blocks,試圖製造出high water mark下有連續的empty blocks
–調整high water mark的位置到目前有資料的最後一個block,並將新的high water mark之上的空間,全數收回,變成free extents,歸還tablespace
–不過因為shrink space最後將變更high water mark位置與收回空間,所以在此操作過程中,table不能被其他session進行ddl/dml指令
 
SQL> alter table hr.test shrink space cascade;
 –假設有index,透過cascade將table之上的index也一起進行shrink segment操作
 
SQL>select segment_name , extent_id from dba_extents where segment_name like 'TEST' and owner='HR';
 
計算Table size(刪除後的資料)
SQL>analyze table hr.test compute statistics;
SQL>select table_name,(blocks*8)||'kb' "size" from all_tables where table_name = 'TEST' and owner='HR';
Q: 為何無資料仍佔用8 oracle blocks(64kb)??
A:因為建立TABLE時,會先預留給64KB給表格

查詢那一些db file可以縮小空間(Shrink完才看得出來效過):

 
SQL>SELECT
  a.file_id,
  a.file_name
  file_name,
  CEIL( ( NVL( hwm,1 ) * blksize ) / 1024 / 1024 ) smallest,
  CEIL( blocks * blksize / 1024 / 1024 ) currsize,
  CEIL( blocks * blksize / 1024 / 1024 ) –
  CEIL( ( NVL( hwm,1) * blksize ) / 1024 / 1024 ) savings,
  'alter database datafile ''' || file_name || ''' resize ' ||
  CEIL( ( NVL( hwm,1) * blksize ) / 1024 / 1024 ) || 'm;' cmd
FROM
  DBA_DATA_FILES a,
  (
     SELECT  file_id, MAX( block_id + blocks – 1 ) hwm
     FROM    DBA_EXTENTS
     GROUP BY file_id
  ) b,
  (
     SELECT TO_NUMBER( value ) blksize
     FROM   V$PARAMETER
     WHERE  name = 'db_block_size'
  )
WHERE
  a.file_id = b.file_id(+)
AND
  CEIL( blocks * blksize / 1024 / 1024 ) – CEIL( ( NVL( hwm, 1 ) * blksize ) / 1024 / 1024 ) > 0
ORDER BY 5 desc
 
Reference:
 
http://blog.xuite.net/charley_ocp/mydba01/36094404
Shrink 教學:http://dbworker.blogspot.tw/2011/06/oracle-segment-hwm-hight-water.html#more

Read more

How to document Home Lab and Network

運維機房和跨域的網路,會遇到各式需求與問題,用對工具才能分析問題,個人覺得最重要的是使用能處理問題的工具。 推薦目前想學和正在使用的平台與軟體,協助將公司/家用機房文件化 佈告欄任務管理 Focalboard 白板可管理任務指派 網路架構文件編寫 netbox 精細管理網路設備與連接線路 IP 資源管理 phpipam 專注網路IP分配 邏輯塊文件編寫 draw.io 視覺化概念圖 機房設備管理 ITDB 管理設備生命週期與使用者

By Phillips Hsieh

如何在Raspberry Pi4上安裝Proxmox for ARM64

第一步 準備好Raspberry Pi 4 / CM4 4GB RAM,這裡要留意CM4如果是買有內建eMMC storage會限制不能使用SD卡開機而限制本地空間容量,如果沒有NAS外接空間或使用USB開機的話,建議買CM4 Lite插上大容量SD卡 第二步 去Armbian官網下載最小化Debian bookworm image https://www.armbian.com/rpi4b/ Armbian 25.2.2 Bookworm Minimal / IOT 然後寫入SD/USB開機碟,寫入方法參考官方文件 https://github.com/raspberrypi/usbboot/blob/master/Readme.md Note: 官方提供的預先設定系統方法,可以在Armbian初次啟動自動化完成系統設定。連結在此 https://docs.armbian.com/User-Guide_Autoconfig/

By Phillips Hsieh

世界越快心越慢

在晚飯後的休息時間,我特別享受在客廳瀏灠youtube上各樣各式創作者的影音作品。很大不同於傳統媒體,節目多是針對大多數族群喜好挑選的,在youtube上我會依心情看無腦的動畫、一些旅拍記錄、新聞時事談論。 尤其在看了大量的Youtube的分享後,我真的感受到會限制我的是我的無知,特別是那些我想都沒想過的實際應用,在學習後大大幫助到我的生活和工作層面。 休息在家時,我喜歡想一些沒做過的菜,動手去設計生活和工作上的解決方案,自己是真的很難閒著沒事做。 如創作文章,陪養新的習慣都能感覺到成長的喜悅,是不同於吃喝玩樂的快樂的。 創作不去限制固定的形式,文字是創作、影像聲音也是創作,記錄生活也是創作,我想留下的就是創造—》實現—》回憶,這樣子的循環過程,在留下的足跡面看到自己一路上的成長、失敗、絕望、重新再來。 雖然大部份的時候去做這些創作也不明白有什麼特別的意義,但不去做也不會留下什麼,所以呀不如反事都去試試看,也許能有不一樣的水花也許有意想不到的結果,投資自己永遠不會是失敗的決定,不是嗎?先問問自己再開始計畫下一步,未來沒人說得準。 像最近看youtube仍大一群人在為DOS開

By Phillips Hsieh

知識管理的三個步驟:一小時學會把知識運用到生活上

摘錄瓦基「閱讀前哨站」文章作為自己學習知識管理的內容 Part1「篩選資訊」 如何從海量資訊中篩選出啟發性、實用性和相關性的精華,讓你在學習過程中不再迷失方向。 1. 實用性 2. 啟發性 Part2「提高理解」 如何通過譬喻法和應用法,將抽象的知識與日常生活和工作緊密結合,建立更深刻的理解。 1. 應用法 2. 譬喻法 Part3「運用知識」 如何連結既有知識,跟自己感興趣的領域和專案產生關聯,讓你在運用知識的路途上游刃有餘。 1. 跟日常工作專案、人際活動產生連結 # 為什麼要寫日記? * 寫日記是為了忘記,忘卻瑣碎事情,保持專注力 * 寫日記就像在翻譯這個世界,訓練自己的解讀能力 * 不只是透過日記來記錄生活,而是透過日記來發展生活 #如何寫日記? * 不要寫流水帳式的日記,而是寫覆盤式的日記 當我們試著記錄活動和感受之間的關聯,有助於辦認出真正快樂的事 日記的記錄方式要以過程為主,而非結果 * 感恩日記的科學建議,每日感恩的案例

By Phillips Hsieh