Article
Lua統合パッチでpsqlはどこまで拡張できる? VACUUM進捗表示の仕組み
psqlにLuaを組み込み、利用者定義の処理を実行できる実験パッチが公開されました。VACUUMラッパーを題材に、二つの接続で実行と監視を分ける仕組み、進捗値の読み方、試す前の互換性を整理します。
Share
こはるの読みどころ
読みどころはLuaの文法ではなく、psqlを小さな運用コンソールへ変える設計です。実験パッチと正式機能を切り分けながら、今の運用にも応用できる監視の考え方を追います。

PostgreSQLの端末クライアントpsqlにLuaを埋め込み、利用者が処理を関数として持ち込める実験パッチが、2026年8月29日に公開されました。題材は、VACUUMを表ごとに実行しながら進捗を読みやすく表示するラッパーです。
気になるのは、Luaが動くこと自体よりも、実行中のSQLを待ちながら同じ端末で別のSQLをどう流すのか、という点ではないでしょうか。長い保守処理を見守るには、psqlのスクリプト機能だけでは見えにくかった接続管理が表に出てきます。
このパッチがpsqlをどう変えようとしているのか、VACUUMラッパーがなぜ二つの接続を使うのか、そして現時点でどこまで実用として扱えるのかを順に追います。
Luaからpsqlの処理を関数として組み立てる
現行のpsqlは、SQLを対話的に実行するだけでなく、バックスラッシュで始まるメタコマンド、変数、条件分岐などを備えたスクリプト環境です。PostgreSQL 18のpsql公式ドキュメントも、管理や自動化を支える端末フロントエンドとして位置づけています。
今回の実験リポジトリは、そこへ\luacode、\luafile、\lua、\luasetなどを加えます。LuaからSQLを実行し、結果を走査し、psqlの表示機能を呼び、独自のバックスラッシュコマンドまで登録することが狙いです。
2026年8月6日の初期デモは、\luacodeで関数を定義して呼び出す小さな例でした。今回のVACUUMラッパーでは、ファイルに置いた関数を次のように読み込み、引数付きで実行するところまで進んでいます。
\luafile ~/vacuum.lua
\lua vacuum {verbose=true}
つまり、psql内でSQLとLuaを往復できるだけでなく、複数クエリ、整形、待機処理を一つの操作へまとめる方向が見えてきたわけですね。
VACUUMの実行用接続と進捗監視用接続を分ける
VACUUMラッパーの核心は、データベース接続を二系統に分けることです。Lua関数は対象表を集めた後、現在の接続設定を複製した接続でVACUUMを送り、そのバックエンドPIDを記録します。
psqlとLua
├─ 複製した接続: VACUUMを非同期実行
└─ 現在の接続: 対象PIDの進捗ビューを定期取得
一つのPostgreSQL接続は、実行中のコマンドを処理している間に別の監視クエリを同時実行できません。そこで保守処理を担当する接続と、pg_stat_progress_vacuumを読む接続を分けます。これは単なる実装都合ではなく、実行と観測を両立させるための構造です。
待機側ではsendquery、consumeinput、isbusy、getresultに相当する操作を組み合わせます。libpqの非同期コマンド処理では、クエリ送信後に入力を消費してbusy状態を調べ、結果がそろってから繰り返し取得する流れが定義されています。Luaが担っているのは、この状態遷移をpsql内で読みやすく記述する部分です。
pg_stat_progress_vacuumの数値は全体の完了率ではない
pg_stat_progress_vacuumには、通常のVACUUMを実行中のバックエンドごとに一行が現れます。進捗レポートの公式仕様では、phase、heap_blks_total、heap_blks_scanned、indexes_total、indexes_processedなどの意味が定義されています。
たとえばheap_blks_scannedが800万、heap_blks_totalが1000万なら、ヒープ走査フェーズでは80%まで進んだと読めます。ただし、その後にインデックスのvacuum、ヒープのvacuum、切り詰め、最終処理が続く場合があります。80%はジョブ全体の完了率ではありません。
indexes_totalとindexes_processedも、インデックス処理のフェーズに入ってから意味を持つ値です。またVACUUM FULLの進捗はpg_stat_progress_vacuumではなくpg_stat_progress_clusterに出ます。画面へ出す列を増やすだけではなく、フェーズに応じて値の意味を切り替える必要があると分かります。
この進捗ビュー自体はPostgreSQL 9.6で追加されました。一方、サンプルが表示するindexes_totalとindexes_processedはPostgreSQL 17で追加された列です。古いサーバへ接続して試す場合は、Lua対応クライアントをビルドできるかだけでなく、監視SQLの列互換性も切り分けたいところです。
LuaラッパーはVACUUMの権限や負荷を変えない
Luaが処理を包んでも、VACUUMそのものの規則は変わりません。VACUUMの公式仕様どおり、対象表には通常MAINTAIN権限が必要で、トランザクションブロック内では実行できず、I/O負荷がほかのセッションへ影響する可能性があります。
運用へ近づけるなら、少なくとも次の三点はラッパー側で詰める必要があります。
- 対象表の選択: サンプルの
pg_class.relkind条件はr、s、nですが、現行のpg_class仕様では通常表がr、マテリアライズドビューがm、パーティション表がp、シーケンスが大文字のSです。自分の対象範囲に合わせて見直す必要があります。 - 引数の扱い: サンプルは
load("return " .. args)でオプションを評価します。信頼できない文字列を渡す入口にはせず、受け付けるキーと値を限定したいところです。 - 非同期結果の回収: libpqは、同じ接続で
PQgetResultがnullを返すまで次のPQsendQueryを送れないと定めています。サンプルのverbose分岐にある連続したsendqueryは、戻り値とエラーを含めて検証が必要です。
PostgreSQL masterをLua付きでビルドして試す段階
リポジトリは、このコードをPostgreSQL masterブランチ向けの実験パッチと説明しています。ビルド手順も、配布済みpsqlへ後から追加する拡張ではなく、Luaを有効にしてPostgreSQL本体をコンパイルする形です。
./configure --with-lua
make all
sudo make install
標準搭載済みの機能や、安定したプラグインAPIとして扱う段階ではありません。上流でのレビュー状況、採用対象バージョン、API互換性は公開資料から確定できないため、既存の管理端末を置き換えず、隔離したビルドと検証用クラスタで確認するのが妥当です。
それでも、試作が示した方向は具体的です。既存psqlの変数や固定メタコマンドで十分な処理はそのまま保ち、繰り返し、整形、複数接続の制御が必要な対話的ワークフローだけをLuaへ寄せる、という境界を考えられます。
psqlを小さな運用コンソールにする設計が見えてきた
冒頭の問いへの答えは、Luaによってpsqlがすぐ万能の自動化基盤になる、ではありません。このパッチが見せたのは、psqlの接続・クエリ・表示機能をスクリプト言語へ公開すると、日常の管理操作を利用者定義のコマンドへまとめられる可能性です。
VACUUMの例から今すぐ持ち帰れるのは、実行と監視を別接続へ分け、進捗値をフェーズ単位で読む設計です。Lua統合を採用する判断はまだ先でも、この二点は外部スクリプトや既存の運用ツールにもそのまま応用できます。
出典
- Title: Pavel Stehule: Integration Lua to psql III
- URL: https://postgr.es/p/9tw
Share
Related Articles
カテゴリやタグが近い記事を続けて読めるように並べています。




