LoginSignup
3
0

More than 1 year has passed since last update.

PG16:Summary function for pg_buffercache

Last updated at Posted at 2022-12-08

はじめに

にゃーん。趣味でポスグレをやっている者だ。

この記事はPostgreSQL 16 全部ぬこ Advent Calendar 2022 9日目の記事です。

今回はcontribモジュールpgbuffercacheにPostgreSQL 16で入った新規関数について書いてみます。

概要

項目 内容
タイトル PG16:Summary function for pg_buffercache
Topic Monitoring & Control
ステータス commited
Last Modified 2022-10-13
概要 contrib/pg_buffercacheに
サマリ情報を返却する関数
pg_buffercache_summary()が追加された

変更内容

pg_buffercacheとは

pg_bufferchacheはPostgreSQLの共有バッファの内容をモニタリングするための拡張機能(contribモジュール)です。
この拡張機能は、PostgreSQL 8.3からサポートされている結構歴史のあるものです。
参考:PostgreSQL 14文書のpg_buffercacheのページ

現状の問題

PostgreSQL 15までは、pg_buffercharでキャッシュ全体の傾向(dirtyページがどのくらいあるか等)を取得しようとすると、
pg_buffercacheによってキャッシュページを全スキャンした結果を集約するクエリを書く必要がありました。

最近はハードウェアのスペックも上がり、共有バッファに大きなサイズを割り当てることも多いと思います。
そうした環境だと、ppg_buffercacheの結果を集約するコストはけっこう高くなります。
定期的にそうした監視を行うのであれば、その辺りのコストは下げたいもの。

pg_buffercache_summary関数

ということで、PostgreSQL 16から、pg_byffercahceの内容をサマライズした結果を出力するpg_buffercache_summary関数が追加されました。

この関数は引数なしで実行し、以下の5つ列をもつ1行のレコードを返却します。

列名 意味
buffers_used integer 有効なrelfilenodeを持つバッファの数(ダーティと非ダーティの両方)
buffers_unused integer 無効なrelfilenodeを持つバッファの数
buffers_dirty integer ダーティバッファの数
buffers_pinned integer バックエンドを少なくとも1つピン留めしているバッファの数
usagecount_avg double precision 使用済みバッファの平均使用量

実行結果はこんな感じになります。

=# \x
Expanded display is on.
=# SELECT * FROM pg_buffercache_summary();
-[ RECORD 1 ]--+------------------
buffers_used   | 4278
buffers_unused | 12106
buffers_dirty  | 2072
buffers_pinned | 0
usagecount_avg | 1.548153342683497

=#

この関数を使用しない場合には、以下のような集約クエリで同等の結果を得ることができます。

=# SELECT relfilenode <> 0 AS is_valid, isdirty, count(*) FROM
pg_buffercache GROUP BY relfilenode <> 0, isdirty;
 is_valid | isdirty | count
----------+---------+-------
 t        | f       |  2206
          |         | 12106
 t        | t       |  2072
(3 rows)

=#
  • 1行目と3行目を加算したものが、buffers_used
  • 2行目がbuffers_unused
  • 3行目がbuffers_dirty
    に相当してますね。
    また、このクエリだとbufferd_pinnedusagecount_avgに相当する情報は出力されません。それらを取得するためには別のクエリが必要になるようです。

検証

では、pg_bufferchacheの結果を集約したクエリと、pg_buffercache_summary()の実行時間を雑に比較してみます。

  • shared_buffersを64MB, 128MB, 256MBに変更して、PostgrerSQLサーバを起動する。
  • 起動直後に、pgbenchの初期化(Scalefactor=100)を実行する。
    • pgbench --unlogged-table -i -s 100
  • pgbench実行直後に、\timingオプションをつけてpg_buffercacheを集約したクエリと、pg_buffercache_summary()を実行し処理時間を測定する。
shared_buffers pg_buffercache集約 pg_buffercache_summary
64MB 4.949 0.561
128MB 8.432 0.691
256MB 15.033 0.827

こうかはばつぐんですね。
検証した環境だと、shared_buffersにそれほど大きな値が設定できないので、集約関数を使ってもそれほど処理時間はかからないのですが、それでも、pg_buffercache_summary()を使う方が圧倒的に高速に処理できることがわかりました。

ハイスペックで数百GBのhared_buffersを設定可能な環境だと、pg_buffercache_summary()の恩恵は大きなものになりそうです。

おわりに

今回はpg_buffercache拡張機能に追加されたサマリを取得する関数について説明しました。
この関数を使ったバッファ監視の運用などを考えてみるのも面白いかもしれません。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0