GaussDB(DWS)磁盤維護:vacuum full執行慢怎麼辦?

摘要:在數據庫中用於維護數據庫磁盤空間的工具是VACUUM,其重要的做用是刪除那些已經標示爲刪除的數據並釋放空間。

vacuum的功能

回收空間

數據庫老是不斷地在執行刪除,更新等操做。良好的空間管理很是重要,可以對性能帶來大幅提升。算法

執行delete操做後,表中的記錄只是被標示爲刪除狀態,並無釋放空間,在之後的update或insert操做中該部分的空間是不可以被重用的。數據庫

在數據庫中用於維護數據庫磁盤空間的工具是VACUUM,其重要的做用是刪除那些已經標示爲刪除的數據並釋放空間。通過vacuum清理後,空間才能獲得釋放。bootstrap

VACUUM回收已刪除元組佔據的存儲空間。在通常的數據庫操做裏,那些已經DELETE的元組或者被UPDATE事後過期的元組是沒有從它們所屬的表中物理刪除的;在完成VACUUM以前它們仍然存在。所以咱們有必須週期地運行VACUUM,特別是在常更新的表上。網絡

凍結tuple的xid

在每條記錄(tuple)的header中,存放xmin,xmax信息(增刪改事務ID)。transactionID的最大值爲2的32次,即無符整形來表示。當transactionID超過此最大值後,會循環使用。工具

這會帶來一個問題:就是最新事務的transactionID會小於老事務的transactionID。若是這種狀況發生後,就沒有辦法按transactionID來區分事務的前後,也沒有辦法實現MVCC了。性能

所以用vacuum後臺進程,按必定的週期和算法觸發vacuum動做,將過老的tuple的header中的事務ID進行凍結。凍結事務ID,即將事務ID設置爲「2」(「0」表示無效事務ID;「1」表示bootstrap,即初始化;「3」表示最小的事務ID)。被凍結的事務ID比任何事務都要老。這樣就不會出現上面的這種狀況了。fetch

更新visibility map

在數據庫中,有一個visibility map用來標記那些page中是沒有dead tuple的。這有兩個好處,一是當vacuum進行scan時,直接能夠跳過這些page。二是進行index-only scan時,能夠先檢查下visibility map。這樣減小fetch tuple時的可見性判斷,從而減小IO操做,提升性能。另外visibility map相對整個relation,仍是小不少,能夠cache到內存中。ui

vacuum full與vacuum的區別

1.vacuum只是將刪除狀態的空間釋放掉,轉換到可以從新使用的狀態,可是對於系統來講該數據塊的空閒空間並無反應到系統的元數據中,並不進行空間合併。spa

而vacuum full實質上是重建了整個表,以達到空間合併的效果。線程

2.vacuum執行過程當中對錶加4級鎖,不會影響表的增刪改查,而vacuum full對錶加8級鎖,執行過程當中表沒法訪問。

3.vacuum對列存表無效

vacuum full的執行流程

建臨時表

數據庫會新建一個臨時表,臨時表繼承老表全部屬性。

這個階段會對pg_class申請「RowExclusiveLock」鎖,由於須要插入記錄。

拷貝數據

將原來的數據copy到temp表中。

對臨時表,老表以及索引都以「AccessExclusiveLock」模式打開。

另外對於toast,只是lock,不打開。

在這個過程當中完成Dead Tuple的清理。

表交換

新表將老表替換掉。會對pg_class再次申請「RowExclusiveLock」鎖。

重建索引

是在交換以後完成的,重建索引時,會更新一些統計信息。對錶申請「ShareLock」鎖。

刪除臨時表

索引重建完成後,將帶有老物理文件的新臨時表進行刪除。

vacuum full執行慢的常見場景

1. 存在鎖爭搶

在cn上執行select * from pg_stat_activity where query like '%vacuum%';找到vacuum full的pid

查看該線程的等待狀態,若是等待狀態是acquire lock,說明存在鎖等待

select * from pg_thread_wait_status where tid = 139878309295872;

在pg_locks中查詢vacuum full在等哪一個鎖

select * from pg_locks where pid = 139878309295872 and granted = 'f';

查看持有該鎖的線程

select * from pg_locks where relation = 544793 and granted = 't';

查看該線程對應的語句

select query from pg_stat_activity where pid = 139877539612416;

根據語句判斷是否能夠殺掉該語句繼續作vacuum full,或者另外找時間窗作vacuum full

2. 存在IO/網絡問題致使事務沒法提交

執行一個簡單的create table語句,若是create table語句執行也很慢,說明存在IO/網絡問題,進一步排查IO和網絡

3. 系統表過大致使vacuum full慢

vacuum full任意一張表時,都會掃描pg_class、pg_partition、pg_proc三張系統表,當這三個系統表過大時,也會致使vacuum full較慢

能夠在排除IO/網絡問題(即create table語句不慢)後,對空表作vacuum full,觀察執行速度,若是空表作vacuum full也比較慢,則說明就是這三張系統表較大致使vacuum full任意表都慢

4. 排除以上場景以後,能夠查看錶定義中是否使用了PCK

當存在PCK時,表作vacuum full時會進行全排序,此時若是表較大或psort_work_mem設置較小,就會致使PCK排序時產生下盤,進行外排,效率急劇降低。

能夠經過調大psort_work_mem進行規避

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索