改變資料頁大小能帶來多少收益?

資料庫工作筆記發表於2023-12-13

來源:PostgreSQL學徒

前言

今天下午④群有位群友問了這樣一個問題,關於 pgbackrest 的

各位大佬,請教個問題,pgbackrest是隻支援8k的block size嗎?還是編譯的時候需要指定引數才可以支援其他大小的block size。我用block size 32k pg16.1 的庫做測試,報下面的錯誤

改變資料頁大小能帶來多少收益?

可以看到,pgbackrest提示了一個很清晰的報錯:page size is 32768 but must be 8192,即當前資料庫的塊大小是32KB,但是pgbackrest要求必須是8KB,關於這個限制我之前還真沒注意過,於是下來去找了一下資料,也特意編譯了一下,發現還真的不支援修改塊大小,這是個硬限制,必須是8KB的資料塊

並且官方的回覆也很耐人尋味,不打算支援不同的頁面大小,因為沒有經過大量測試,並且需要重新編譯才能修改,並且,增大頁面大小可能並不如想象中的那麼有益。總而言之,pgbackrest官方不會考慮支援不同的頁大小,這就和PostgreSQL不支援hint並且永遠打不算支援hint有點異曲同工之妙了。

那不妨讓我們思考一下,為什麼pgbackrest官方會認為不同的頁大小並不是那麼重要?油管上面 tomas vondra 做了一篇名為 Postgres vs. page sizes 的分享,聽完之後,受益匪淺,也讓我有了更多的思考。讓我們隨著作者的思緒一起聽一下這篇分享。

Postgres vs. page sizes

頁結構

前面主要介紹了 PostgreSQL 讀取資料頁的大致流程

改變資料頁大小能帶來多少收益?

預設8KB的頁面,表/索引等資料庫物件,以及WAL在底層儲存上都是按照8KB的頁面進行劃分。但是由於一 IO會經過層層關卡,並且由於使用的是Buffer IO,還會涉及到作業系統頁快取 (此處做了簡化,沒有去考慮什麼驅動層、IO排程層這些東西)。

改變資料頁大小能帶來多少收益?

可以看到,PostgreSQL雖然預設使用8KB的頁面,並且由於是Buffer IO,那麼以x86為例,page cache和檔案系統通常預設是4KB,然後就是儲存層,老式HDD扇區通常是512位元組,新一點的可能是4KB。SSD的話會更加複雜一點,通常在4KB ~ 16KB。因此整個IO流程就變得有點複雜了,一個資料頁可能對映到多個檔案系統頁,而每個檔案系統頁又可能對映到多個儲存"頁",這也側面導致了"放大",WAL的機制類似,但相對要簡單一點,因為都是順序寫。

SSD vs. HDD

作者也特意介紹了一下SSD和HDD的區別,因為這對後文的測試也很重要。

改變資料頁大小能帶來多少收益?

HDD使用磁碟,即磁性介質作為資料儲存介質,在資料讀取和寫入上,使用磁頭+馬達的方式進行機械定址。因為機械硬碟靠機械驅動讀寫資料的限制,導致機械硬碟的效能提升遇到了瓶頸,特別是隨機讀寫能力。SSD使用Flash作為儲存介質,資料讀取寫入透過SSD控制器進行定址,不需要機械操作,有著優秀的隨機訪問能力。

改變資料頁大小能帶來多少收益?

與HDD不同的是,SSD總是將資料寫入新位置(Program),同時不斷擦除(Erase)老資料,完全擦寫一次可以稱為1次P/E,因此SSD的壽命以P/E為單位。page是單次讀寫單位,大小一般為4KB ~ 16KB,寫操作只能寫到空的page,而擦除是以塊為單位,塊通常是64~128個page,塊的擦除次數有壽命限制,超過限制就會變成壞塊。

SSD通常都有較大的DRAM快取,

PostgreSQL總是重新寫入整個資料頁,使得所有"對映"的SSD頁面失效,導致"放大"問題

資料的反覆修改會產生大量的無效頁,一旦整個塊的空間不足以寫入資料,SSD會將這個塊的資料讀入到快取中,擦除這個塊中的頁,然後再把快取中已更新的資料寫入進去。這種 read-erase-modify-write過程,就好比寫入的資料可能只有一個頁4KB,但實際要擦除並且寫N個頁,稱之為寫入放大。就好比你寫一張紙需要耗費一張紙,你寫一行字也會浪費一張草稿紙,這就是寫入放大的一個主要原因。

修改塊大小

改變資料頁大小能帶來多少收益?

要修改塊大小,我們需要在編譯的時候修改,並且一經編譯,無法動態修改,磁碟上的資料佈局與記憶體中的資料表示完全一致。頁面及其元組按原樣讀入緩衝區快取中,無需任何轉換。這也是為什麼資料檔案在不同平臺之間不相容的原因,當然還有可能的原因便是位元組序、大小端以及對齊的問題。

  1. 資料頁大小最小支援1KB,最大32KB
  2. WAL頁大小最小支援1KB,最大64KB

修改很容易,但是代價卻不菲,就比如此例中,改了之後你的pgbackrest就擺爛了,其次每個小版本怎麼辦?另外,AFAIK,CI/CD測試也是預設使用的8KB大小,如果修改了,那麼意味著你也要再做一遍測試。其次就是那些外掛?那些備份工具?那些上下游生態元件等等?是否都會有影響?這些都是你要考慮的點。

OLTP

改變資料頁大小能帶來多少收益?

tomas vondra 為了驗證不同的塊大小會對效能產生怎樣的效能影響,進行了詳盡的測試。他的機器規格如上,一臺64GB記憶體,280GB NVME,另一臺是8GB記憶體,100GB SATA (RAID)。

按照以往我們的既定思維,小的資料塊適合OLTP,大的資料塊適合OLAP,比如Greenplum預設資料塊就是32KB。對於WAL的話,大的資料塊可能更有效(順序寫)。

改變資料頁大小能帶來多少收益?

OLTP使用pgbench進行測試,主要調整不同的scalefactor以控制資料集大小,資料集也分為三種情況:

  1. 小的資料集適合shared buffers
  2. 中等資料集適合記憶體
  3. 大資料集超過記憶體,也就意味著page cache無法全部快取,可能需要進行I/O

改變資料頁大小能帶來多少收益?

小資料集

X軸是資料塊大小,Y軸是WAL的塊大小,左側是read-only測試結果,右側是read-write測試結果,顏色越綠代表結果越好,TPS越高,顏色越紅代表結果越差,TPS越低。

改變資料頁大小能帶來多少收益?

以8KB的預設引數作為基準資料 (因為大多數情況下我們使用的都是該配置),然後對比不同的資料塊和WAL塊大小的效能(以百分比顯式)。

改變資料頁大小能帶來多少收益?

改變資料頁大小能帶來多少收益?

如果 >100 意味著TPS更高,<100意味著TPS更低。

結果表明,對於小資料集沒有太大差異。對於read-write來說,情況類似,使用大的WAL頁面顯然並沒有好處,吞吐量下降了10% ~ 20%。

中等資料集

中等資料集,對於read-write,1~4KB的資料頁,大概有10%的效能提升,越大的資料頁會有下降,當32KB的時候,下降約35%。

改變資料頁大小能帶來多少收益?

而對於WAL的頁大小,影響就要低一點,32 ~ 64KB要稍慢一點。

大資料集

改變資料頁大小能帶來多少收益?

對於超過記憶體的大資料集與中等資料集的結果類似,但是效果更加明顯。1 ~ 4KB的頁大小,對於read-write大約可以提升50%左右,這個是個很可觀的數字,對於read-only,也有20%左右的效能提升。但是較大的WAL頁面帶來的好處並不明顯。

FPI 的影響

接下來是每個事務產生的WAL大小,可以看到,對於越小的資料塊,產生的WAL量越小,不難理解,資料頁越小,那麼由於FPI記錄的整頁大小也就越小,WAL的量也隨之越小。大資料集的行為也是類似,越小的資料塊,WAL的量大約可以減小20%~30%左右。

改變資料頁大小能帶來多少收益?

作者也測試了一下,將full_page_write設為off之後,基線從42K的TPS提升到了58K,提升也很可觀,如果改為4KB,也是從57K提升到了70K。

改變資料頁大小能帶來多少收益?

SATA

X軸是請求的大小 (size of request in kilobytes),Y軸是IOPS。

對於SSD,請求大小和IOPS的對比會非常明顯,右側的圖顯式:請求大小越大,IOPS越小,因此具體儲存的行為和訪問資料的方式都至關重要。

改變資料頁大小能帶來多少收益?

如果是SATA,結果類似,4KB大約提升40%(read-only 提升30%左右)。

改變資料頁大小能帶來多少收益?

結論

  1. 對於至強處理器,對於小的資料塊,2~4KB,提升大約50%;WAL的塊大小無關緊要
  2. 對於i5處理器,對於小的資料塊,2~4KB,提升大約40%;小的WAL塊大小表現要好點

改變資料頁大小能帶來多少收益?

OLAP

OLAP採用TPC-H 模型,不過作者只執行了初始資料載入和查詢,沒有進行任何資料重新整理等操作。

資料載入

資料載入包括COPY,建立PK/FK/INDEXs,VACUUM等,此處的指標是耗時時長。

改變資料頁大小能帶來多少收益?

可以看到,資料塊越大,耗時越少,8KB和32KB大約20%左右的差距。WAL塊大小也是類似,越大,時間也少,但相較於資料塊的影響就要小得多。

動作拆解

改變資料頁大小能帶來多少收益?

將5個動作拆解開之後,行為類似,1KB的效能最差,大資料塊效能越好。但是外來鍵有個例外,32KB時有個尖刺。

查詢

改變資料頁大小能帶來多少收益?

查詢是跑完每組查詢的總耗時,2~16KB的資料類似,但是為1KB和32KB的差距這麼明顯?

QUERY 17

改變資料頁大小能帶來多少收益?

隨著資料塊的增大,耗時逐漸降低,在16KB的時候,達到最佳狀態,32KB的效果並沒有8KB的好。

QUERY 8

改變資料頁大小能帶來多少收益?

QUERY 8表現不同

QUERY 7&9

改變資料頁大小能帶來多少收益?

7和9就表現更奇葩了,時好時壞,作者的解釋是

更大的頁面意味著更少的頁面數量,從而導致不同的成本估算。這可能是成本模型的一個限制或問題,只是簡單地使用seq_page_cost和random_page_cost,而不考慮頁面大小。此外,查詢中的不同操作可能對頁面大小的敏感度不同,並在不同的頁面大小下“切換”。

查詢計劃與資料塊大小之間有這明顯的相關性,更大的頁面意味著更少的頁面數量,從而導致不同的成本估算。

改變資料頁大小能帶來多少收益?

改變資料頁大小能帶來多少收益?

結論

改變資料頁大小能帶來多少收益?

改變資料頁大小能帶來多少收益?

最終結論

  1. 不同的頁大小對於效能可能會產生可觀的影響
  2. WAL的頁大小影響並不大
  3. 對於OLTP類的應用,小資料頁更佳 (SSD)
  4. 對於OLAP類的應用,越大的資料頁和WAL頁大小,載入越快
  5. 對於OLAP類的查詢,則較難調整,需要根據實際情況和測試資料,相應調整

改變資料頁大小能帶來多少收益?

小結

確實,最佳化器只考慮了隨機IO和順序IO的比值,而沒有考慮資料塊的大小,比如FPI,資料塊的大小就會有顯著影響;其次,不同儲存之間的行為差異等等,另外,資料塊越大,意味著資料頁越少,那麼進而影響到relpages,影響到執行計劃的選擇 (cost的計算)等等,再者,統計資訊的收集是基於取樣演算法,預設是3W個資料塊裡取3W行資料來進行取樣,資料塊的多少也影響到資料統計資訊的採集,如果有4W個,則取樣3W個,如果29000個,則全部採集...

改變資料頁大小能帶來多少收益?

但是,一個大致可行的想法是:越大的資料塊對於批次操作有益,但是不利於隨機操作。TP場景下,對於SSD,預設4KB的頁大小,可以考慮將PostgreSQL的blocksize設定為4KB,HDD也可以考慮設定為4KB。

參考


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027826/viewspace-2999905/,如需轉載,請註明出處,否則將追究法律責任。

相關文章