PostgreSQL vacuum原理—vacuum揭秘
在前面兩個章節中,我們講了vacuum的一些重要引數“PostgreSQL vacuum原理一功能與引數”以及PG發起vacuum的流程“PostgreSQL vacuum原理—啟動機制”。這個章節我們重要講下vacuum 的實現,
主要分為vacuum full和lazy vacuum。
1.vacumm full
vacuum full會鎖表和索引,而且是“AccessExclusiveLock”級別的。其實vacuum full會重建整個表,這個的功能實現在cluster.c檔案中,因為其行業相當於是一個cluster重建的一個變種。
建臨時表階段:PG會新表一個以”pg_temp_%u”的臨時表,臨時表繼承老表所有屬性。”%u”是老表的OID。如果使用者表有名字與這個臨時表相同的,那麼就會失敗。另外臨時表的OID是relfilenode。 這個階段,會對pg_class申請“RowExclusiveLock”鎖,因為需要插入條目;也會做表名檢查,檢查是否與現有表名衝突。
copy資料階段:然後將原來的資料copy到temp表中。對臨時表,老表以及索引都以“AccessExclusiveLock”模式開啟。另外對於toast,只是lock,不開啟。在這個過程中完成Dead Tuple的清理。
swap表階段:最後做一個swap table操作,新表將老表替換掉。交換隻是將物理檔案進行交換。reltablespace和relfilenode進行交換,會對pg_class再次申請“RowExclusiveLock”鎖。
重建索引階段:是在交換之後完成的,重建索引時,會更新一些統計資訊。對錶申請“ShareLock”鎖。
刪除臨時表階段:索引重建完成後,將帶有老物理檔案的新臨時表進行刪除。
2. lazy vacumm
PG在lazy vaccum之前,會先判斷此次vacuum是full scan還是part scan。判斷靠vacuum_freeze_table_age引數,它只與newest xid和relfrozenxid比較,
公式為:relfrozenxid < newestxid - vacuum_freeze_table_age
演變後:vacuum_freeze_table_age < newestxid - relfrozenxid
vacuum_freeze_table_age預設值為150million。因此如果一個表在pg_class中的relfrozenxid比newestxid小150million時,就會觸發全表掃描,完成後更新pg_class中的relfrozenxid。
vacuum_freeze_table_age的最大值是0.95*autovacuum_freeze_max_age。
新的凍結relfroenxid的計算需要靠以下公式的運算結果來判斷:
oldestXmin – vacuum_freeze_min_age
上面公式演變後成: autovacuum_freeze_max_age - vacuum_freeze_min_age < newest xid – oldestXmin
relfrozenxin取值? | 公式成立 | 公式不成立 |
full scan | oldestXmin,說明oldestXmin過老 | oldestXmin-vacuum_freeze_min_age,如果是負值,返回3 |
part scan | 0 | 0 |
從上面可以知道,part scan是不會更新pg_class中的relfrozenxid值的,只有full scan會去更新。原因很簡單,part scan實際上只是清理dead tuple,FSM(Free Space Map)和標記visibility map。
預設情況下,autovacuum_freeze_max_age 的值為200million,vacuum_freeze_min_age 為50million。那也就是說oldest xid與newest xid的差距不能大於150million。
對於一個系統,如果每秒事務量為1W tps,可以支援15000秒,也就是4個小時左右。vacuum_freeze_min_age 的最大值不能超過autovacuum_freeze_max_age/2,也就是100million。
對於multixid的凍結,也是同樣的計算方法,只不過autovacuum_multixact_freeze_max_age的值為400million,
PG用這個方法,完美解決了wraparound 問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30088583/viewspace-1603893/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL的vacuum流程SQL
- 【Postgresql】VACUUM 垃圾回收SQL
- PostgreSQL vacuum可見性SQL
- 新特性:postgresql的vacuum漫談SQL
- PostgreSQL DBA(92) - PG 12 Improving VACUUMSQL
- PostgreSQL VACUUM 之深入淺出 (一)SQL
- PostgreSQL VACUUM 之深入淺出 (二)SQL
- PostgreSQL VACUUM 之深入淺出 (三)SQL
- PostgreSQL DBA(142) - PG 12(Monitoring PostgreSQL VACUUM processes)SQL
- PostgreSQL DBA(143) - pgAdmin(Monitoring PostgreSQL VACUUM processes#2)SQL
- PostgreSQL 原始碼解讀(127)- MVCC#11(vacuum過程-vacuum_rel函式)SQL原始碼MVCC#函式
- PostgreSQL 並行vacuum patch - 暨為什麼需要並行vacuum或分割槽表SQL並行
- PostgreSQL 原始碼解讀(131)- MVCC#15(vacuum過程-lazy_vacuum_heap函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(128)- MVCC#12(vacuum過程-heap_vacuum_rel函式)SQL原始碼MVCC#函式
- postgreSQL 12-2 vacuum-主流程SQL
- 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函式
- Postgresql關於Vacuum的作用和操作方法,Vacuum full鎖表並生成新的relfilenodeSQL
- PostgreSQL DBA(159) - pgAdmin(Allow vacuum command to process indexes in paralleSQLIndex
- 深入淺出VACUUM核心原理(中): index by passIndex
- 第二週-20200306-PostgreSQL13並行vacuum索引SQL並行索引
- 教你使用SQLite VacuumSQLite
- PostgreSQL 原始碼解讀(126)- MVCC#10(vacuum過程)SQL原始碼MVCC#
- PostgreSQL 原始碼解讀(264)- PG 14(Speeding up recovery and VACUUM)SQL原始碼
- openGauss 對錶執行VACUUM
- PostgreSQL 原始碼解讀(125)- MVCC#9(vacuum-主流程)SQL原始碼MVCC#
- postgresql VACUUM 不會從表中刪除死行的三個原因SQL
- PostgreSQL 原始碼解讀(134)- MVCC#18(vacuum過程-HeapTupleSatisfiesVacuum函式)SQL原始碼MVCC#APT函式
- PostgreSQL 原始碼解讀(130)- MVCC#14(vacuum過程-lazy_scan_heap函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(135)- MVCC#19(vacuum過程-heap_execute_freeze_tuple函式)SQL原始碼MVCC#函式
- PostgreSQL14在做vacuum時候的邏輯判斷是否經過HEAPTUPLE_RECENTLY_DEADSQLAPT
- template0 的 age 問題. vacuum template0
- openGauss/MogDB列存表vacuum DELTAMERGE過程申請的鎖
- Postgresql驗證_update、delete產生死亡元組,標準vacuum釋放表檔案磁碟空間的場景SQLdelete
- PG12中新增:VACUUM命令的SKIP_LOCKED選項
- 技術應用丨DWS 空間釋放(vacuum full) 最佳實踐
- 揭秘PostgreSQL:如何查詢表欄位名稱SQL
- PostgreSQL pg_rewind原理SQL