本文介紹了堆表預讀、堆表預擴充以及索引建立預擴充的簡介、原理以及使用方法等。
前提條件
支援的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(核心小版本14.5.1.0及以上)
PostgreSQL 11(核心小版本1.1.1及以上)
您可通過如下語句查看PolarDB PostgreSQL版的核心小版本的版本號碼:
PostgreSQL 14
select version();
PostgreSQL 11
show polar_version;
背景資訊
PolarDB PostgreSQL版底層使用PolarFS(以下簡稱為PFS)作為檔案系統。不同於 ext4 等單機檔案系統,PFS在頁擴充過程中,中繼資料更新開銷較大。且PFS的最小頁擴充粒度為4 MB。而PostgreSQL 8 KB的頁擴充粒度並不適合PFS,將會導致寫表或建立索引時效能下降。同時,PFS在讀取大塊頁面時I/O效率更高。
為了適配上述特徵,PolarDB PostgreSQL版設計了堆表預讀、堆表預擴充、索引建立預擴充的功能,使運行在PFS上的PolarDB PostgreSQL版能夠獲得更好的效能。
簡介
堆表預讀
在PostgreSQL讀取堆表的過程中,會以8 KB頁為單位通過檔案系統讀取頁面至記憶體緩衝池(Buffer Pool)中。PFS對於這種資料量較小的I/O操作並不是特別高效。因此,PolarDB PostgreSQL版為了適配PFS而設計了堆表批量預讀。
當讀取的頁數量大於1時,將會觸發批量預讀,一次I/O讀取128 KB資料至緩衝池中。預讀對順序掃描(Sequential Scan)、Vacuum兩種情境效能可以帶來一倍左右的提升,在索引建立情境下可以帶來18%的效能提升。
堆表預擴充
在PostgreSQL中,資料表空間的擴充過程中將會逐個申請並擴充8 KB的頁。即使是PostgreSQL支援的批量頁擴充,進行一次N頁擴充的流程中也包含了N次I/O操作。這種頁擴充不符合PFS最小頁擴充粒度為4 MB的特性。因此,PolarDB PostgreSQL版設計了堆表批量預擴充。
在擴充堆表的過程中,一次I/O擴充4 MB頁。在寫表頻繁的情境下(例如裝載資料),能夠帶來一倍的效能提升。
索引建立預擴充
索引建立預擴充與堆表預擴充的功能類似。索引建立預擴充特別針對PFS最佳化索引建立過程。在索引建立的頁擴充過程中,一次I/O擴充4 MB頁。這種設計可以在建立索引的過程中帶來30%的效能提升。
說明當前索引建立預擴充只適配了B-Tree索引。其他索引類型暫不支援。
原理介紹
堆表預讀
堆表預讀的實現步驟主要分為以下四步:
在Buffer Pool中申請N個Buffer。
通過
palloc
在記憶體中申請一段大小為N*頁大小
的空間,簡稱為p
。通過PFS批量讀取堆表中
N * 頁大小
的資料拷貝至p
中。將
p
中N個頁的內容逐個拷貝至從Buffer Pool申請的N個Buffer中。
後續的讀取操作會直接命中Buffer。資料流圖如下所示:
堆表預擴充
預擴充的實現步驟主要分為以下三步:
從Buffer Pool中申請N個Buffer,不觸發檔案系統的頁擴充。
通過PFS的檔案寫入介面進行批量頁擴充,並且寫入為全零頁。
對申請出來的頁逐個進行頁初始化,標識頁的可用空間,結束預擴充。
索引建立預擴充
索引建立預擴充的實現步驟與預擴充類似,但沒有涉及Buffer的申請。步驟如下:
寫索引頁時,通過PFS的檔案寫入介面進行批量頁擴充,並且寫入為全零頁。
將Buffer Pool中已經構建好的索引頁寫入檔案系統中。
使用指南
堆表預讀
堆表預讀的參數名為
polar_bulk_read_size
,功能預設開啟,預設大小為128 KB。說明不建議使用者自行修改該參數,128 KB是貼合PFS的最優值,自行調整並不會帶來效能的提升。
關閉堆表預讀功能。
ALTER SYSTEM SET polar_bulk_read_size = 0; SELECT pg_reload_conf();
開啟堆表預讀功能並設定預讀大小為128 KB。
ALTER SYSTEM SET polar_bulk_read_size = '128 KB'; SELECT pg_reload_conf();
堆表預擴充
堆表預擴充的參數名為
polar_bulk_extend_size
,功能預設開啟,預擴充的大小預設是4 MB。說明不建議使用者自行修改該參數值,4 MB是貼合PFS的最優值。
關閉堆表預擴充功能。
ALTER SYSTEM SET polar_bulk_extend_size = 0; SELECT pg_reload_conf();
開啟堆表預擴充功能並設定預擴充大小為4 MB。
ALTER SYSTEM SET polar_bulk_extend_size = '4 MB'; SELECT pg_reload_conf();
索引建立預擴充
索引建立預擴充的參數名為
polar_index_create_bulk_extend_size
,功能預設開啟。索引建立預擴充的大小預設是4 MB。說明不建議使用者自行修改該參數值,4 MB是貼合PFS的最優值。
關閉索引建立預擴充功能。
ALTER SYSTEM SET polar_index_create_bulk_extend_size = 0; SELECT pg_reload_conf();
開啟索引建立預擴充功能並設定預擴充大小為4 MB。
ALTER SYSTEM SET polar_index_create_bulk_extend_size = '4 MB'; SELECT pg_reload_conf();
效能對比
為了展示堆表預讀、堆表預擴充、索引建立預擴充的效能提升效果,在PostgreSQL 14版本的PolarDB PostgreSQL版叢集上進行了測試。
規格:8核32 GB記憶體。
測試情境:400 GB pgbench測試。
堆表預讀
400 GB表的Vacuum效能對比如下所示:
400 GB表的SeqScan效能對比如下所示:
結論:
堆表預讀在Vacuum和SeqScan情境下效能提升了1-2倍。
堆表預讀大小在超過預設值128 KB之後對效能提升沒有明顯協助。
堆表預擴充
400 GB表資料裝載效能對比如下所示:
結論:
堆表預擴充在資料裝載情境下帶來一倍的效能提升。
堆表預擴充大小在超過預設值4 MB後對效能沒有明顯協助。
索引建立預擴充
400 GB表建立索引效能對比如下所示:
結論:
索引建立預擴充在索引建立情境下能夠帶來30%的效能提升。
索引建立預擴充大小超過預設值4 MB對效能沒有明顯協助。