Как очистить файлы базы данных SQLite хранилища Firefox, чтобы удалить большие файлы SQLITE-WAL?

Как очистить файлы базы данных SQLite хранилища Firefox, чтобы удалить большие файлы SQLITE-WAL?

Я заметил, чтоWAL (журнал опережающей записи)Файлы (*.sqlite-wal), связанные с базами данных SQLite (*.sqlite), используемыми веб-браузером Firefox, часто становятся довольно большими. Они буквально могут стать в 150 раз больше размера связанных баз данных SQLite и оставаться такими в течение месяцев (годов? вечно?).

В соответствии сэтот ответ StackOverflowвозможным решением может быть запуск следующей команды SQLite pragma для каждой затронутой базы данных хранилища:

PRAGMA schema.wal_checkpoint(TRUNCATE);

Теоретически для выполнения этого действия можно использовать внешний по отношению к Firefox инструмент SQLite, но я узнал, что выполнение действийв пределахFirefox обычно дает наилучшие результаты. (Например, попробуйте поработать с файлом omni.jarвне Firefox... это может быть PITA, поскольку Mozilla использует нетипичную структуру JAR.)

Есть ли в Firefox способ очистить все базы данных SQLite, чтобы их содержимое полностью записалось в соответствующие .sqliteфайлы?


ОБНОВЛЯТЬ:

Я хотел бы отметить, что одной из основных целей размещения этого вопроса является безопасное обращение с файлом, storage-sync-v2.sqlite-walкоторый растет до тех пор, пока не достигнет 32 МБ в каждом профиле Firefox. Соответствующая база данных, storage-sync-v2.sqlite, также имеет storage-sync-v2.shmфайл, но, как правило, остается довольно маленькой. Чтобы сосредоточиться наодна тема на вопрос, я написалсвязанный вопрос, специально направленный на решение этой цели.

решение1

Закройте экземпляр Firefox, использующий профиль, содержащий соответствующие базы данных.

Запустите Firefox из временного профиля. Откройте Browser Console и вставьте следующий фрагмент. Отредактируйте строку пути так, чтобы она указывала на целевой профиль. НажмитеEnter

Повторите эти действия для каждой базы данных SQLite.

Надеюсь, все сработает как надо, но не помешает сделать резервную копию своего профиля, прежде чем что-либо предпринимать.

(()=>{
  let file = new FileUtils.File("/pathToTargetProfile/places.sqlite"); // edit this string
  let db = Services.storage.openDatabase(file);
  let stmt = db.createStatement("PRAGMA wal_checkpoint(TRUNCATE)");
  stmt.executeStep();
  console.log(stmt.row); //this might provide useful info
  stmt.finalize();
  db.close();
})();

решение2

На самом деле это действительно хороший вопрос, который задают не многие.

Файл .sqlite-walувеличивается до предела в 32 МБ, поскольку это, вероятно, предел журнала транзакций, который вы (или создатель вашего пакета) определили во время компиляции SQLite вашего Firefox.

Директива, с помощью которой можно настроить лимит журнала транзакций во время компиляции, называетсяSQLITE_DEFAULT_JOURNAL_SIZE_LIMITи это определено вбайты. В вашем случае это 32 МБ.

Вы также можете настроить лимит журнала транзакций позже в SQLite с помощью:

PRAGMA schema.journal_size_limit = N ;(сноваНвбайты, отрицательное число не устанавливает предела)

Что вам нужно понять, этомягкий предел, не сложный. Если у вас есть активный процесс, который пишет в журнал; он продолжит писать, даже если будет достигнут указанный лимит. Он может легко достичь 2 ГБ, даже если у вас определен лимит в 20 МБ.

Этот лимит длянеактивныйЖурнал транзакций. Я думаю, разработчики Firefox решили, что 32 МБ — это правильный баланс между наличием журнала предварительной записи и скоростью.

Если вы хотите настроить размер PRAGMA после компиляции, вам нужно сделать это для каждого имеющегося у вас профиля. Если вы планируете использовать много профилей/баз данных, вам, вероятно, захочется перекомпилировать его с набором SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT.

Процитирую правильные отрывки из высказываний этого человека:

В режиме WAL файл журнала упреждающей записи не усекается после контрольной точки. Вместо этого SQLite повторно использует существующий файл для последующих записей WAL, поскольку перезапись происходит быстрее, чем добавление.

Прагма journal_size_limit может использоваться для ограничения размера журнала отката и файлов WAL, остающихся в файловой системе после транзакций или контрольных точек. Каждый раз, когда транзакция фиксируется или файл WAL сбрасывается, SQLite сравнивает размер файла журнала отката или файла WAL, оставшегося в файловой системе, с предельным размером, установленным этой прагмой, и если файл журнала или WAL больше, он усекается до предела.

Вторая форма прагмы, указанная выше, используется для установки нового лимита в байтах для указанной базы данных. Отрицательное число подразумевает отсутствие лимита. Чтобы всегда усекать журналы отката и файлы WAL до минимального размера, установите journal_size_limit равным нулю. Как первая, так и вторая формы прагмы, указанные выше, возвращают одну строку результата, содержащую один целочисленный столбец — значение лимита размера журнала в байтах. Лимит размера журнала по умолчанию равен -1 (нет лимита). Макрос препроцессора SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT можно использовать для изменения лимита размера журнала по умолчанию во время компиляции.

Эта прагма работает только с одной базой данных, указанной до имени прагмы (или с «главной» базой данных, если база данных не указана.) Нет способа изменить ограничение размера журнала для всех присоединенных баз данных с помощью одного оператора PRAGMA. Ограничение размера должно быть установлено отдельно для каждой присоединенной базы данных.

Обновление:

Я забыл упомянуть один важный параметр SQLite wal_autocheckpoint=N;(где N — эточислоиз 32КиБстраницыв журнале объемом 512 КБ). (О чем автор уже упомянул при усечении данных)

Вы можете настроить его на использование меньшей автоматической контрольной точки. Обратите внимание, что это влияет на производительность SQLite и, следовательно, браузера. Слишком много контрольных точек замедлят браузер.

Чтобы правильнонастроить автоматическую контрольную точкуперейди по ссылке.

Важно также отметить, что контрольно-пропускные пункты, инициированные таким образом,ПАССИВНЫЙ. Это означает, что SQLite должен делать как можно больше без блокировок.

Процитирую человека из ПАССИВНОГО режима:

SQLITE_CHECKPOINT_PASSIVE Сделать контрольную точку как можно большего числа кадров, не дожидаясь завершения работы каких-либо читателей или писателей базы данных, затем синхронизировать файл базы данных, если все кадры в журнале были отмечены контрольной точкой. Обратный вызов busy-handler никогда не вызывается в режиме SQLITE_CHECKPOINT_PASSIVE. С другой стороны, пассивный режим может оставить контрольную точку незавершенной, если есть параллельные читатели или писатели.

Как и в примечании к обновлению выше, вы также можете установить эту опцию во время компиляции с помощьюSQLITE_DEFAULT_WAL_AUTOCHECKPOINT=<pages>.

От мужчины:

Этот макрос устанавливает количество страниц по умолчанию для функции автоматической контрольной точки WAL. Если не указано, количество страниц по умолчанию равно 1000.

Связанный контент