How do I unlock a SQLite database?

前端 未结 30 1408
栀梦
栀梦 2020-11-22 15:56
sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked

How do I unlock the database so this will work?

相关标签:
30条回答
  • 2020-11-22 16:25

    Some functions, like INDEX'ing, can take a very long time - and it locks the whole database while it runs. In instances like that, it might not even use the journal file!

    So the best/only way to check if your database is locked because a process is ACTIVELY writing to it (and thus you should leave it the hell alone until its completed its operation) is to md5 (or md5sum on some systems) the file twice. If you get a different checksum, the database is being written, and you really really REALLY don't want to kill -9 that process because you can easily end up with a corrupt table/database if you do.

    I'll reiterate, because it's important - the solution is NOT to find the locking program and kill it - it's to find if the database has a write lock for a good reason, and go from there. Sometimes the correct solution is just a coffee break.

    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.

    0 讨论(0)
  • 2020-11-22 16:26

    In windows you can try this program http://www.nirsoft.net/utils/opened_files_view.html to find out the process is handling db file. Try closed that program for unlock database

    In Linux and macOS you can do something similar, for example, if your locked file is development.db:

    $ fuser development.db

    This command will show what process is locking the file:

    > development.db: 5430

    Just kill the process...

    kill -9 5430

    ...And your database will be unlocked.

    0 讨论(0)
  • 2020-11-22 16:27

    As Seun Osewa has said, sometimes a zombie process will sit in the terminal with a lock aquired, even if you don't think it possible. Your script runs, crashes, and you go back to the prompt, but there's a zombie process spawned somewhere by a library call, and that process has the lock.

    Closing the terminal you were in (on OSX) might work. Rebooting will work. You could look for "python" processes (for example) that are not doing anything, and kill them.

    0 讨论(0)
  • 2020-11-22 16:28

    I just had the same error. After 5 minets google-ing I found that I didun't closed one shell witch were using the db. Just close it and try again ;)

    0 讨论(0)
  • 2020-11-22 16:29

    If a process has a lock on an SQLite DB and crashes, the DB stays locked permanently. That's the problem. It's not that some other process has a lock.

    0 讨论(0)
  • 2020-11-22 16:29

    I was having "database is locked" errors in a multi-threaded application as well, which appears to be the SQLITE_BUSY result code, and I solved it with setting sqlite3_busy_timeout to something suitably long like 30000.

    (On a side-note, how odd that on a 7 year old question nobody found this out already! SQLite really is a peculiar and amazing project...)

    0 讨论(0)
提交回复
热议问题