他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

29.1. 信頼性

信頼性は、すべての深刻なデータベースシステムで重要な特性です。 PostgreSQLは信頼できる操作を保証することができます。 信頼できる操作とは、コミットされたトランザクションにより記録されたデータはすべて不揮発性の領域に格納され、電源断、オペレーティングシステムの障害、ハードウェアの障害(当然ですが、不揮発性の領域自体の障害は除きます。)があっても安全であるという点です。 通常、コンピュータの永続的格納領域(ディスク装置など)へのデータ書き込みの成功がこの条件を満たします。 実際、コンピュータに致命的な障害が発生したとしても、もしディスク装置が無事ならば、類似のハードウェアを持つ別のコンピュータに移すことができ、コミットされたトランザクションを元通りに復元できます。

データを周期的にディスクプラッタに書き出すことは簡単な操作に思われるかもしれませんが、そうではありません。 ディスク装置は主メモリ、CPU、コンピュータの主メモリとディスクプラッタの間にある各種のキャッシュ層と比べ非常に低速であるからです。 まず、オペレーティングシステムのバッファキャッシュが存在します。 これは頻繁にアクセス要求があるディスクブロックをキャッシュし、ディスクへの書き込みをまとめます。 好運にもすべてのオペレーティングシステムがバッファキャッシュをディスクに強制書き込みさせる方法をアプリケーションに提供しています。 PostgreSQLはこの機能を使用します。 (これを調整する方法についてはwal_sync_methodパラメータを参照してください。)

次に、ディスク装置のコントローラキャッシュが存在する可能性があります。 特に、RAIDコントローラカードでは、これは一般的です。 これらはwrite-throughキャッシュ、つまり、データが届いた時に即座に書き込みがディスク装置に対して行なわれる、の場合があります。 また、write-backキャッシュ、つまり、多少遅れて書き込みがディスク装置に対して行なわれる、の場合もあります。 こうしたキャッシュではディスクコントローラキャッシュが揮発性、つまり、電源障害の際にその内容が失われてしまいますので、信頼性に関する障害が発生する可能性があります。 より優れたコントローラカードではバッテリバックアップ付き装置(BBUs) を持ちます。 つまり、システムの電源が落ちている状態でもキャッシュに電源を供給します。 後で電源が復旧した後に、データがディスク装置に書き出されます。

最後に、ほとんどのディスク装置がキャッシュを持っています。一部はwrite-throughであり、一部はwrite-backです。 ディスクコントローラキャッシュの場合と同様にwrite-backのディスク装置キャッシュの場合にはデータが損失する恐れがあります。 一般消費者向けのIDEおよびSATA装置では特に、よくwrite-backキャッシュを使用しています。これは電源障害時にデータが残りません。 多くのソリッドステートドライブ(SSD)も同様に揮発性のwrite-backキャッシュを持っています。

これらのキャッシュは、大抵は無効にできます。しかしながらオペレーティングシステムやドライブの種類によってその方法は異なります。

最近のSATAドライブ(ATAPI-6以降)はドライブキャッシュの書き出しコマンド(FLUSH CACHE EXT)を提供しており、 一方SCSIドライブでは従来から類似のSYNCHRONIZE CACHEコマンドをサポートしていました。 これらのコマンドは、直接PostgreSQLに発行されませんが、いくつかのファイルシステム(例えばZFSext4)では、 それらをwrite-backが有効なドライブへデータを書き出すために使います。 不幸なことに、このようなwriteバリアを持つファイルシステムは、バッテリバックアップ付き装置 (BBU)のディスクコントローラと組み合わせた際に、好ましくは動作しません。 このような処理の流れにおいて、同期コマンドはコントローラキャッシュにあるデータを全てディスクへ強制的に書き込みを行うため、 BBUのメリットの大半を失わせています。PostgreSQLのソースツリー内のsrc/tools/fsyncユーティリティを 使うことで、あなたの環境が影響を受けるかどうかを確認できます。もし影響を受けるようであれば、 ファイルシステムのwriteバリアを無効にするか、(オプションがあれば)ディスクコントローラを再設定することで、 BBUによる性能上の効果を得ることできるでしょう。もしwriteバリアを無効にした場合は、バッテリが 動作していることを確認しておきましょう。バッテリの欠陥はデータロスの可能性に繋がります。 ファイルシステムやディスクコントローラの設計者が、いずれはこの動作を修正してくれることが望まれます。

オペレーティングシステムが、ストレージハードウェアに書き込み要求を送信した時、データが不揮発性のストレージ領域に本当に届いたかどうかを確認することはほぼできません。 ですので、全てのストレージ構成品がデータ整合性を保証することをよく確認しておくことは、管理者の責任です。 バッテリを持たない書き込みキャッシュを持つコントローラを使用しないでください。 装置レベルでは、もし装置が停止前にデータが書き出されることを保証できないのであれば、write-backキャッシュを無効にしてください。 もしSSDを使っている場合、多くのドライブはデフォルトでキャッシュ書き出しコマンドを無視することに注意して下さい。 diskchecker.plを使うことで、I/Oサブシステムの動作の信頼性をテストすることができます。

ディスクプラッタの書き込み操作自体によってもデータ損失が発生することがあります。 ディスクプラッタは、通常512バイトのセクタに分割されています。 物理的な読み込み操作、書き込み操作はすべて、セクタ全体を処理します。 書き込み要求がディスクに達した時、その要求は512バイトの倍数(PostgreSQLでは大抵一度に8192バイトもしくは16セクタ分です)になるでしょう。そして 電源断により、任意のタイミングで書き込み処理が失敗することがありえます。これは一部の512バイトのセクタに書き込みが行なわれたのに、残りのセクタには書き込みが行なわれていない状況を意味します。 こうした問題の対策として、PostgreSQLは、ディスク上の実際のページを変更するに定期的にページ全体のイメージを永続的なWAL格納領域に書き出します。 これにより、PostgreSQLはクラッシュリカバリ時に部分的に書き出されたページをWALから復旧させることができます。 もし、部分的なページ書き込みを防止できるファイルシステムソフトウェア(例えばZFS)を使うのであれば、full_page_writesを無効にしてページイメージ作成を無効にすることができます。バッテリバックアップ付き(BBU)のディスクコントローラでは、フルページ(8kB)がBBUへ書き込まれることを保証できなければ、部分的なページ書き出しを防止できません。