コミットは、トランザクション中で行われたデータ操作を確定させる。コミット後は、すべてのデータ変更が永続的なものとなることをデータベースシステムは保証しなければならない。そのために、「同期書き込み」というOSが用意した機能を利用する。同期書き込みを行うと、物理的にハードディスク上に書き込みを完了したことをOSが確認するまでは、呼び出し元に返らない。したがって、データの永続性は確実になるが、同期書き込み操作は非常に遅い。

テーブルやインデックスのデータをコミット時にいちいち同期書込していたのでは実用に耐えられないほど遅くなるので、基本的にはトランザクションログだけをコミット時に同期書込する。テーブルやインデックスのデータはいつでもトランザクションログから再現できるからだ。

それでも、トランザクションのコミット時にトランザクションログを同期書き込みすることは避けられない。この同期書き込みを回避し、さらにレスポンスを良くするために従来使われていたのが、あえて同期書き込みをオフにする方法だ。具体的には、postgresql.confで、

fsync = off

を設定すると、同期書き込みを行わなくなるので、格段に高速になる。

データ消失よりコワいこと

もちろんこの方法にはリスクがある(だからこそデフォルトでonになっているのだ)。まず、データが消失する可能性がある。同期書き込みをしないのだから当然だ。しかし、コミットしたデータが消失するだけなら、もう一度やり直せば済む場合もある。たとえば、マスターデータをロードするようなケースだ。

しかし、fsync = offの本当のリスクは単にデータがなくなることではない。どこまでデータが消失したのかがわからないことだ。どこまでデータがなくなったわからないのだから、再度トライすることもできないし、残ったデータに整合性があることはまったく保証できなくなる。

結局、fsync = offは、信頼性の高いバッテリでシステムの電源がバックアップされ、決して停電などの障害が起きないシステムでしか使うことができないことになる。