当我输入这个查询: 删除邮件中id = 71的所有邮件
SQLite返回以下错误:
SQL error: database is locked
我如何解锁数据库,以便这个查询将工作?
当我输入这个查询: 删除邮件中id = 71的所有邮件
SQLite返回以下错误:
SQL error: database is locked
我如何解锁数据库,以便这个查询将工作?
当前回答
我在Mac OS X 10.5.7上从终端会话运行Python脚本时遇到了同样的问题。尽管我已经停止了脚本,并且终端窗口位于命令提示符处,但它在下次运行时仍然会给出这个错误。解决方案是关闭终端窗口,然后再次打开它。我觉得没道理,但奏效了。
其他回答
这个环节解决了问题。:当Sqlite给出:数据库锁定错误 它解决了我的问题也许对你有用。
并且可以使用开始事务和结束事务来避免将来数据库被锁定。
有些函数,比如INDEX'ing,可能会花费很长时间——而且在运行时它会锁定整个数据库。在这种情况下,它甚至可能不使用日志文件!
因此,最好/唯一的方法来检查您的数据库是否被锁定,因为一个进程正在积极地写入它(因此你应该让它独自呆着,直到它完成它的操作)是md5(或md5sum在某些系统)文件两次。 如果你得到一个不同的校验和,数据库正在被写入,你真的真的真的不想杀死这个进程,因为如果你这样做,你很容易得到一个损坏的表/数据库。
我要重申一下,因为这很重要——解决方案不是找到锁程序并杀死它——而是找出数据库是否有一个很好的写锁,然后从那里开始。有时候正确的解决方法就是喝杯咖啡休息一下。
The only way to create this locked-but-not-being-written-to situation is if your program runs BEGIN EXCLUSIVE, because it wanted to do some table alterations or something, then for whatever reason never sends an END afterwards, and the process never terminates. All three conditions being met is highly unlikely in any properly-written code, and as such 99 times out of 100 when someone wants to kill -9 their locking process, the locking process is actually locking your database for a good reason. Programmers don't typically add the BEGIN EXCLUSIVE condition unless they really need to, because it prevents concurrency and increases user complaints. SQLite itself only adds it when it really needs to (like when indexing).
Finally, the 'locked' status does not exist INSIDE the file as several answers have stated - it resides in the Operating System's kernel. The process which ran BEGIN EXCLUSIVE has requested from the OS a lock be placed on the file. Even if your exclusive process has crashed, your OS will be able to figure out if it should maintain the file lock or not!! It is not possible to end up with a database which is locked but no process is actively locking it!! When it comes to seeing which process is locking the file, it's typically better to use lsof rather than fuser (this is a good demonstration of why: https://unix.stackexchange.com/questions/94316/fuser-vs-lsof-to-check-files-in-use). Alternatively if you have DTrace (OSX) you can use iosnoop on the file.
在我的例子中,我也得到了这个错误。
我已经检查了其他进程,可能是锁定数据库的原因,如(SQLite管理器,连接到我的数据库的其他程序)。但是没有其他程序连接到它,它只是同一个应用程序中保持连接的另一个活动SQLConnection。
在建立新的SQLConnection和新命令之前,尝试检查您以前的活动SQLConnection,它可能仍然被连接(首先断开它)。
从您之前的评论中,您说存在一个-journal文件。
这可能意味着您已经打开和(EXCLUSIVE?)事务,还没有提交数据。是你的程序或者其他进程留下了-journal吗?
重新启动sqlite进程将查看日志文件,清除任何未提交的操作并删除-journal文件。
在选择重新启动选项之前,有必要看看能否找到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
这表明我有另一个使用数据库的pid 3556 (manage.py)的Python程序。