今回のチューニング
これまでの2回のチューニングでは、共有バッファとトランザクションログバッファの調整を取り上げました。この2つのチューニング項目は PostgreSQLのディスクI/Oを減らすために重要な役割を果たしています。そのため、これらの設定を適切に調整してあげることで性能を大きく改善 (16クライアント時で48tpsから90tps)できました。
さて今回は、PostgreSQL 8.0から導入された「ライタープロセス」を取り上げたいと思います。
ダーティページとは
PostgreSQLでは共有バッファをディスクキャッシュとして使っています。このためデー タの更新は共有バッファ上で行われるのみで、すぐにはハードディスクに書き込まれません。ですがこれは後で必ず書き込まなければならないデータです。共有 バッファは「ページ」という8Kバイトの単位で管理されており、後でハードディスクに書き込まなければならないページのことを特に「ダーティページ」と呼 びます。
ダーティページの扱われ方
ダーティページは更新が行われるデータベースサーバであれば常に存在し、徐々に増えていくものです。ですがダーディページはいつか必ずハードディスクに書き込まれます。では、いったいいつ書き込まれるのでしょうか?
書き込みのタイミングは2つあります。
1つは共有バッファが足りなくなった場合です。PostgreSQLエンジンがハードディスク上のデータベースのある部分へアクセスを必要としたとします。するとPostgreSQLエンジンはその部分を共有バッファに読み込もうとします。
ですがここで共有バッファのすべてが他のデータで埋まっていて空きがなかったとします。もちろんこのままでは読み込む場所がありませんので、 PostgreSQLエンジンは読み込みに先立って、共有バッファ中で再びアクセスされる可能性が最も少ないと思われるページを1つ選び出し、そのページ が持っているデータを捨てることで空きを作るのです。ただし選び出したページがダーティページだったなら、捨てる前にハードディスクに書き出します。これ が1つ目の書き込みのタイミングです。
もう1つの書き込みのタイミングはチェックポイントの時です。チェックポイントとは、共有バッファ上の全ダーティページをハードディスクに書き込む処理のことです。
PostgreSQLでは共有バッファ上のダーティページをすぐにハードディスクに書き込むことはせず、代わりにトランザクションログを随時ハードディスクに書き込んで障害時のデータの信頼性を確保していることは前回説明しました。
ですがこのままだとトランザクションログが貯まる一方ですから、どこかでトランザクションログを削除できるタイミングを作らないといけません。それがチェックポイントなのです。
トランザクションログは未書き込みのデータを復元するためにリカバリで用いられますが、チェックポイントによってダーティページをすべてハードディ スクに書き出せば未書き込みのデータもなくなり、それ以前のトランザクションログが不要になり削除できるようになります。
このようにチェックポイントでは、ダーティページの書き出しと同時に不要なトランザクションログの削除も行っているのです。ちなみにチェックポイントは、特に指示しなくてもPostgreSQLエンジンによって定期的に実行されています。
ダーティページにまつわる性能の問題
ダーティページの存在には2つの問題があります。
1つはトランザクションのレスポンスタイムの低下です。共有バッファが足りなくなると、共有バッファ中で最も不要と思われるページを捨てて空きを作 るわけですが、このときもしも捨てるページがダーティページだった場合には先にハードディスクへ書き出す必要があります。これによりレスポンスタイムが低 下します。これを避けるには、共有バッファ中の最も不要と思われるページを常にダーティでない状態に保つ必要があります。
もう1つの問題は、チェックポイント処理時間の増大です。更新の多いデータベースでありがちなことですが、共有バッファ中のダーティページが増えてくると、それらすべてをハードディスクに書き出すチェックポイント処理の所要時間が長くなってしまいます。
チェックポイント処理中はハードディスクへのアクセスが集中するためトランザクション処理能力は大きく落ち込みますが、そのような性能の悪い期間が より長引いてしまうのです。これを避けるには、共有バッファ中のダーティページの数を減らすようにしなければなりません。