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

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

Ответы [ 35 ]

235 голосов
/ 14 августа 2010

В Windows вы можете попробовать эту программу http://www.nirsoft.net/utils/opened_files_view.html, чтобы узнать, что процесс обрабатывает файл БД. Попробуйте закрыть эту программу для разблокировки базы данных

В Linux и macOS вы можете сделать нечто подобное, например, если ваш заблокированный файл - development.db:

$ fuser development.db

Эта команда покажет, какой процесс блокирует файл:

> development.db: 5430

Просто убей процесс ...

убить -9 5430

... И ваша база данных будет разблокирована.

86 голосов
/ 12 октября 2011

Я вызвал блокировку моего sqlite db при сбое приложения во время записи. Вот как я это исправил:

echo ".dump" | sqlite old.db | sqlite new.db

Взято из: http://random.kakaopor.hu/how-to-repair-an-sqlite-database

51 голосов
/ 20 октября 2008

Страница SQLite wiki DatabaseIsLocked предлагает хорошее объяснение этого сообщения об ошибке. Отчасти утверждается, что источник разногласий является внутренним (для процесса, выдающего ошибку).

Чего эта страница не объясняет, так это как SQLite решает, что что-то в вашем процессе имеет блокировку, и какие условия могут привести к ложному срабатыванию.

30 голосов
/ 22 июня 2009

Удаление файла -journal звучит как ужасная идея. Он позволяет sqlite откатывать базу данных до согласованного состояния после сбоя. Если вы удалите его, когда база данных находится в несогласованном состоянии, то у вас останется поврежденная база данных. Ссылаясь на страницу с сайта sqlite :

Если происходит сбой или сбой питания и на диске остается горячий журнал, важно, чтобы исходный файл базы данных и горячий журнал оставались на диске с их исходными именами, пока файл базы данных не будет открыт другим процессом SQLite. и откатился назад. [...]

Мы подозреваем, что общий режим сбоя для восстановления SQLite происходит следующим образом: происходит сбой питания. После восстановления питания доброжелательный пользователь или системный администратор начинает осматривать диск на предмет повреждений. Они видят файл своей базы данных с именем "Important.Data". Возможно, этот файл им знаком. Но после сбоя есть еще и горячий журнал под названием «важное.данные-журнал». Затем пользователь удаляет горячий журнал, думая, что он помогает очистить систему. Мы не знаем никакого способа предотвратить это, кроме обучения пользователей.

Откат должен произойти автоматически при следующем открытии базы данных, но произойдет сбой, если процесс не сможет заблокировать базу данных. Как уже говорили другие, одна из возможных причин этого заключается в том, что в настоящее время этот процесс открыт. Другой возможностью является устаревшая блокировка NFS, если база данных находится на томе NFS. В этом случае обходным путем является замена файла базы данных новой копией, которая не заблокирована на сервере NFS (mv database.db original.db; cp original.db database.db). Обратите внимание, что в FAQ по sqlite рекомендуется соблюдать осторожность при одновременном доступе к базам данных на томах NFS из-за ошибочных реализаций блокировки файлов NFS.

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

Кстати, наличие файла -journal не обязательно означает, что произошел сбой или есть изменения, которые необходимо откатить. Sqlite имеет несколько разных режимов ведения журнала, а в режимах PERSIST или TRUNCATE он всегда оставляет файл -journal на своем месте и изменяет его содержимое, чтобы указать, есть ли частичные транзакции для отката.

13 голосов
/ 07 марта 2013

Если вы хотите удалить ошибку «база данных заблокирована», выполните следующие действия:

  1. Скопируйте файл базы данных в другое место.
  2. Заменить базу данных на скопированную базу данных. Это разыменует все процессы, которые обращались к вашему файлу базы данных.
12 голосов
/ 30 января 2009

Если процесс блокируется на БД SQLite и происходит сбой, БД остается заблокированной навсегда. Это проблема. Дело не в том, что какой-то другой процесс имеет блокировку.

10 голосов
/ 30 сентября 2008

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

9 голосов
/ 16 июня 2011

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

Предложенные выше рецепты восстановления не сработали (включая идею сначала переместить, а затем скопировать базу данных обратно). Но после копирования в систему, отличную от NFS, база данных стала пригодной для использования, и данные, по-видимому, не были потеряны.

5 голосов
/ 04 августа 2009

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

Использование оболочки Linux, которая была бы ...

mv mydata.db temp.db
cp temp.db mydata.db
4 голосов
/ 14 ноября 2008

Я нашел документацию о различных состояниях блокировки в SQLite, что очень полезно. Майкл, если вы можете выполнять чтение, но не можете выполнять запись в базу данных, это означает, что процесс получил зарезервированную блокировку в вашей базе данных, но еще не выполнил запись. Если вы используете SQLite3, есть новая блокировка PENDING, в которой больше не разрешено подключать больше процессов, но существующие соединения могут выполнять чтение, поэтому если вы столкнулись с этой проблемой, вам следует рассмотреть это вместо этого.

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