PostgreSQL的vacuum流程
vacuum是一種維護過程,有助於PostgreSQL的持久執行,它的兩個主要任務是刪除死元組,以及凍結事務標識。
vacuum的作用: 1.釋放,再利用更新/刪除的行所佔據的磁碟空間。 2.更新postgresql查詢計劃中使用的統計資料。 3.防止因事務ID的重置而使非常老的資料丟失。
併發清理過程為指定的表或者資料庫中的表執行以下任務:
第一部分 1.從指定的表中依次處理每一張表, 2.獲取表上的ShareUpdateExclusiveLock鎖(該鎖允許其他事物對該表進行讀取)。 3.掃描表中的所有頁面,獲取所有的死亡元組,(死元組的列表儲存在本地記憶體的maintenance_work_mem裡) 4.如果有必要,凍結舊的元組的事務標識 5.移除指向死亡元組的索引元組 第二部分 1.移除每一頁中的死亡元組,並對每一頁內的的活元組進行碎片整理,重排本頁的活元組 2.更新已經處理的空閒空間對映(FSM)和可見性對映(VM) PG會不斷執行這個過程直至最後一頁 第三部分 1.如果最後一個頁面沒有任何元組,則截斷最後一頁 2.更新與凍結事務標識相關的系統檢視(pg_class與pg_database) 3.釋放ShareUpdateExclusiveLock鎖 第四部分 1.更新一些統計資訊(pg_stat_all_tables等) 2.移除不必要的提交日誌檔案,移除CLOG(10版本及以後為xact)中的非必要檔案與頁面 (當更新pg_database.datfrozenxid時,會嘗試刪除不必要的CLOG)
清理過程會使用共享快取,處理過的頁面不會快取在共享快取裡。
為了移除死亡元組,清理過程有兩種模式,分別是併發清理與完整清理。清理過程刪除表檔案每個頁面中的死元組,而其他事務可以在其執行時繼續讀取該表。相反,完整清理不僅會 移除整個檔案中所有的死元組,還會對整個檔案中所有的活元組進行碎片整理。其他事務在完整清理執行時無法訪問該表。
清理過程涉及全表掃描,所以引入了可見性對映(Visibility Map,VM)來提高移除死元組的效率。
VM:每個表都有各自的可見性對映,用於儲存表檔案中每個頁面的可見性,頁面的可見性確定了每個頁面是否包含死亡元組。清理過程可以跳過沒有死亡元組的頁面。
如圖,假設一個表包含三個頁面,第0號頁和第2號頁包含死亡元組,但是第一號頁不包含死亡元組,在可見性對映中儲存著包含死亡元組的資訊,則在清理過程中,會參考VM,跳過第一個頁面清理下邊的頁面。
每個VM 檔案字尾_vm儲存,如一個表檔案的relfilenode是2612,則VM檔案為2612_vm,VM在9.6版本做了加強,除了顯示頁面可見性,還包含了頁面中原則是否全部凍結的資訊。
凍結過程分兩種模式:惰性模式和迫切模式。
惰性模式在開始凍結處理時,PG會計算freezelimit_txid,並凍結t_xmin小於freezelimit_txid的元組,
freezelimit_txid=(OldestXmin-vacuum_freeze_min_age)
OldestXmin是當前正在執行的事務中最早的事務標識,vacuum_freeze_min_age是一個配置引數(預設為50000000)
迫切模式 9.5版本之前會掃描所有頁以檢查表中的所有元組,更新相關的系統目錄,並在可能的情況下刪除不必要的檔案和clog頁。
滿足pg_database.datfrozenxid <(OldestXmin-vacuum_freeze_table_age)時,會觸發迫切模式,vacuum_freeze_table_age 預設值為150000000。
凍結每個表後,目標表的pg_class.relfrozenxid被更新。 在完成vacuum處理之前,必要時更新pg_database.datfrozenxid。每個pg_database.datfrozenxid列在相應的資料庫中儲存最小pg_class.relfrozenxid。
9.6版本進行了VM與凍結過程,新VM包含了每個頁面中所有元組是否被全部凍結的資訊,在迫切模式下進行凍結處理時,可以跳過僅包含凍結元組的頁面。
帶有freeze的vacuum會強制凍結指定表中的所有事務標識,而且freezeLimit會被設定為OldestXmin而不是OldestXmin - vacuum_freezre_min_age。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990629/viewspace-2787007/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- postgreSQL 12-2 vacuum-主流程SQL
- 【Postgresql】VACUUM 垃圾回收SQL
- 新特性:postgresql的vacuum漫談SQL
- PostgreSQL vacuum可見性SQL
- PostgreSQL 原始碼解讀(125)- MVCC#9(vacuum-主流程)SQL原始碼MVCC#
- PostgreSQL DBA(142) - PG 12(Monitoring PostgreSQL VACUUM processes)SQL
- PostgreSQL DBA(143) - pgAdmin(Monitoring PostgreSQL VACUUM processes#2)SQL
- PostgreSQL DBA(92) - PG 12 Improving VACUUMSQL
- PostgreSQL VACUUM 之深入淺出 (一)SQL
- PostgreSQL VACUUM 之深入淺出 (二)SQL
- PostgreSQL VACUUM 之深入淺出 (三)SQL
- Postgresql關於Vacuum的作用和操作方法,Vacuum full鎖表並生成新的relfilenodeSQL
- PostgreSQL 原始碼解讀(127)- MVCC#11(vacuum過程-vacuum_rel函式)SQL原始碼MVCC#函式
- PostgreSQL 並行vacuum patch - 暨為什麼需要並行vacuum或分割槽表SQL並行
- PostgreSQL DBA(159) - pgAdmin(Allow vacuum command to process indexes in paralleSQLIndex
- PostgreSQL 原始碼解讀(131)- MVCC#15(vacuum過程-lazy_vacuum_heap函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(128)- MVCC#12(vacuum過程-heap_vacuum_rel函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(132)- MVCC#16(vacuum過程-lazy_vacuum_index函式#1)SQL原始碼MVCC#Index函式
- PostgreSQL 原始碼解讀(129)- MVCC#13(vacuum過程-vacuum_set_xid_limits函式)SQL原始碼MVCC#MIT函式
- PostgreSQL 原始碼解讀(133)- MVCC#17(vacuum過程-lazy_vacuum_index函式#2)SQL原始碼MVCC#Index函式
- 第二週-20200306-PostgreSQL13並行vacuum索引SQL並行索引
- postgresql VACUUM 不會從表中刪除死行的三個原因SQL
- PostgreSQL 原始碼解讀(126)- MVCC#10(vacuum過程)SQL原始碼MVCC#
- PostgreSQL 原始碼解讀(264)- PG 14(Speeding up recovery and VACUUM)SQL原始碼
- PostgreSQL 原始碼解讀(134)- MVCC#18(vacuum過程-HeapTupleSatisfiesVacuum函式)SQL原始碼MVCC#APT函式
- PostgreSQL14在做vacuum時候的邏輯判斷是否經過HEAPTUPLE_RECENTLY_DEADSQLAPT
- PostgreSQL 原始碼解讀(130)- MVCC#14(vacuum過程-lazy_scan_heap函式)SQL原始碼MVCC#函式
- 教你使用SQLite VacuumSQLite
- PostgreSQL二進位制安裝流程SQL
- PostgreSQL 原始碼解讀(135)- MVCC#19(vacuum過程-heap_execute_freeze_tuple函式)SQL原始碼MVCC#函式
- Postgresql驗證_update、delete產生死亡元組,標準vacuum釋放表檔案磁碟空間的場景SQLdelete
- openGauss 對錶執行VACUUM
- template0 的 age 問題. vacuum template0
- 深入淺出VACUUM核心原理(中): index by passIndex
- openGauss/MogDB列存表vacuum DELTAMERGE過程申請的鎖
- PostgreSQL-PostgreSQL中的public(九)SQL
- 【PostgreSQL 】PostgreSQL 15對distinct的優化SQL優化
- PG12中新增:VACUUM命令的SKIP_LOCKED選項