当我输入这个查询: 删除邮件中id = 71的所有邮件

SQLite返回以下错误:

SQL error: database is locked

我如何解锁数据库,以便这个查询将工作?


当前回答

如果一个进程在SQLite DB上有一个锁,并且崩溃了,那么这个DB将永远处于锁定状态。这就是问题所在。并不是其他进程有锁。

其他回答

如果你想删除一个“database is locked”错误,请按照以下步骤执行:

将数据库文件复制到其他位置。 用复制的数据库替换数据库。这将解除对访问数据库文件的所有进程的引用。

SQLite db文件只是文件,所以第一步是确保它不是只读的。另一件要做的事情是确保在DB打开时没有某种GUI SQLite DB查看器。可以在另一个shell中打开DB,也可以在代码中打开DB。通常情况下,如果不同的线程或应用程序(如SQLite Database Browser)打开了数据库以便写入,则会看到这种情况。

删除-journal文件听起来是个糟糕的主意。它允许sqlite在崩溃后将数据库回滚到一致的状态。如果在数据库处于不一致状态时删除它,则会留下一个损坏的数据库。引用sqlite站点的一个页面:

If a crash or power loss does occur and a hot journal is left on the disk, it is essential that the original database file and the hot journal remain on disk with their original names until the database file is opened by another SQLite process and rolled back. [...] We suspect that a common failure mode for SQLite recovery happens like this: A power failure occurs. After power is restored, a well-meaning user or system administrator begins looking around on the disk for damage. They see their database file named "important.data". This file is perhaps familiar to them. But after the crash, there is also a hot journal named "important.data-journal". The user then deletes the hot journal, thinking that they are helping to cleanup the system. We know of no way to prevent this other than user education.

The rollback is supposed to happen automatically the next time the database is opened, but it will fail if the process can't lock the database. As others have said, one possible reason for this is that another process currently has it open. Another possibility is a stale NFS lock, if the database is on an NFS volume. In that case, a workaround is to replace the database file with a fresh copy that isn't locked on the NFS server (mv database.db original.db; cp original.db database.db). Note that the sqlite FAQ recommends caution regarding concurrent access to databases on NFS volumes, because of buggy implementations of NFS file locking.

我无法解释为什么删除一个-journal文件会让你锁定一个数据库,而你以前不能。这是可复制的吗?

顺便说一下,-journal文件的存在并不一定意味着发生了崩溃或有要回滚的更改。Sqlite有几种不同的日志模式,在PERSIST或TRUNCATE模式下,它始终保留-journal文件,并更改内容以指示是否有要回滚的部分事务。

您可以尝试:.timeout 100来设置超时时间。 我不知道在命令行中发生了什么,但在c# .Net中,当我这样做:“UPDATE table-name SET column-name = value;”我得到数据库被锁定,但这个“UPDATE table-name SET column-name = value”它很好。

看起来,当您添加;,sqlite将寻找进一步的命令。

我在谷歌Chrome浏览器中查看存储的密码时遇到了这个错误。

# ~/.config/google-chrome/Default
$ sqlite3 Login\ Data
SQLite version 3.35.5 2021-04-19 18:32:05
sqlite> .tables
Error: database is locked

如果你不是特别关心父进程,或者你不想停止当前正在使用数据库的chrome进程,只需将文件复制到其他地方。

$ cp Login\ Data ~/tmp/ld.sql
$ sqlite3 ~/tmp/ld.sql .tables
field_info              meta   sync_model_metadata   
insecure_credentials    stats                 
logins                  sync_entities_metadata

这样做将允许您读取数据库的内容,而不打扰或停止主chrome进程。