PostgreSQL Cost Based Vacuum探秘
PostgreSQL cost based vacuum的意思就是指每次 vacuum,進行heap scan時,都會基於IO cost進行sleep。如果IO cost越大,總體sleep的時間就會越長。也就是說scan 表,並且清理dead tuple
是斷斷續續的,並不會一次性全vacuum完。這樣子做的原因就是儘量避免對當前DML操作的影響,從而減少因vacuum而對系統IO的壓力。
cost based 有幾個非常重要的引數:
- vacuum_cost_delay : 預設vacuum_cost_delay為20毫秒。 heap scan時,需要sleep的時間。
- vacuum_cost_page_hit :vacuum時,page在buffer中命中時,所花的代價。預設值為1。
- vacuum_cost_page_miss:vacuum時,page不在buffer中,需要從磁碟中讀入時的代價預設為10。
- vacuum_cost_page_dirty:當vacuum時,修改了clean的page。這說明需要額外的IO去刷髒塊到磁碟。預設值為20。
- vacuum_cost_limit:預設為200,單位時間內多個vacuum worker完成vacuum而不被sleep 懲罰的所允許IO最大消耗值。
上面帶有字樣“page”的引數是在readbuffer時,計算的代價。它會及時更新到vacuumCostBalance值中,這個值是每個值的總和。
即:vacuumCostBalance=vacuum_cost_page_hit * x + vacuum_cost_page_miss*Y + vacuum_cost_page_dirty*Z。其中x,y,z為訪問次數。按預設值轉換後為:vacuumCostBalance=1* x + 10*Y + 20*Z。
vacuum_cost_limit有兩個用途:
其一是用來計算每個vacuum worker毫秒級別所允許消耗的最大IO,vacuum_cost_limit/vacuum_cost_dely。也就是說每個worker會平攤掉這個cost值。一句話概括就是所有vacuum worker在vacuum_cost_delay時間段
內所允許消耗的最大IO。當新的vacuum_worker進來進,都會rebalance一把,得到此worker的VacuumCostLimit值。
其二是在cost base模式下,用來控制每次delay的時間。每次delay最小值為vacuum_cost_delay值,最大值為4*vacuum_cost_delay值。判斷依據為VacuumCostBalance / VacuumCostLimit的值是否
大於”4“。大於”4“之後就是4*vacuum_cost_delay。PG設定delay最大值為4倍,就是不希望延遲太長。其實4倍的效果已經是非常明顯了。因為在vacuum過程中需要scan heap,index等,而且delay都是
在block級別的。因此,如果某個表IO很高時,就需要透過調高vacuum_cost_limit值來縮短delay時間,從而減少空間爆增量。
從上面兩點看出,這是一個非常重要的值,如果這個值設定不夠高,也就是說跟當前的系統TPS不匹配的話,那麼導致的結果就是vacuum老是被delay,一個TPS高的表,往往就需要很常的時間來vacuum了。
因此,如果高TPS系統,本人還是建議設定的高些。不然高TPS表,不被及時vacuum完成,而是被delay住,那麼將導致這個表的增長是非常恐怖的,往往會引起效能問題。這個時候變成大表之後,一般vacuum已經不
起作用了,需要vacuum full來處理,而vacuum full是會鎖表的。這會導致對應用嚴重傷害。這個時候有人會跳出來說,vacuum頻率高點可能會影響當前的效能。這個當然會有,在IO上會有爭用。但是這個效能問題,我們
是可能透過其它方式來規避的。比如說應用設計以及資料庫分片技術等。
我們先看一個例子,來分析PG是如何基於IO cost,從而來delay vacuum 的:
從上面,看Deal Tuples為6116,已經超過threshod值1651,所以後面開始vacuuming “public.sbtest1”。
但是總共花了45.64s,才vacuum完成。這個時候的cost_limit值為100。
我調整了cost_limit的值到1000,這個時候,可以看到只用了5.85秒。vacuum速度快多了。
這是為什麼呢?原因就是每次scan tuple時,delay的時間少了。PG在索引,表,visibility map等scan進,都嵌入了vacuum_delay_point()方法。
這使得delay的效果是堆積的。當我改成400後,12.84s。
從上面的例子中,已經完全說明了,為什麼有些高TPS系統,vacuum老是起不了效果。高DML操作表,一直被增大的原因。
另外,autovacuum已經能做到表級並行了。下面三個表位於同一個庫中。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30088583/viewspace-1615226/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL vacuum原理—vacuum揭秘SQL
- PostgreSQL的vacuum流程SQL
- 【Postgresql】VACUUM 垃圾回收SQL
- PostgreSQL vacuum可見性SQL
- PostgreSQL DBA(175) - Cost EST(SeqScan)SQL
- 新特性:postgresql的vacuum漫談SQL
- PostgreSQL VACUUM 之深入淺出 (一)SQL
- PostgreSQL VACUUM 之深入淺出 (二)SQL
- PostgreSQL VACUUM 之深入淺出 (三)SQL
- PostgreSQL vacuum 核心原始碼機理SQL原始碼
- PostgreSQL vacuum原理—啟動機制SQL
- PostgreSQL DBA(142) - PG 12(Monitoring PostgreSQL VACUUM processes)SQL
- PostgreSQL DBA(92) - PG 12 Improving VACUUMSQL
- PostgreSQL vacuum原理一功能與引數SQL
- 【MOS】Limitations of the Oracle Cost Based Optimizer (文件 ID 212809.1)MITOracle
- PostgreSQL DBA(143) - pgAdmin(Monitoring PostgreSQL VACUUM processes#2)SQL
- postgreSQL 12-2 vacuum-主流程SQL
- PostgreSQL 並行vacuum patch - 暨為什麼需要並行vacuum或分割槽表SQL並行
- 深入淺出Calcite與SQL CBO(Cost-Based Optimizer)優化SQL優化
- PostgreSQL 原始碼解讀(127)- MVCC#11(vacuum過程-vacuum_rel函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(131)- MVCC#15(vacuum過程-lazy_vacuum_heap函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(132)- MVCC#16(vacuum過程-lazy_vacuum_index函式#1)SQL原始碼MVCC#Index函式
- Postgresql關於Vacuum的作用和操作方法,Vacuum full鎖表並生成新的relfilenodeSQL
- PostgreSQL 原始碼解讀(128)- MVCC#12(vacuum過程-heap_vacuum_rel函式)SQL原始碼MVCC#函式
- PostgreSQL 原始碼解讀(133)- MVCC#17(vacuum過程-lazy_vacuum_index函式#2)SQL原始碼MVCC#Index函式
- PostgreSQL 原始碼解讀(129)- MVCC#13(vacuum過程-vacuum_set_xid_limits函式)SQL原始碼MVCC#MIT函式
- PostgreSQL DBA(159) - pgAdmin(Allow vacuum command to process indexes in paralleSQLIndex
- PostgreSQL 原始碼解讀(264)- PG 14(Speeding up recovery and VACUUM)SQL原始碼
- PostgreSQL 原始碼解讀(126)- MVCC#10(vacuum過程)SQL原始碼MVCC#
- postgresql VACUUM 不會從表中刪除死行的三個原因SQL
- PostgreSQL 原始碼解讀(134)- MVCC#18(vacuum過程-HeapTupleSatisfiesVacuum函式)SQL原始碼MVCC#APT函式
- PostgreSQL 原始碼解讀(125)- MVCC#9(vacuum-主流程)SQL原始碼MVCC#
- 教你使用SQLite VacuumSQLite
- PostgreSQL 原始碼解讀(130)- MVCC#14(vacuum過程-lazy_scan_heap函式)SQL原始碼MVCC#函式
- 第二週-20200306-PostgreSQL13並行vacuum索引SQL並行索引
- PostgreSQL14在做vacuum時候的邏輯判斷是否經過HEAPTUPLE_RECENTLY_DEADSQLAPT
- cost量化分析
- 表連線cost