全局執(zhí)行計(jì)劃緩存
本文介紹了PolarDB PostgreSQL版(兼容Oracle)的全局執(zhí)行計(jì)劃緩存(Global Plan Cache)功能。
背景信息
在之前的PolarDB中,執(zhí)行計(jì)劃緩存(Plan Cache)是和Prepared Statement進(jìn)行綁定的,這種做法存在以下兩個(gè)問題:
每個(gè)連接的Plan Cache是獨(dú)立的,無(wú)法共享。
每個(gè)連接都會(huì)緩存一份Plan Cache,導(dǎo)致內(nèi)存占用較多。
PolarDB PostgreSQL版(兼容Oracle)引入了全局執(zhí)行計(jì)劃緩存(簡(jiǎn)稱GPC)功能,通過讓不同的連接共享同一份Plan Cache來(lái)解決以上兩個(gè)問題。
Plan可以在不同的Prepared Statement、連接之間共享。對(duì)于有大量不同SQL的應(yīng)用程序,GPC可以大大降低內(nèi)存的使用量,減少OOM(Out of Memory)的風(fēng)險(xiǎn)。 此外更高效的Plan Cache機(jī)制減少了生成執(zhí)行計(jì)劃的代價(jià),因此性能也有所提升。
Plan共享的前提是它們的Query Key是一致的,Query Key組成包括以下幾部分:
查詢文本。
數(shù)據(jù)庫(kù)標(biāo)識(shí)號(hào)。
對(duì)象搜索路徑。
用戶ID。
前提條件
PolarDB PostgreSQL版(兼容Oracle)集群默認(rèn)開啟GPC功能。
支持的PolarDB PostgreSQL版(兼容Oracle)的版本如下:
Oracle 2.0(內(nèi)核小版本2.0.14.15.0及以上)
說(shuō)明您可通過如下語(yǔ)句查看PolarDB PostgreSQL版(兼容Oracle)的內(nèi)核小版本的版本號(hào):
SHOW polar_version;
使用限制
僅支持Prepared Statement形式的查詢,即不支持PL/SQL場(chǎng)景下的Plan Cache。
僅支持
SELECT
、INSERT
、UPDATE
、DELETE
語(yǔ)句。不支持臨時(shí)表。
參數(shù)說(shuō)明
參數(shù) | 說(shuō)明 |
polar_gpc_mem | 用于設(shè)置存放GPC的內(nèi)存大小。單位:MB。默認(rèn)值為30 MB,取值不超過shared_buffer的數(shù)量。 說(shuō)明
|
polar_enable_gpc_level | GPC功能的開啟級(jí)別,允許動(dòng)態(tài)修改。取值如下:
說(shuō)明
|
polar_gpc_clean_timeout | 清理不經(jīng)常用GPC的時(shí)間間隔,可以動(dòng)態(tài)修改,單位:秒。默認(rèn)值為1800s,取值范圍為0~24小時(shí)之間的數(shù)值。 |
polar_worker.gpc_clear_interval | 清理失效GPC的時(shí)間間隔,可以動(dòng)態(tài)修改,單位:秒。默認(rèn)值為60秒,最大允許設(shè)置為 (2^32 - 1)/1000。 |
polar_gpc_clean_max | 一次清理的GPC數(shù)量,可以動(dòng)態(tài)修改。默認(rèn)值為100,取值范圍為10~10000之間的數(shù)值。 |
polar_gpc_partitions | 用于保存GPC的哈希表數(shù)量。默認(rèn)值為32,取值范圍為1~1024之間的數(shù)值。 說(shuō)明 參數(shù)修改后需要重啟才能生效。 |
polar_gpc_entries | 每個(gè)哈希表中的最大條目數(shù)量。默認(rèn)值為1024,取值范圍為1~10000之間的數(shù)值。 說(shuō)明 參數(shù)修改后需要重啟才能生效。 |
使用指南
polar_stat_gpc
通過polar_stat_gpc視圖可以查看GPC的整體使用狀況。使用方法如下:
SELECT * FROM polar_stat_gpc;
polar_stat_gpc視圖中主要指標(biāo)如下:
get:嘗試匹配GPC的次數(shù)。
hit:成功匹配到GPC的次數(shù)。
store:GPC保存成功的次數(shù)。
store_failed:因?yàn)闀簳r(shí)的GPC內(nèi)存不足導(dǎo)致的保存失敗次數(shù)。如果該值經(jīng)常上升,說(shuō)明polar_gpc_mem設(shè)置小了。
store_exists:嘗試將Local Plan Cache添加到GPC時(shí),發(fā)現(xiàn)其他Session已經(jīng)寫入該P(yáng)lan的次數(shù)。
polar_gpc_plan
通過polar_gpc_plan視圖可以查看每一個(gè)GPC占用的內(nèi)存情況。使用方法如下:
SELECT * FROM polar_gpc_plan;
polar_gpc_plan視圖中主要指標(biāo)如下:
plan_id:執(zhí)行計(jì)劃的ID。
stmt_name:Prepared Statement的名稱。
query:查詢語(yǔ)句。
used_cnt:該計(jì)劃被使用的次數(shù)。
last_use_time:上次使用該GPC的時(shí)間。
is_valid:計(jì)劃是否有效。
polar_gpc_plan_mcxt
通過polar_gpc_plan_mcxt視圖可以查看每一個(gè)GPC的MemoryContext信息。使用方法如下:
SELECT * FROM polar_gpc_plan_mcxt;
polar_gpc_plan_mcxt視圖中主要指標(biāo)如下:
plan_id:執(zhí)行計(jì)劃的ID。
mcxt_name:MemoryContext的名稱。
totalspace:總共的內(nèi)存空間。
freespace:剩余的內(nèi)存空間。
used:使用的內(nèi)容空間。
nblocks:block的數(shù)量。
polar_gpc_plan_key
通過polar_gpc_plan_key視圖可以查看每個(gè)GPC的GPC Key(用于匹配GPC的鍵)。使用方法如下:
SELECT * FROM polar_gpc_plan_key;
polar_gpc_plan_key視圖中主要指標(biāo)如下:
plan_id:計(jì)劃的ID。
query:查詢語(yǔ)句。
dbid:數(shù)據(jù)庫(kù)的ID。
pid:進(jìn)程號(hào)。
num_params:查詢語(yǔ)句的參數(shù)個(gè)數(shù)。
search_path:搜索路徑。
role_id:用戶ID。
polar_prepared_statement
通過polar_prepared_statement視圖可以查看GPC中所有的Prepared Statement信息。使用方法如下:
SELECT * FROM polar_prepared_statement;
polar_prepared_statement視圖中主要指標(biāo)如下:
is_saved:Prepared Statement的執(zhí)行計(jì)劃是否保存到了GPC。
is_valid:計(jì)劃是否有效。
cacheable:計(jì)劃是否可以緩存。
polar_gpc_evict_invalid_gpc
通過polar_gpc_evict_invalid_gpc函數(shù)可以手動(dòng)清理已經(jīng)失效的GPC。使用方法如下:
SELECT polar_gpc_evict_invalid_gpc();
如果不手動(dòng)調(diào)用該函數(shù),系統(tǒng)默認(rèn)每隔$polar_worker.gpc_clear_interval
秒自動(dòng)清理一次失效的GPC。
polar_gpc_evict_live_gpc
通過polar_gpc_evict_live_gpc函數(shù)可以手動(dòng)淘汰一些最近不常用的GPC。使用方法如下:
SELECT polar_gpc_evict_live_gpc();
如果不手動(dòng)調(diào)用該函數(shù),系統(tǒng)默認(rèn)每隔$polar_worker.gpc_clear_interval
秒自動(dòng)淘汰不常用的GPC。