チェックポイントは、書き込みの多いPostgreSQLインストールの大きな障害になる可能性があります。この分野の問題を特定するための最初のステップは、問題が発生する頻度を監視することです。これにより、最近データベースに追加された使いやすいインターフェイスが利用できるようになりました。
チェックポイントは、データベースがメモリにキャッシュしているすべてのものがディスクと同期されていることを確認するために実行する定期的なメンテナンス操作です。アイデアは、1つを完了したら、データベースの先行書き込みログに配置された古いエントリについて心配する必要をなくすことができるということです。これは、クラッシュ後の回復にかかる時間が短縮されることを意味します。
チェックポイントの問題は、チェックポイントを完了するには、データベースのバッファキャッシュ内の変更されたデータのすべてのビットをディスクに書き込む必要があるため、非常に集中的になる可能性があることです。 PostgreSQL 8.3には、チェックポイントのオーバーヘッドをより適切に監視し、アクティビティを長期間にわたって分散させることでオーバーヘッドを下げることができる機能がいくつか追加されました。チェックポイントとバックグラウンドライターと呼ばれるこれらの変更についての長い記事を書きましたが、何が変更されたかを説明していますが、かなり乾燥した読み物です。
おそらく知りたいのは、本番システムでチェックポイントを監視する方法と、伝える方法です。それらがあまりにも頻繁に起こっている場合。状況は改善されましたが、現在のPostgreSQLバージョンでも、ディスクI/Oが非常に重くなる「チェックポイントスパイク」が発生する可能性があります。また、デフォルトの構成が、パフォーマンスではなく、ディスク容量が非常に少なく、クラッシュリカバリが高速になるように調整されていることは役に立ちません。チェックポイントが発生する頻度に関する1つの入力であるcheckpoint_segmentsパラメータは、デフォルトで3に設定されています。これにより、わずか48MBの書き込み後にチェックポイントが強制されます。
チェックポイントの頻度は2つの方法で確認できます。 log_checkpointsをオンにして、ログで何が起こるかを監視できます。 pg_stat_bgwriterビューを使用することもできます。このビューでは、チェックポイント(時間の経過と書き込みの発生)の2つのソースのそれぞれのカウントと、それらが行った作業量に関する統計が表示されます。
これを簡単にするための主な問題は、最近まで、pg_stat_bgwriter内のカウンターをリセットすることは不可能でした。つまり、タイムスタンプが付いたスナップショットを作成し、しばらく待ってから別のスナップショットを作成し、すべての値を差し引いて、データから有用な統計を導き出す必要があります。それは苦痛です。
私がそれを簡単にするためにパッチを書いたのに十分な苦痛です。データベースの現在の開発バージョンでは、pg_stat_reset_shared(‘bgwriter’)を呼び出して、これらすべての値を再び0に戻すことができます。これにより、PostgreSQLで一般的だった方法に従うことができます。 8.3より前は、オンにできるstats_reset_on_server_startという名前のパラメータがありました。これにより、サーバーを起動するたびにサーバーのすべての内部統計がリセットされます。つまり、便利なpg_postmaster_start_time()関数を呼び出して、現在の時刻と比較し、システムで使用可能な統計の操作/秒に関して常に正確なカウントを得ることができます。
これはまだ自動ではありませんが、現在は自動ではありません。これらの共有部分をリセットすることは可能であり、自分で行うことができます。最初の鍵は、統計のクリアをサーバーの起動シーケンスに統合することです。このようなスクリプトは機能します:
pg_ctl start -l $PGLOG -w
psql -c "select pg_stat_reset();"
psql -c "select pg_stat_reset_shared('bgwriter');"
そこにあるstartコマンドの「-w」に注意してください。これにより、pg_ctlはサーバーの起動が終了するまで待機してから戻ります。これは、サーバーに対してステートメントをすぐに実行する場合に不可欠です。
これで、サーバーの開始時間は、バックグラウンドライターの統計情報が収集を開始したときと基本的に同じになり、次の楽しいクエリを使用できるようになります。
SELECT
total_checkpoints,
seconds_since_start / total_checkpoints / 60 AS minutes_between_checkpoints
FROM
(SELECT
EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time())) AS seconds_since_start,
(checkpoints_timed+checkpoints_req) AS total_checkpoints
FROM pg_stat_bgwriter
) AS sub;
また、システムでチェックポイントが発生している正確な頻度の簡単なレポートを取得します。出力は次のようになります:
total_checkpoints | 9
minutes_between_checkpoints | 3.82999310740741
この情報を使用して行うことは、平均的な時間間隔を凝視し、それが速すぎるように見えるかどうかを確認することです。通常、チェックポイントは5分ごとに発生するようにします。ビジー状態のシステムでは、追いつくためにチェックポイントを10分以上にプッシュする必要がある場合があります。この例では、3.8分ごとが速すぎる可能性があります。これは、checkpoint_segmentsを高くする必要があるシステムです。
この手法を使用してチェックポイント間隔を測定すると、checkpoint_segmentsパラメーターとcheckpoint_timeoutパラメーターを順番に増やす必要があるかどうかがわかります。その目標を達成するために。今すぐ手動で数値を計算できます。9.0が出荷されたら、サーバーが再起動するたびに統計情報が消えてもかまわない限り、完全に自動化することを検討できます。
他にも興味深い方法がいくつかあります。バックグラウンドライターがpg_stat_bgwriterで提供するデータを分析しますが、今日はすべてのトリックを提供するつもりはありません。