【PostgreSQL】PostgreSQL 15移除了Stats Collector

2022-08-29 06:01:41

試用即將發行的PostgreSQL 15的人會發現少了一個後臺程序:​

postgres    1710       1  0 04:03 ?        00:00:00 /usr/pgsql-15/bin/postmaster -D /var/lib/pgsql/15/data/
postgres    1711    1710  0 04:03 ?        00:00:00 postgres: logger 
postgres    1712    1710  0 04:03 ?        00:00:00 postgres: checkpointer 
postgres    1713    1710  0 04:03 ?        00:00:00 postgres: background writer 
postgres    1715    1710  0 04:03 ?        00:00:00 postgres: walwriter 
postgres    1716    1710  0 04:03 ?        00:00:00 postgres: autovacuum launcher 
postgres    1717    1710  0 04:03 ?        00:00:00 postgres: logical replication launcher 

來和PostgreSQL 14比較一下:​

postgres    1751       1  0 04:04 ?        00:00:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
postgres    1752    1751  0 04:04 ?        00:00:00 postgres: logger 
postgres    1754    1751  0 04:04 ?        00:00:00 postgres: checkpointer 
postgres    1755    1751  0 04:04 ?        00:00:00 postgres: background writer 
postgres    1756    1751  0 04:04 ?        00:00:00 postgres: walwriter 
postgres    1757    1751  0 04:04 ?        00:00:00 postgres: autovacuum launcher 
postgres    1758    1751  0 04:04 ?        00:00:00 postgres: stats collector 
postgres    1759    1751  0 04:04 ?        00:00:00 postgres: logical replication launcher 

是的,stats collector程序沒有了。但是去掉這個程序是個好事,一個主要的瓶頸和令人頭疼的問題永遠消失了。

 

stats collector的工作內容是什麼?

新手使用者可能想知道它是什麼以及為什麼PG 14和更早版本需要它。至少會有一些使用者對用於查詢計劃的表級統計資訊的收集(ANALYZE)感到困惑。但這是不同的。PostgreSQL跟蹤每個程序的所有活動以獲得累積統計資訊,例如掃描表或索引的次數,或者最後一次vacuum或autovacuum在表上執行的時間,或者autovacuum在表上執行的次數等。所有stats collector收集的資料可通過不同的pg_stat_*檢視獲得。

 

問題點

由於對談的每個後端都是PostgreSQL中的一個單獨程序,因此收集統計資訊並傳輸並不是一件容易的事。每個後端將有關他們所做的活動的資訊傳送到單個"stats collector"程序。

這種通訊過去是通過UDP通訊端進行的。這種方法有很多問題,這不是一個可延伸的模型。

使用者經常報告不同型別的問題,例如:過時的統計資訊、stats collector未執行、autovacuum無法運作/啟動等。

 

如果stats collector在特定機器上出現問題,過去真的很難理解出了什麼問題。

 

"stats collector"的另一個不利影響是它引起的IO。如果啟用DEBUG級別2,可能會看到不斷出現在PostgreSQL紀錄檔中的訊息,例如:​

2022-08-22 03:49:57.153 UTC [736] DEBUG:  received inquiry for database 0
2022-08-22 03:49:57.153 UTC [736] DEBUG:  writing stats file "pg_stat_tmp/global.stat"
2022-08-22 03:49:57.153 UTC [736] DEBUG:  writing stats file "pg_stat_tmp/db_0.stat"
2022-08-22 03:49:57.168 UTC [1278] DEBUG:  autovacuum: processing database "postgres"
2022-08-22 03:49:57.168 UTC [736] DEBUG:  received inquiry for database 13881
2022-08-22 03:49:57.168 UTC [736] DEBUG:  writing stats file "pg_stat_tmp/global.stat"
2022-08-22 03:49:57.168 UTC [736] DEBUG:  writing stats file "pg_stat_tmp/db_13881.stat"
2022-08-22 03:49:57.169 UTC [736] DEBUG:  writing stats file "pg_stat_tmp/db_0.stat"

這可能會導致資料目錄所在的掛載點產生大量IO。這是引數stats_temp_directory的值所指向的地方。在許多系統上,它將是資料目錄中的pg_stat_tmp。

 

在Ubuntu/Debian上,它將位於/var/run/postgresql中,例如:​

postgres=# show stats_temp_directory ;
          stats_temp_directory           
-----------------------------------------
 /var/run/postgresql/14-main.pg_stat_tmp
(1 row)
 

PostgreSQL 15中的新特性

開始使用動態共用記憶體來收集統計資訊,而不再使用檔案和檔案系統。

 

以前,統計收集器通過UDP接收統計更新,並通過定期將統計資料寫入臨時檔案來共用統計資料。這些檔案可以達到數十兆位元組,並且每秒最多寫入兩次。這會阻止我們新增其他有用的統計資料。

 

現在統計資訊儲存在共用記憶體中。可變編號物件的統計資訊儲存在dshash雜湊表中(由動態共用記憶體支援)。固定編號的統計資訊儲存在普通共用記憶體中。

 

pgstat.c的標頭檔案包含該架構的概述。

 

不再需要統計資訊收集器,將其刪除。

 

現在副本刪除了已刪除物件的統計條目,從完全關閉的副本啟動時不再需要重置統計資訊。

 

顯然,引數stats_temp_directory不見了。因此,我們不需要pg_stat_tmp目錄,該目錄是在資料目錄(或其他位置)中,在該目錄生成和讀取所有統計檔案。然而,仍保留此目錄是因為不會破壞許多依賴於該目錄的擴充套件,例如pg_stat_statements。

在載入擴充套件庫之前,目錄保持為空。例如,如果我們載入pg_stat_statements庫,目錄中會出現一個檔案。​

$ ls pg_stat_tmp/
pgss_query_texts.stat

當然,擴充套件不是免費的,他們也有對應的成本。

 

在新架構中,大多數統計更新首先在每個程序中本地累積為"pending"(每個backend都有一個backend本地雜湊表)。"pending"是指它們已累積但尚未提交到共用統計系統(shared stats system)。之後會在提交或超時後重新整理到共用記憶體。

 

由於統計資料會在有人嘗試讀取時同時被更新,因此讀取一致性就出現了。因此PostgreSQL 15引入了一個新引數:stats_fetch_consistency,它可以取三個值none、cache 或snapshot​:

·"none"是最有效的。但是,將不會提供讀取一致性。但對於大多數使用來說應該沒問題。 

·"cache"確保重複存取產生相同的值,這對於涉及例如自連線(self-joins)是有必要的.

·"snapshot"在互動式檢查統計資訊時很有用,但開銷更大。

預設為"cache"

 

如果是在共用記憶體中,重啟後如何保持呢?

在被shutdown之前,檢查點程序會將這些統計資訊寫入檔案系統,重啟後可以再次被載入。通常,如果是crash了,統計資訊就丟失了。

 

這一改動是否會影響我的監控/指令碼?

監控檢視pg_stat_*會繼續起作用。但是,要確保取得是stats_fetch_consistency的恰當的值。如上所述,pg_stat_tmp目錄只是為擴充套件保留的。

 

其它

很多人像我一樣,使用postgresql的等待事件來理解postgresql以及對談都把時間花費在哪的人。資料收集和分析工具,比如pg_gather,通過使用等待事件來分析問題。

 

​為了更好地監控postgresql,三個新的等待事件被引入了:

·PgStatsDSA:等待統計動態共用記憶體分配器存取

·PgStatsHash:等待stats共用記憶體雜湊表存取

·PgStatsData:等待共用記憶體統計資料存取

 

隨著統計收集器的所有開銷及其維護的消失,其他子系統(如 autovacuum)要做的工作就更少了。

 

此外,經常查詢統計資訊的監控工具預計會大大減少系統負載。