Блокировка базы данных SQLite навсегда (пока не удалена) для PHP - PullRequest
0 голосов
/ 01 августа 2011

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

Мы успешно использовали этот механизм кэширования около года. Однако в трех случаях у нас были проблемы с блокировкой базы данных SQLite, что вызывало проблемы. Мы получаем сообщение «исключение PDOException» с сообщением «SQLSTATE [HY000]: общая ошибка: база данных 5 заблокирована» в ... ».

У меня был поиск вокруг, и это, кажется, общая проблема, и есть много дискуссий о способах минимизировать его вероятность или предотвратить его (например, доски друпалов ). Тем не менее, моя проблема, кажется, немного отличается от этого. Кажется, описанные мной ситуации указывают на то, что это связано с параллелизмом - когда два PHP-процесса пытаются получить доступ к базе данных SQLite в одно и то же время, один из них получает ошибку блокировки. В этой ситуации попытки просто минимизировать проблему имеют смысл. Но для моего приложения, когда проблема начинает возникать (предположительно из-за параллелизма), база данных SQLite с этого момента постоянно блокируется. С этого момента каждый запрос на доступ к кешу получает исключение PDOException. Наше решение состояло в том, чтобы просто удалить файл кэша, что не является концом света, но это требует ручного вмешательства, и плюс означает, что мы теряем данные встроенного кэша.

Почему это происходит? Есть ли другие причины, по которым мы могли бы начать блокировку? Почему блокировка сохраняется? Есть ли способ программно очистить его? Есть ли способ предотвратить это в первую очередь?

Два «решения», которые я рассматриваю до сих пор:

  1. Поместите try-catch вокруг функций доступа к кешу. Если мы получим исключения, просто игнорируем кеш и уведомляем техподдержку, чтобы вручную очистить кеш.
  2. Используйте мьютекс (используя PHP flock ) для файла SQLite, чтобы предотвратить проблему с параллелизмом (но, опять же, я даже не уверен, что это является основной причиной).

Любая информация или предложения будут с благодарностью!

1 Ответ

1 голос
/ 12 декабря 2011

Ну ...

  1. Делает техподдержку обрабатывать несуществующую проблему.
  2. Игнорирует тот факт, что SQLite имеет собственную блокировку.(SQLite3 даже оптимизировал его!)

Оставляя гика во мне, стоя у двери, я бы использовал «решение» № 3 (которое вы не перечислили) и просто поставил try-catchвокруг кеш доступа к функциям.Если вы получаете исключения, сделайте короткий сон, а затем снова вызовите вызывающую исключение функцию.

thisFunction(...) 
{
    ....
    try
    {
      ....
    }
    catch(Exception $e)
    {
      sleep(rand(1,3))
      thisFunction(...);
    }
    ....
}

Таким образом, вы действительно получите что-то от ошибки, с которой sqlite пытается вам помочь.;)

...