ワープロなど多くのアプリケーションでは、「Save」あるいは「保存」を実行するとメモリ上で編集したデータがディスク上のファイルに書き込まれます。しかし、データベースで「保存」に相当する COMMIT を実行しても、メモリ上にあるデータがディスク上のデータファイルに書き込まれるとは限りません。
ここまで読んで、次のような疑問を持つ人も多いでしょう。
(1) ディスクに書き込まないのはなぜ?
(2) この状態でシステムが異常終了したら、書き込んだはずのデータが失われるのでは?
簡単に結論を言ってしまうと、
(1) パフォーマンスのためです。データをディスクに書き込むのには時間がかかります。
(2) ご心配なく。データを失わないようにするための仕掛けがあります。
その仕掛けが「トランザクションログ」です。
データベースを更新するとき、多くの場合、複数のファイルの複数のブロックにランダムアクセスしてデータを更新する必要があります。この処理には時間が掛かるので、データファイルの更新は、非同期に、またなるべくまとめて実行してアクセス回数を減らすことで、パフォーマンスの向上を図っています。
具体的には、データファイルを更新する代わりに、データ更新の内容をログファイル(トランザクションログ)に出力します。単一のファイルに追記するだけなので、データファイルの更新に比べると高速に実行できます。
データ更新において COMMIT を発行したとき、データベースサーバーは、トランザクションログへの出力完了をもって「更新成功」をクライアントに返します。
この時点ではデータファイルはまだ更新されていません。
この状態でシステムが異常終了したらどうなるでしょうか。データベースが再起動するとき、トランザクションログへの出力内容がデータファイルに反映済みかどうか確認し、反映されていないものがあればまずそれをデータファイルに書き込むようになっています。これをリカバリ処理などと呼びますが、このような仕掛けがあるのでCOMMIT に成功したデータが失われることはありません。
以上から明らかなように、トランザクションログの保全はデータベースの運用において極めて重要です。何らかのシステム異常によりトランザクションログの出力に障害が発生するとデータベースが停止することになります。
また、何らかの障害によりデータファイルが失われてもトランザクションログがあれば復旧させることも可能ですが、トランザクションログが失われると、データファイルを復旧させることができなくなります。
トランザクションログを利用したデータベースのバックアップと復旧の方法をPostgreSQLではポイントインタイムリカバリ(PITR)と呼んでいます。これについては「バックアップとリストア、リカバリ」の記事を参照してください。
データベースが管理するデータは、システム障害が発生しても失われないような対策が必要な重要なものであることが多いですが、必ずしもすべてのデータがそうであるとは限りません。
PostgreSQL 9.1では Unlogged table と呼ばれる機能が新たにサポートされました。これはテーブル作成時に
CREATE TABLE table_name ...
を実行する代わりに
CREATE UNLOGGED TABLE table_name ...
とするだけのものですが、こうして作成されたテーブルに対する更新は、トランザクションログに出力されません。従って、システムが異常終了した場合など、このテーブルに対するリカバリ処理は実行されず、COMMIT したはずのデータが一部、失われる可能性があります。その代わりに、ログ出力しない分だけ、データ更新のパフォーマンスが上がります。
環境にもよりますが、PostgreSQL Magazine #01 の記事によれば、5倍の性能向上が見られた、とのことです。
「トランザクションログ」と言えば、多くのデータベース技術者は何のことか理解できると思いますが、RDBMS の種類によって、違う名前で呼ばれることがありますので、混乱しないように注意して下さい。PostgreSQLでは「WALファイル」という言葉が使われます。WALはWrite Ahead Loggingの略です。MySQLのInnoDBでもWALという言葉が使われます。Oracleでは「REDOログ」と呼ばれています。
解説:松田神一
© EDUCO All Rights Reserved.