PostgreSQLのチェックポイント実行契機
はじめに
これは、 PostgreSQL Advent Calendar 2023 シリーズ1の12日目の記事です。
今回は、業務でチェックポインタプロセスのソースコードを読むことがあったので、チェックポイントがいつ実行されるかについて調べました。
半分はみんながよく知ってること、半分は知らなくても特に問題ないこと、なのでたぶんこの記事はあまり役に立たないと思います・・・
チェックポイントとは?
まずおさらいしておきましょう。ググってみるとITパスポートの勉強サイトが出てきました。このサイトによるとチェックポイントは以下のようです。
データベースにおいてトランザクションの更新情報が、ディスク上のデータベースに反映されるタイミングのこと。
チェックポイントという用語はITパスポートにも出題されるみたいですね。知らなかった。
PostgreSQL的に言うと、共有バッファ上のダーティなページをディスクに書き出す処理のことになります。チェックポイント処理の一部といってよいかはわかりませんが、不必要になったWALの削除やリサイクルもチェックポイントのタイミングで実行されます。
詳しくは色々な記事があるので、それらを参考にするのがいいと思います。
- https://qiita.com/U_ikki/items/89b1eea657e47120e3ee
- https://www.ashisuto.co.jp/db_blog/article/20161004_checkpoint_tuning.html
調査方法
調査環境
- PostgreSQL 16.1
チェックポイントのログを見たいので、log_checkpoints=on
にしておきましょう。
方法
src/backend/access/transam/xlog.c
にCreateCheckPoint
という関数があり、この関数を呼び出すことでチェックポイントが実行されます。これ呼び出している部分の実装やコメントを読んだり、ドキュメントを読んだりして調査しました。
ちなみに、CreateCheckPoint
は以下になります。
チェックポイントの実行契機
簡単にチェックポイントの実行契機を3つに分類しました。
- 時間とWALファイルサイズ
- PostgreSQLの起動・停止
- SQLコマンド
それぞれ見ていきましょう。
時間とWALファイルサイズ
これが一番初めに思い浮かぶのではないでしょうか。
PostgreSQLのチェックポインタプロセスは、以下の条件のどちらかが満たされるとチェックポイントを開始します。
- 前回のチェックポイントから
checkpoint_timeout
(デフォルト5分)時間が経過する。 - 前回のチェックポイントから
max_wal_size
(デフォルト1GB)サイズのWALが生成される。
ただし、前回のチェックポイント以降書き出すWALがない場合はチェックポイントはスキップされます。
PostgreSQLの起動・停止
起動
通常起動の場合はチェックポイントは実行されませんが、リカバリが走る場合はチェックポイントが実行されます。
- リカバリ中:
checkpoint_timeout
時間が経過している、またはmax_wal_size
サイズ以上のWALファイルをリカバリしている場合にチェックポイントが実行される(リカバリ中のチェックポイントをリスタートポイントと呼ぶらしい)。ただし、リプレイした最後のチェックポイントがリスタートポイントである場合は実行されない。 - リカバリ完了時(スタンバイからの昇格):一貫性のために必須ではないが、最後のリスタートポイントがかなり前になってしまうのを避けるためにチェックポイントが実行される。リカバリ完了のレコードを作成した後、リカバリモードから抜けてSQLを受け付けるようになった後でチェックポイントが実行される。(これをオンラインチェックポイントらしい)
- リカバリ完了時(スタンバイからの昇格以外):リカバリした内容をディスクへフラッシュするため、チェックポイントが実行される。
停止
PostgreSQLを停止するときにチェックポイントが実行されます。ただし、以下の停止のときのみで、即時シャットダウンのときはチェックポイントは実行されません。
- スマートシャットダウン(
pg_ctl stop -m smart
) - 高速シャットダウン(
pg_ctl stop -m fast
)
SQLコマンド
CHECKPOINT
当たり前ですが、CHECKPOINT
コマンドを実行するとチェックポイントが実行されます。
SELECT pg_backup_start(label => 'label', fast => true)
これは低レベルAPIを使用したベースバックアップを作成するときに、バックアップを開始する関数です。2番目の引数にtrue
を渡すかfalse
を渡すかでチェックポイントの挙動が変わります。
-
true
:即時にチェックポイントが要求されます。 -
false
:次にスケジュールされたチェックポイントが完了するまで待機します。
CREATE DATABASE
CREATE DATABASE name WITH STRATEGY = strategy
でデータベース作成時の手法を指定できます。以下の2種類があり、FILE_COPY
が指定された場合にデータベース作成前後でチェックポイントが実行されます。
strategy | 説明 |
---|---|
WAL_LOG |
デフォルト。ブロックごとにコピーされ、各ブロックがWALに書かれる。 |
FILE_COPY |
ファイルシステムレベルでディレクトリ全体がコピーされる。 |
チェックポイントを実行する必要がある理由は以下の通りです。
- データベース作成前:コピー元のデータベース(テンプレートデータベース)への変更をディスクへフラッシュし、データベースがディスク上で最新であることを保証するため。
- データベース作成後:ディレクトリコピーが再実行されないことを保証するため。
これにドキュメントにも記載されています。
DROP DATABASE
以下の流れでチェックポイントが実行されます。
- 共有バッファ上にある削除対象のデータベースのページを削除する。
- 削除対象のデータベースのファイルに対するfsync要求とリンク解除要求をキャンセルするようにチェックポインタプロセスに伝える。
- 2によって送信されたメッセージをチェックポインタプロセスが受信したことを確認するためにチェックポイントを実行する。
このような作業を行わないと、削除されたデータベースのページをフラッシュするようなことが起こります。そして、同じOIDをもつ新しいデータベースが作成されていた場合には上書きされてしまいます。
ALTER DATABASE SET TABLESPACE
ALTER DATABASE SET TABLESPACE
コマンドが実行される前後でチェックポイントが実行されます。これは、CREATE DATABSE
と同様に説明することができます。
- データベース変更前:コピー元のデータベースへの変更をディスクへフラッシュし、データベースがディスク上で最新であることを保証するため。
- データベース変更後:ディレクトリコピーが再実行されないことを保証するため。
DROP TABLESPACE
DROP TABLESPACE
を実行するとき、ディレクトリが空でないとテーブルスペースを削除できません。しかし、テーブルスペースにファイルが残存する場合があります。例えば、DROP TABLE
の実行によって、次のチェックポイントで削除するようにスケジュールされた空のファイルが残っている可能性があります。そのファイルを消してよいかどうかをチェックするためにチェックポイントを強制的に実行し、空ファイルを削除します。
まとめ
PostgreSQLのチェックポイント実行契機を調べてみました。
特にSQLコマンドの部分は今まであまり意識したことがなかったですが、確かにチェックポイント必要だなとわかり、勉強になりました。
間違っていることを書いているかもしれませんので、有識者のコメントお待ちしています!
おまけ
NTTデータグループのSlideShareの発表資料を以下にまとめています。今年の資料だけで20件を超えました。ぜひご覧ください!
Discussion