ログ先行書き込み(WAL)はトランザクションロギングを行うための一般的な手法です。 詳しい説明はすべてでなくても、たいていのトランザクション処理について書かれた本に書かれています。 簡単にいうと、WALの基本的な考え方は、データファイルへの変更はロギングされ、その後にのみ(テーブルやインデックスがある)データファイルに書き出されなければならないということです。 つまり、そのタイミングでログレコードが永続的な記憶装置に書き出されます。 このような手順に従って処理を行えば、たとえクラッシュがおきてもログを使ってデータベースをリカバリできるため、トランザクションのコミットの度にデータページをディスクに吐き出す必要がなくなります。 リカバリの時点では、まず、データページに対してまだ行われていない変更分はログレコードを使って再実行(これがロールフォワードリカバリです。 すなわちREDOとして知られています)され、コミットされていないトランザクションによる変更はデータページから削除されます(これはロールバックワードリカバリ、すなわちUNDOとして知られています)。
WALを採用する1つ目の明白な利点はディスクへの書き込み回数が大幅に減ることです。 というのは、トランザクションコミットの時にログファイルだけをディスクに吐き出せばよいからです。 マルチユーザ環境では、多くのトランザクションのコミットをログファイルの1回のfsync()で済ますことができます。 それだけではなく、ログファイルへの書き込みはシーケンシャルに行なわれるため、データページを吐き出すコストに比べログファイルの同期はずっと低コストになります。
2つ目のメリットは、データページの一貫性です。 実際、WALが導入される前は、PostgreSQLはクラッシュした時に一貫性を保てるという保証はありませんでした。 WAL導入以前では、書き込み中にクラッシュした場合に次のようなことが起こる可能性がありました。
存在しないテーブルの行をインデックス行が指す
分割処理中にインデックス行が失われる
部分的にしかデータが書かれていないために、完全にテーブルやインデックスのページの内容が壊れてしまう
このインデックスに関わる問題(上記の1と2)は、fsync()の呼び出しを追加すれば解決できる可能性があります。 しかしWALがない場合、最後の問題を解決するかというのはわかりません。 WALは、クラッシュ後の修復時にページの一貫性を保証するために必要とされるページであれば、そのデータページ内容全体をログに保存します。