全部產品
Search
文件中心

PolarDB:全域執行計畫緩衝

更新時間:Jul 06, 2024

本文介紹了PolarDB PostgreSQL版的全域執行計畫緩衝(Global Plan Cache)功能。

背景資訊

在之前的PolarDB中,執行計畫緩衝(Plan Cache)是和Prepared Statement進行綁定的,這種做法存在以下兩個問題:

  • 每個串連的Plan Cache是獨立的,無法共用。

  • 每個串連都會緩衝一份Plan Cache,導致記憶體佔用較多。

PolarDB PostgreSQL版引入了全域執行計畫緩衝(簡稱GPC)功能,通過讓不同的串連共用同一份Plan Cache來解決以上兩個問題。

Plan可以在不同的Prepared Statement、串連之間共用。對於有大量不同SQL的應用程式,GPC可以大大降低記憶體的使用量,減少OOM(Out of Memory)的風險。 此外更高效的Plan Cache機制減少了產生執行計畫的代價,因此效能也有所提升。

Plan共用的前提是它們的Query Key是一致的,Query Key組成包括以下幾部分:

  • 查詢文本。

  • 資料庫標識號。

  • 對象搜尋路徑。

  • 使用者ID。

前提條件

  • PolarDB PostgreSQL版叢集預設開啟GPC功能。

  • 支援的PolarDB PostgreSQL版的版本如下:

    • PostgreSQL 11(核心小版本1.1.28及以上)

    • PostgreSQL 14(核心小版本14.9.15.0及以上)

    說明

    您可通過如下語句查看PolarDB PostgreSQL版的核心小版本的版本號碼:

    • PostgreSQL 11

      show polar_version;
    • PostgreSQL 14

      select version();

使用限制

  • 僅支援Prepared Statement形式的查詢,即不支援PL/SQL情境下的Plan Cache。

  • 僅支援SELECTINSERTUPDATEDELETE語句。

  • 不支援暫存資料表。

參數說明

參數

說明

polar_gpc_mem

用於設定存放GPC的記憶體大小。單位:MB。預設值為30 MB,取值不超過shared_buffer的數量。

說明
  • 參數修改後需要重啟叢集才會生效。

  • polar_gpc_mem小於等於0時,表示關閉GPC功能;polar_gpc_mem大於0時,叢集在啟動時會預留此時設定的共用記憶體。當共用記憶體不足時,新的Plan Cache會暫時存放到本地。當不經常使用或者失效的GPC被清理以後,會釋放出共用記憶體空間,之後本地的Plan Cache會嘗試移動到GPC中。

polar_enable_gpc_level

GPC功能的開啟層級,允許動態修改。取值如下:

  • 0(預設):表示不使用GPC。

  • 1:表示僅在唯讀節點(RO)上使用GPC。

  • 2:表示在主節點(RW)和唯讀節點上都使用GPC。

說明
  • 該參數必須與polar_gpc_mem配合使用,只有 polar_gpc_mem大於0且polar_enable_gpc_level大於0時,GPC才能正常工作。

  • 如果polar_gpc_mem大於0, 而polar_enable_gpc_level等於0,那麼已經使用了GPC的查詢可以繼續使用,但是新的查詢不會繼續使用GPC。

polar_gpc_clean_timeout

清理不經常用GPC的時間間隔,可以動態修改,單位:秒。預設值為1800s,取值範圍為0~24小時之間的數值。

polar_worker.gpc_clear_interval

清理失效GPC的時間間隔,可以動態修改,單位:秒。預設值為60秒,最大允許設定為 (2^32 - 1)/1000。

polar_gpc_clean_max

一次清理的GPC數量,可以動態修改。預設值為100,取值範圍為10~10000之間的數值。

polar_gpc_partitions

用於儲存GPC的雜湊表數量。預設值為32,取值範圍為1~1024之間的數值。

說明

參數修改後需要重啟才會生效。

polar_gpc_entries

每個雜湊表中的最大條目數量。預設值為1024,取值範圍為1~10000之間的數值。

說明

參數修改後需要重啟才會生效。

使用指南

polar_stat_gpc

通過polar_stat_gpc視圖可以查看GPC的整體使用狀況。使用方法如下:

SELECT * FROM polar_stat_gpc;

polar_stat_gpc視圖中主要指標如下:

  • get:嘗試匹配GPC的次數。

  • hit:成功匹配到GPC的次數。

  • store:GPC儲存成功的次數。

  • store_failed:因為暫時的GPC記憶體不足導致的儲存失敗次數。如果該值經常上升,說明polar_gpc_mem設定小了。

  • store_exists:嘗試將Local Plan Cache添加到GPC時,發現其他Session已經寫入該Plan的次數。

polar_gpc_plan

通過polar_gpc_plan視圖可以查看每一個GPC佔用的記憶體情況。使用方法如下:

SELECT * FROM polar_gpc_plan;

polar_gpc_plan視圖中主要指標如下:

  • plan_id:執行計畫的ID。

  • stmt_name:Prepared Statement的名稱。

  • query:查詢語句。

  • used_cnt:該計劃被使用的次數。

  • last_use_time:上次使用該GPC的時間。

  • is_valid:計劃是否有效。

polar_gpc_plan_mcxt

通過polar_gpc_plan_mcxt視圖可以查看每一個GPC的MemoryContext資訊。使用方法如下:

SELECT * FROM polar_gpc_plan_mcxt;

polar_gpc_plan_mcxt視圖中主要指標如下:

  • plan_id:執行計畫的ID。

  • mcxt_name:MemoryContext的名稱。

  • totalspace:總共的記憶體空間。

  • freespace:剩餘的記憶體空間。

  • used:使用的內容空間。

  • nblocks:block的數量。

polar_gpc_plan_key

通過polar_gpc_plan_key視圖可以查看每個GPC的GPC Key(用於匹配GPC的鍵)。使用方法如下:

SELECT * FROM polar_gpc_plan_key;

polar_gpc_plan_key視圖中主要指標如下:

  • plan_id:計劃的ID。

  • query:查詢語句。

  • dbid:資料庫的ID。

  • pid:進程號。

  • num_params:查詢語句的參數個數。

  • search_path:搜尋路徑。

  • role_id:使用者ID。

polar_prepared_statement

通過polar_prepared_statement視圖可以查看GPC中所有的Prepared Statement資訊。使用方法如下:

SELECT * FROM polar_prepared_statement;

polar_prepared_statement視圖中主要指標如下:

  • is_saved:Prepared Statement的執行計畫是否儲存到了GPC。

  • is_valid:計劃是否有效。

  • cacheable:計劃是否可以緩衝。

polar_gpc_evict_invalid_gpc

通過polar_gpc_evict_invalid_gpc函數可以手動清理已經失效的GPC。使用方法如下:

SELECT polar_gpc_evict_invalid_gpc();

如果不手動調用該函數,系統預設每隔$polar_worker.gpc_clear_interval秒自動清理一次失效的GPC。

polar_gpc_evict_live_gpc

通過polar_gpc_evict_live_gpc函數可以手動淘汰一些最近不常用的GPC。使用方法如下:

SELECT polar_gpc_evict_live_gpc(); 

如果不手動調用該函數,系統預設每隔$polar_worker.gpc_clear_interval秒自動淘汰不常用的GPC。