pg_jitter是一個輕量級的PostgreSQL JIT編譯提供者,新增三種替代JIT後端——sljit、AsmJit和MIR,能在PostgreSQL 14至18版本中提供更快的編譯速度及具競爭力的查詢執行效能。

Postgres於2018年在11版本引入JIT編譯,解決了必須在執行時解譯表達式並使用效率低下的逐行迴圈來進行內部資料轉換(所謂的tuple deforming)問題。對於表達式密集的工作負載或寬表,JIT能顯著提升這些操作的效能。然而,標準的基於LLVM的JIT編譯速度非常慢,編譯時間可能達數十至數百毫秒,這使得它僅適合非常重的OLAP型查詢。在典型的OLTP查詢中,LLVM的JIT開銷甚至可能超過查詢本身的執行時間。pg_jitter則提供微秒級的本地代碼生成編譯時間,取代毫秒級,讓JIT適用於更廣泛的查詢。

實際上,JIT編譯的效應更廣泛——即使是sljit,執行速度也可能因冷快取及記憶體壓力增加(與代碼生成和JIT編譯相關的快速分配/釋放)而減慢約1毫秒。因此,在每秒執行大量查詢的系統中,建議避免對非常快速的查詢(如點查詢或僅處理少量記錄的查詢)使用JIT編譯。預設的jit_above_cost參數設為非常高的數值(100,000),這對LLVM合理,但對更快的提供者不合適。建議根據所用後端及工作負載,將此參數設為約200至數千。

pg_jitter在某些操作上的優化遠勝於典型表達式。

在/tests資料夾中有多個腳本可執行不同類型的基準測試。

在0.3.0版本中,新增了更多基準測試:

TPC-C與TPC-H的數據較低,因為它們是單次執行,而其他三種是連續執行。若持續執行TPC-C/TPC-H查詢,效能會更佳。

目前的原始碼可視為測試版,通過所有支援平台的Postgres標準回歸測試,並在效能測試中展現良好提升,也成功通過約700萬個SqlLogicTest測試案例,但尚未進行大規模生產驗證,敬請期待。

對於MIR和sljit,請使用MIR-patched和SLJIT-patched的修補版本,這些版本包含多項錯誤修正、額外SIMD指令及記憶體管理改進。

所有參數均可由使用者設定(會話中SET,永久設定用ALTER SYSTEM),除非另有說明,設定後無需重啟即可生效。

這些參數僅在pg_jitter.backend設為'auto'時生效,選擇特定後端時不會收集統計資料。

以下為控制何時觸發JIT編譯的PostgreSQL標準參數:

pg_jitter實作了PostgreSQL的JitProviderCallbacks介面。當PostgreSQL決定JIT編譯查詢時,會呼叫compile_expr():

元提供者(jit_provider = 'pg_jitter')是一個輕量的調度器:

每個後端仍可獨立使用,只需將jit_provider直接設為'pg_jitter_sljit'即可。

JIT編譯的代碼與PostgreSQL的ResourceOwner系統綁定:

單一程式碼庫透過src/pg_jitter_compat.h中的編譯時# if PG_VERSION_NUM條件,支援PostgreSQL 14至18版本,處理關鍵差異:

原生預編譯blob管線已移除。小型葉節點函式由Tier 0發射器或一般Tier 1直接呼叫處理。不可安全重寫的傳址操作,始終使用PostgreSQL內建函式的C封裝。

每次提交至主分支時,均會針對所有支援平台與Postgres版本組合(共20組合)執行完整Postgres回歸測試(pg_regress)。分支提交則僅針對單一版本(PG17)執行。以下為最近一次主分支測試狀態。

異常平台的回歸測試在每次提交至主分支時於Travis CI執行。狀態如下:

Linux/PPC64與FreeBSD/x86_64版本針對所有支援Postgres版本執行,Linux/s390x版本僅針對PG14與PG16執行。