1. 程式人生 > 其它 >0陣列中等 牛客NC.37合併陣列 leetcode56. 合併區間

0陣列中等 牛客NC.37合併陣列 leetcode56. 合併區間

技術標籤:技術交流GaussDB磁碟資料分散式儲存資料庫

摘要:在資料庫中用於維護資料庫磁碟空間的工具是VACUUM,其重要的作用是刪除那些已經標示為刪除的資料並釋放空間。

vacuum的功能

回收空間

資料庫總是不斷地在執行刪除,更新等操作。良好的空間管理非常重要,能夠對效能帶來大幅提高。

執行delete操作後,表中的記錄只是被標示為刪除狀態,並沒有釋放空間,在以後的update或insert操作中該部分的空間是不能夠被重用的。

在資料庫中用於維護資料庫磁碟空間的工具是VACUUM,其重要的作用是刪除那些已經標示為刪除的資料並釋放空間。經過vacuum清理後,空間才能得到釋放。

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比任何事務都要老。這樣就不會出現上面的這種情況了。

更新visibility map

在資料庫中,有一個visibility map用來標記那些page中是沒有dead tuple的。這有兩個好處,一是當vacuum進行scan時,直接可以跳過這些page。二是進行index-only scan時,可以先檢查下visibility map。這樣減少fetch tuple時的可見性判斷,從而減少IO操作,提高效能。另外visibility map相對整個relation,還是小很多,可以cache到記憶體中。

vacuum full與vacuum的區別

1.vacuum只是將刪除狀態的空間釋放掉,轉換到能夠重新使用的狀態,但是對於系統來說該資料塊的空閒空間並沒有反應到系統的元資料中,並不進行空間合併。

而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進行規避

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