places.sqliteがVACUUMされるタイミング

昨日Firefox SQLiteデータベースのVACUUMについて - hogehogeの記事を書き、

Firefox3.6だったか3.5だったかで、places.sqliteはPCがアイドル時にVACUUMする処理が入っているはず。

と書いた。

また、コメント欄にてBug 512854 ? VACUUM places.sqlite database on daily idle once a monthを教えてもらい、mozilla-1.9.2: changeset 31871:7b4f35e3a442リポジトリにコミットされていることが分かった。

もしかすると勘違いされているかもしれないので書いておくとFirefox3.6では既に反映されています

それだけじゃ何なので、ソースコードからいつどういった条件でVACUUMされるか調べてみた。

まず、Firefoxが起動するとPlacesサービス(nsNavHistory)が初期化され、idle-dailyというトピック名のオブザーバが登録される。

オブザーバへの通知

このオブザーバに通知がいくと、最後にVACUUMした時間*1(lastVacuumTime)を取得し、以下の条件を満たすとVACUUMが実施される。

  • 現在時間がlastVacuumTimeから30日超かつ60日未満、または一度もVACUUMされていない(lastVacuumTime値がない)
  • 使用ページに対して空きページ(freelist_count)が10%超

アイドル時の条件

アイドル時にVACUUMが実施されるわけだが、条件がある。
アイドル時間が5分超、かつ、前にアイドルした時間(この値は1日経たないと更新されない)*2から1日(24*60*60秒)経っている場合。つまり、1日に0〜1回しか通知されない。

所感

1ヶ月から2ヶ月の間に一回くらいはVACUUMが実施されるように思われる。
が、空きページが10%超という条件が結構厳しいように感じられる。places.sqliteのページサイズは4096バイトなわけだが、空きページ(freelist_count)というは全く使われていないページのこと。ちょっとでも使われているページはカウントされず、4096バイト丸々空いている箇所が10%ないとVACUUMの条件を満たさない。これってそんなにたくさん発生するのだろうか...。

さらに、前回から2ヶ月間この10%を超えないと永久にVACUUMされないという仕様に見える。(違っていたらご指摘願います)

*1:about:configから見られる"places.last_vauum"値 * 1000

*2:about:configから見られる"idle.lastDailyNotification"の値