摘要:在GaussDB(DWS)中,VACUUM的本質就是一個「吸塵器」,用於吸取「塵埃」。 下面將從VACUUM的做用、用法、原理等方面進行介紹。
本文分享自華爲雲社區《GaussDB(DWS) VACUUM總結》,原文做者:KevinMV 。sql
在GaussDB(DWS)中,VACUUM的本質就是一個「吸塵器」,用於吸取「塵埃」。而塵埃其實就是舊版本數據,若是這些數據沒有及時清理,那麼將會致使數據庫空間膨脹,性能降低,更嚴重的狀況會致使宕機。下面將從VACUUM的做用、用法、原理等方面進行介紹。數據庫
1)空間膨脹問題:清除廢舊元組以及相應的索引。包括提交的事務delete的元組(以及索引)、update的舊版本(以及索引),回滾的事務insert的元組(以及索引)、update的新版本(以及索引)、copy導入的元組(以及索引)。segmentfault
2)freeze:防止因事務ID回捲問題(Transaction ID wraparound)而致使的宕機,將小於OldestXmin的事務號轉化爲freeze xid,更新表的relfrozenxid,更新庫的relfrozenxid,truncate clog。性能
3)更新統計信息:VACUUM analyze時,會更新統計信息,使得優化器可以選擇更好的方案執行sql。優化
VACUUM 命令存在兩種形式,VACUUM和VACUUM FULL,VACUUM命令作的是LAZY VACUUM。從字面意思就能夠看出來,LAZY VACUUM是VACUUM FULL的簡化版。具體區別見下表。spa
注:目前LAZY VACUUM只對行存表起做用,對列存表無效,列存表只能依靠VACUUM FULL釋放空間。blog
VACUUM在GaussDB(DWS)中具體執行語法以下:繼承
1)回收空間並更新統計信息,對關鍵字順序無要求索引
VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ table_name [ (column_name [, ...] ) ] ]事務
2)僅回收空間,不更新統計信息
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table_name ]
3)回收空間並更新統計信息,且對關鍵字順序有要求
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table_name [ (column_name [, ...] ) ] ]
重要參數說明:
(1)從指定的多張表中進行遍歷,從而獲取每個表。
(2)獲取遍歷到表的共享鎖,該鎖容許其餘事務讀取。
(3)獲取每一個頁面的dead tuples(死亡元組),並freeze須要的元組。
(4)刪除指向dead tuples的院所元組。
(5)刪除dead tuples並從新分配live tuples(活動元組)。
(6)更新目標表的FSM(用於記錄每一個數據塊的空閒空)和VM(標記數據塊中是否存在須要清理的行)。
(7)重複5,6步驟直到遍歷完該表的每一頁.
(8)若是最後一頁沒有元組,則進行截斷。
(9)更新與VACUUM有關的統計信息表和系統目錄。
(1)創建臨時表:數據庫建立一張臨時表,該表繼承老表的全部屬性。若是用戶表有名字與這個臨時表相同的,那麼就會失敗。在該階段申請的行排他鎖(RowExclusiveLock)。
(2)數據複製:將原來表中的數據複製到臨時表中。在該過程當中完成堆dead tuples的清理。該階段申請的是訪問排他鎖AccessExclusiveLock。
(3)交換表:使用新表代替老表。而交換的本質是物理文件的交換,即臨時錶帶老物理文件,老表帶新物理文件。該階段會再次申請行排他鎖(RowExclusiveLock)。
(4)重建索引:當交換完成後,會進行索引重建,並更新統計信息。此時對錶申請共享鎖(ShareLock)。
(5)刪除臨時表:索引重建完成後,會將帶有老物理文件的臨時表進行刪除。