Как разблокировать базу данных SQLite? - PullRequest
235 голосов
/ 30 сентября 2008
sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked

Как разблокировать базу данных, чтобы она работала?

Ответы [ 35 ]

4 голосов
/ 08 марта 2016

Я добавил "Pooling=true" в строку подключения, и это сработало.

4 голосов
/ 13 сентября 2012

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

3 голосов
/ 17 февраля 2012

У меня есть такая проблема в приложении, когда доступ к SQLite осуществляется через 2 соединения: одно было только для чтения, а второе - для записи и чтения. Похоже, что соединение только для чтения заблокировало запись со второго соединения. Наконец, оказывается, что необходимо завершить или, по крайней мере, сбросить подготовленные операторы НЕМЕДЛЕННО после использования. До тех пор, пока готовый оператор не будет открыт, он вызвал, что база данных была заблокирована для записи.

НЕ ЗАБЫВАЙТЕ ЗВОНИТЬ:

sqlite_reset(xxx);

или

sqlite_finalize(xxx);
3 голосов
/ 19 февраля 2015

Некоторые функции, такие как INDEX'ing, могут занимать очень много времени - и во время работы блокирует всю базу данных. В таких случаях он может даже не использовать файл журнала!

Так что лучший / единственный способ проверить, заблокирована ли ваша база данных, потому что процесс АКТИВНО записывает в нее (и, таким образом, вы должны оставить его в покое, пока он не завершил свою работу), - это md5 (или md5sum в некоторых системах) файл дважды. Если вы получаете другую контрольную сумму, база данных пишется, и вы действительно ДЕЙСТВИТЕЛЬНО не хотите уничтожать этот процесс, потому что вы можете легко получить поврежденную таблицу / базу данных, если вы это сделаете.

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

Единственный способ создать эту заблокированную, но не записываемую ситуацию - это если ваша программа запускает BEGIN EXCLUSIVE, потому что она хотела сделать какие-то изменения таблицы или что-то еще, то по какой-либо причине никогда не отправляет END потом и процесс никогда не прекращается . Все три выполняемых условия весьма маловероятны в любом правильно написанном коде, и, таким образом, в 99 случаях из 100, когда кто-то хочет уничтожить -9 свой процесс блокировки, процесс блокировки фактически блокирует вашу базу данных по уважительной причине. Программисты обычно не добавляют условие BEGIN EXCLUSIVE без особой необходимости, поскольку оно предотвращает параллелизм и увеличивает количество жалоб пользователей. Сам SQLite добавляет его только тогда, когда это действительно необходимо (например, при индексации).

Наконец, статус «заблокирован» не существует ВНУТРИ файла, как указано в нескольких ответах, - он находится в ядре операционной системы. Процесс, который запустил BEGIN EXCLUSIVE, запросил у ОС блокировку файла. Даже если ваш эксклюзивный процесс потерпел крах, ваша ОС сможет выяснить, должна ли она поддерживать блокировку файла или нет !! Невозможно получить базу данных, которая заблокирована, но ни один процесс не блокирует ее активно !! Когда дело доходит до выяснения, какой процесс блокирует файл, обычно лучше использовать lsof, а не fuser (это хорошая демонстрация того, почему: https://unix.stackexchange.com/questions/94316/fuser-vs-lsof-to-check-files-in-use). В качестве альтернативы, если у вас есть DTrace (OSX), вы можете использовать iosnoop на файл.

2 голосов
/ 17 сентября 2011
Команда

lsof в моей среде Linux помогла мне выяснить, что процесс зависает, сохраняя файл открытым.
Убил процесс и проблема была решена.

2 голосов
/ 03 апреля 2011

Должна быть внутренняя проблема базы данных ...
Для меня это проявилось после попытки просмотреть базу данных с помощью «менеджера SQLite» ...
Итак, если вы не можете найти другой процесс, подключенный к базе данных, и вы просто не можете это исправить, просто попробуйте это радикальное решение:

  1. Предоставление для экспорта ваших таблиц (Вы можете использовать «SQLite manager» в Firefox)
  2. Если миграция изменила схему базы данных, удалите последнюю неудачную миграцию
  3. Переименуйте ваш файл "database.sqlite"
  4. Выполнить "rake db: migrate", чтобы создать новую рабочую базу данных
  5. Предоставить права доступа к базе данных для импорта таблицы
  6. Импорт резервных копий таблиц
  7. Написать новую миграцию
  8. Выполнить с помощью "rake db:migrate"
2 голосов
/ 14 ноября 2008

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

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

2 голосов
/ 16 мая 2013

Эта ссылка решит проблему. : Когда Sqlite дает: Ошибка блокировки базы данных Это решило мою проблему, может быть полезно для вас.

И вы можете использовать начало транзакции и конец транзакции, чтобы не блокировать базу данных в будущем.

1 голос
/ 24 октября 2012

Одной из распространенных причин получения этого исключения является то, что вы пытаетесь выполнить операцию записи, все еще удерживая ресурсы для операции чтения. Например, если вы ВЫБИРАЕТЕ из таблицы, а затем пытаетесь ОБНОВИТЬ что-то, что вы выбрали, не закрывая сначала свой ResultSet.

1 голос
/ 21 июня 2010

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

В Linux для этой цели можно использовать fuser:

$ fuser database.db

$ fuser database.db-journal

В моем случае я получил следующий ответ:

philip    3556  4700  0 10:24 pts/3    00:00:01 /usr/bin/python manage.py shell

Что показало, что у меня была другая программа на Python с pid 3556 (manage.py), использующая базу данных.

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