全部產品
Search
文件中心

PolarDB:預讀和預擴充

更新時間:Jul 06, 2024

本文介紹了堆表預讀、堆表預擴充以及索引建立預擴充的簡介、原理以及使用方法等。

前提條件

支援的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索引。其他索引類型暫不支援。

原理介紹

  • 堆表預讀

    堆表預讀的實現步驟主要分為以下四步:

    1. 在Buffer Pool中申請N個Buffer。

    2. 通過palloc在記憶體中申請一段大小為N*頁大小的空間,簡稱為p

    3. 通過PFS批量讀取堆表中N * 頁大小的資料拷貝至p中。

    4. p中N個頁的內容逐個拷貝至從Buffer Pool申請的N個Buffer中。

    後續的讀取操作會直接命中Buffer。資料流圖如下所示:堆表預讀

  • 堆表預擴充

    預擴充的實現步驟主要分為以下三步:

    1. 從Buffer Pool中申請N個Buffer,不觸發檔案系統的頁擴充。

    2. 通過PFS的檔案寫入介面進行批量頁擴充,並且寫入為全零頁。

    3. 對申請出來的頁逐個進行頁初始化,標識頁的可用空間,結束預擴充。

  • 索引建立預擴充

    索引建立預擴充的實現步驟與預擴充類似,但沒有涉及Buffer的申請。步驟如下:

    1. 寫索引頁時,通過PFS的檔案寫入介面進行批量頁擴充,並且寫入為全零頁。

    2. 將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效能對比如下所示:vacuum效能對比

    • 400 GB表的SeqScan效能對比如下所示:seqscan效能對比

    結論:

    • 堆表預讀在Vacuum和SeqScan情境下效能提升了1-2倍。

    • 堆表預讀大小在超過預設值128 KB之後對效能提升沒有明顯協助。

  • 堆表預擴充

    400 GB表資料裝載效能對比如下所示:資料裝載效能對比

    結論:

    • 堆表預擴充在資料裝載情境下帶來一倍的效能提升。

    • 堆表預擴充大小在超過預設值4 MB後對效能沒有明顯協助。

  • 索引建立預擴充

    400 GB表建立索引效能對比如下所示:建立索引效能對比

    結論:

    • 索引建立預擴充在索引建立情境下能夠帶來30%的效能提升。

    • 索引建立預擴充大小超過預設值4 MB對效能沒有明顯協助。