摘要:在GaussDB(DWS)中,VACUUM的本質就是一個“吸塵器”,用於吸收“塵埃”。 下面將從VACUUM的作用、用法、原理等方面進行介紹。
在GaussDB(DWS)中,VACUUM的本質就是一個“吸塵器”,用於吸收“塵埃”。而塵埃其實就是舊版本數據,如果這些數據沒有及時清理,那么將會導致數據庫空間膨脹,性能下降,更嚴重的情況會導致宕機。下面將從VACUUM的作用、用法、原理等方面進行介紹。
1、VACUUM的作用
1)空間膨脹問題:清除廢舊元組以及相應的索引。包括提交的事務delete的元組(以及索引)、update的舊版本(以及索引),回滾的事務insert的元組(以及索引)、update的新版本(以及索引)、copy導入的元組(以及索引)。
2)freeze:防止因事務ID回卷問題(Transaction ID wraparound)而導致的宕機,將小於OldestXmin的事務號轉化為freeze xid,更新表的relfrozenxid,更新庫的relfrozenxid,truncate clog。
3)更新統計信息:VACUUM analyze時,會更新統計信息,使得優化器能夠選擇更好的方案執行sql。
2、VACUUM命令
VACUUM 命令存在兩種形式,VACUUM和VACUUM FULL,VACUUM命令做的是LAZY VACUUM。從字面意思就可以看出來,LAZY VACUUM是VACUUM FULL的簡化版。具體區別見下表。
注:目前LAZY VACUUM只對行存表起作用,對列存表無效,列存表只能依靠VACUUM FULL釋放空間。
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 [, ...] ) ] ]
重要參數說明:
- FULL 選擇VACUUM FULL清理,可以恢復更多空間,但耗時更多。
- FREEZE指定FREEZE相當於執行VACUUM時將VACUUM_freeze_min_age參數設為0。
- VERBOSE為每個表打印一份詳細的清理工作
- ANALYZE | ANALYSE更新用於優化器的統計信息,以決定執行查詢的最有效方法。
3、VACUUM原理
3.1 LAZY VACUUM執行流程
(1)從指定的多張表中進行遍歷,從而獲取每一個表。
(2)獲取遍歷到表的共享鎖,該鎖允許其他事務讀取。
(3)獲取每個頁面的dead tuples(死亡元組),並freeze需要的元組。
(4)刪除指向dead tuples的院所元組。
(5)刪除dead tuples並重新分配live tuples(活動元組)。
(6)更新目標表的FSM(用於記錄每個數據塊的空閑空)和VM(標記數據塊中是否存在需要清理的行)。
(7)重復5,6步驟直到遍歷完該表的每一頁.
(8)如果最后一頁沒有元組,則進行截斷。
(9)更新與VACUUM有關的統計信息表和系統目錄。
3.2 VACUUM FULL執行流程
(1)建立臨時表:數據庫創建一張臨時表,該表繼承老表的所有屬性。如果用戶表有名字與這個臨時表相同的,那么就會失敗。在該階段申請的行排他鎖(RowExclusiveLock)。
(2)數據復制:將原來表中的數據復制到臨時表中。在該過程中完成堆dead tuples的清理。該階段申請的是訪問排他鎖AccessExclusiveLock。
(3)交換表:使用新表代替老表。而交換的本質是物理文件的交換,即臨時表帶老物理文件,老表帶新物理文件。該階段會再次申請行排他鎖(RowExclusiveLock)。
(4)重建索引:當交換完成后,會進行索引重建,並更新統計信息。此時對表申請共享鎖(ShareLock)。
(5)刪除臨時表:索引重建完成后,會將帶有老物理文件的臨時表進行刪除。
本文分享自華為雲社區《GaussDB(DWS) VACUUM總結》,原文作者:KevinMV 。