当我输入这个查询: 删除邮件中id = 71的所有邮件
SQLite返回以下错误:
SQL error: database is locked
我如何解锁数据库,以便这个查询将工作?
当我输入这个查询: 删除邮件中id = 71的所有邮件
SQLite返回以下错误:
SQL error: database is locked
我如何解锁数据库,以便这个查询将工作?
当前回答
我有一个工具“DB Browser for SQLite”正在运行,也在里面工作。显然,这个工具也会锁上东西。 在点击“写入更改”或“恢复更改”后,锁消失了,另一个进程(一个React-Native脚本)不再给出这个错误。
其他回答
这是因为该数据库上正在运行其他一些查询。SQLite是一个同步执行查询的数据库。如果其他人正在使用该数据库,那么如果你执行查询或事务,它就会给出这个错误。
因此,停止正在使用特定数据库的进程,然后执行查询。
我刚刚遇到了类似的情况——我的web应用程序能够从数据库中读取数据,但不能执行任何插入或更新。重启Apache至少暂时解决了这个问题。
不过,如果能找到根本原因就好了。
如果一个进程在SQLite DB上有一个锁,并且崩溃了,那么这个DB将永远处于锁定状态。这就是问题所在。并不是其他进程有锁。
在我编写的一个c# . net 4.6.1应用程序中,当它试图写入数据时,我也收到了sqlite锁,但在我的开发机器上的Visual Studio中运行该应用程序时却没有。相反,只有在远程Windows 10机器上安装并运行该应用程序时,才会出现这种情况。
最初我认为是文件系统权限,但事实证明是我使用Nuget在项目中安装的system . data . sqlite包驱动程序(v1.0.109.2)导致了这个问题。我删除了NuGet包,并在项目中手动引用了旧版本的驱动程序,一旦应用程序重新安装在远程机器上,锁定问题就神奇地消失了。只能认为是最新的驱动程序或Nuget包有bug。
有些函数,比如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.