Mozilla Flux

Mozilla関係の情報に特化したブログです。

Placesデータベースの読み書き処理を大きく減らす裏技(Firefox 49以降)

Firefoxはブラウジング履歴やブックマークなどの情報をPlacesと呼ばれるSQLiteデータベースに記録している。Placesが壊れてしまうとブックマークが失われたり、ロケーションバーからうまく候補を呼び出せなくなったりするため、FirefoxはジャーナルモードというSQLiteの機能を利用して、データベースの保護に努めている。

Placesを保護する手段の1つが、ログ先行書き込み(WAL:Write-Ahead Logging)だ。SQLiteでは、トランザクション開始から終了までの更新内容を順次「-shm」ファイルに書き込み、コミット時に「-wal」ファイルへと更新内容を書き込む*1。コミットした時点では本体データベースファイルに更新内容を書き込まないため、クラッシュしても本体は無傷で残り、トランザクションも迅速に完了できるというわけだ。Placesの場合、このWALジャーナリングモードが初期設定で有効化されており、本体であるplaces.sqliteのほかに、places.sqlite-shmとplaces.sqlite-walという2つのログファイルが作成される。

これとは別に、PlacesではFULL同期モードが初期設定で採用されており、コンテンツが安全にデータベースに書き込まれたのを確認してから次の処理に進むようになっている。SQLiteの公式サイトの説明によれば、WALジャーナリングモードは通常NORMAL同期モードと呼ばれる相対的に軽い処理のモードを採用することが一般的らしい。あえて重いモードを選択しているあたり、Placesを厳重に保護しようとするMozillaの判断がうかがえる。

だが、これらの保護措置はFirefoxのテスト自動化にとって妨げとなる。大量のディスク入出力(I/O)が発生するからだ。そこで、Firefox 49ではWALジャーナリングモードとFULL同期モードを両方オフにする隠し設定が導入された(Bug 1272025)。これにより、Firefoxの自動テストのような負荷の高い環境では、ギガバイト単位でディスクI/Oを節約できるという。

危険度の高い変更であるため、隠し設定は通常よりも複雑なものとなっている。まず、about:configの画面でplaces.database.disableDurabilityの設定を新規作成し、真偽値をtrueにする。次に、環境変数を追加する。設定値は何でもよく、変数の存在だけが重要だ。ALLOW_PLACES_DATABASE_TO_LOSE_DATA_AND_BECOME_CORRUPTがそれだ。Windowsだとコントロールパネルの「システムの詳細設定」からユーザー環境変数を追加できる。トラブルシューティング情報(about:support)からプロファイルフォルダを開き、places.sqlite-shmとplaces.sqlite-walのファイルが消えていることを確認できれば成功だ。

隠し設定が有効化されると、WALジャーナリングモードはMEMORYジャーナリングモードへと変更され、ロールバックジャーナルと呼ばれるデータベースのバックアップがメモリ上に作成されるようになる。書き込みは直接Placesデータベースに対し行われるので、ログの読み書き分のディスクI/Oがなくなるわけだ。しかも、Placesへの書き込み完了を待たずに次の処理へ移るため、ユーザー側からは書き込み処理に要する時間も短縮されたように見える。

一般ユーザーが使用することを想定していない裏技ではあるが、履歴やブックマークの完全性よりもFirefoxの動作の高速性を選びたいマニア向けに紹介しておく。