sqlite3_wal_checkpoint_v2 всегда возвращает SQL_BUSY - PullRequest
2 голосов
/ 31 августа 2011

Контекст

Я использую sqlite версии 3.7.7.1 в программе Windows C ++, я создаю БД, которая имеет только одно соединение с SQLITE_OPEN_READWRITE |SQLITE_OPEN_CREATE |SQLITE_OPEN_NOMUTEX.

Я использую SQLite, потому что мне нужна очень быстрая транзакция ACID.База данных хранится на твердотельном диске NTFS в Windows XP sp3.

Эта база данных имеет 3 таблицы, и каждая транзакция подразумевает 3 таблицы, а самая большая транзакция вставляет 12 строк в одну из таблиц, вставляя 1 строку вдругой и обновите третью таблицу.

Мое приложение имеет цикл 400 мс, а база данных используется для пакета из 9 транзакций, который происходит в начале каждого цикла.Зная, что моя средняя транзакция занимает 15 мс (с очень редким пиком в 60 мс (примерно 1 из 60 000 транзакций, когда время теряется в функции Windows FlushFileBuffers)), база данных просто используется в первые 150 мс цикла 400 мс.

После бенчмаркинга журнал WAL предлагает лучшие показатели для моего приложения.

Но у меня есть проблема с журналом WAL: файл xxx-wal растет и растет непрерывно (после транзакции 500 Кбайтфайл был 8GB!).Активация auto_checkpoint не помогает.

При попытке вручную создать контрольную точку путем вызова sqlite3_wal_checkpoint_v2 с параметром SQLITE_CHECKPOINT_RESTART, sqlite3 продолжал возвращать SQLITE_LOCKED.

Я обнаружил, что при создании таблицы с использованием sqlite3_cсоединение становится заблокированным навсегда. Какое объяснение?Есть ли способ избежать этого?

Итак, закрывая соединение и открывая его снова, я повторяю вызов sqlite3_wal_checkpoint_v2, но на этот раз он вернул SQLITE_BUSY.Даже если я вызываю sqlite3_busy_timeout с 1 секундой, он все равно возвращает SQLITE_BUSY.

Вопросы

Что приводит к тому, что база данных занята, зная, что только одно соединениеиспользуется на БД, что это соединение используется несколькими потоками, но сериализовано через мьютекс на моей стороне приложения?

Подробнее:

  • Я использую несколько подготовленных операторов, которые я выполняю в циклах (даже один для НАЧАЛА СДЕЛКИ и СОВЕРШЕНИЯ СДЕЛКИ)
  • Кажется, БД занята после первой транзакции.

Мне трудно понять схему блокировки и занятости sqlite, несмотря на мое чтение на веб-сайте sqlite.У кого-нибудь есть хорошие ссылки по этому поводу?

1 Ответ

4 голосов
/ 01 сентября 2011

Я нашел причину своей проблемы, и на моей стороне было что-то 2 глупости:

Запрос размера страницы с помощью "PRAGMA page_size", я просто читал строку и не сбрасывал и не завершалоператор с "sqlite3_reset" или sqlite3_finalize (он был скрыт оболочкой C ++, с которой я тестировал).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...