Как следует использовать sqlite3 в «устойчивом состоянии»?

#python #sqlite

Вопрос:

У меня каждые несколько секунд выполняются задачи, которые необходимо считывать и записывать в мою базу данных sqlite3.

Чтобы избежать запуска интерпретаторов python и открытия базы данных для каждой задачи, процессы всегда выполняются, а соединение sqlite3 никогда не закрывается.

Чтобы повысить производительность и разрешить больше одновременных операций чтения, я использую режим WAL.

Проблема в том, что «контрольные точки» никогда не создаются, потому что соединения не закрыты, поэтому мой файл wal растет, и у меня плохая производительность. Первое возвращаемое значение PRAGMA wal_checkpoint(TRUNCATE); равно 1, что указывает на то, что оно было заблокировано для завершения.

Каков стандартный способ, чтобы несколько процессов всегда выполнялись в одной и той же базе данных?

  1. разве закрытие соединений не нормально, если мы не используем режим WAL?
  2. должен ли я регулярно закрывать и снова открывать соединения? (например, с таймером)
  3. есть ли способ заставить wal_checkpoint выполнить? (Я не знаю, почему они заблокированы)

Любое другое решение приветствуется!

Ответ №1:

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

В документах SQLite есть раздел, посвященный удаленным файлам WAL:

В обычных случаях новое содержимое добавляется в файл WAL до тех пор, пока файл WAL не накопит около 1000 страниц (и, таким образом, будет иметь размер около 4 МБ), после чего автоматически запускается контрольная точка и файл WAL перерабатывается. Контрольная точка обычно не обрезает файл WAL.

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

Не могли бы вы рассказать немного подробнее о системе, о том, как она работает и чего вы пытаетесь достичь? Может быть, есть другой способ.

Комментарии:

1. Спасибо за ответ! Это именно та проблема, с которой я столкнулся, поэтому мне было интересно, есть ли где-нибудь описанное типичное использование SQLite. Мой вариант использования немного проще, потому что у меня есть один писатель и несколько читателей.

2. Например, можно ли постоянно держать читателей WAL открытыми?

3. Я не вижу в этом проблемы, но вы уже упоминали, что в вашем случае использования это проблема. Я бы предложил провести небольшой тест с несколькими вариантами, чтобы увидеть, что работает лучше всего. Обычно рекомендуется делать транзакции как можно короче, поэтому вы можете поэкспериментировать с открытием/закрытием соединений по требованию

4. Есть ли способ закрыть транзакции, не закрывая соединение? Открытие соединения немного затратно по сравнению с простыми операциями.