当我输入这个查询: 删除邮件中id = 71的所有邮件
SQLite返回以下错误:
SQL error: database is locked
我如何解锁数据库,以便这个查询将工作?
当我输入这个查询: 删除邮件中id = 71的所有邮件
SQLite返回以下错误:
SQL error: database is locked
我如何解锁数据库,以便这个查询将工作?
当前回答
由于某种原因,数据库被锁定了。以下是我的解决方法。
我将sqlite文件下载到我的系统(FTP) 删除在线sqlite文件 将文件上传到主机提供商
现在可以正常工作了。
其他回答
我也有同样的问题。显然,回滚函数似乎用与db文件相同但没有最近更改的日志覆盖了db文件。我已经在下面的代码中实现了这一点,从那时起它一直工作得很好,而之前我的代码会因为数据库保持锁定而陷入循环。
希望这能有所帮助
我的python代码
##############
#### Defs ####
##############
def conn_exec( connection , cursor , cmd_str ):
done = False
try_count = 0.0
while not done:
try:
cursor.execute( cmd_str )
done = True
except sqlite.IntegrityError:
# Ignore this error because it means the item already exists in the database
done = True
except Exception, error:
if try_count%60.0 == 0.0: # print error every minute
print "\t" , "Error executing command" , cmd_str
print "Message:" , error
if try_count%120.0 == 0.0: # if waited for 2 miutes, roll back
print "Forcing Unlock"
connection.rollback()
time.sleep(0.05)
try_count += 0.05
def conn_comit( connection ):
done = False
try_count = 0.0
while not done:
try:
connection.commit()
done = True
except sqlite.IntegrityError:
# Ignore this error because it means the item already exists in the database
done = True
except Exception, error:
if try_count%60.0 == 0.0: # print error every minute
print "\t" , "Error executing command" , cmd_str
print "Message:" , error
if try_count%120.0 == 0.0: # if waited for 2 miutes, roll back
print "Forcing Unlock"
connection.rollback()
time.sleep(0.05)
try_count += 0.05
##################
#### Run Code ####
##################
connection = sqlite.connect( db_path )
cursor = connection.cursor()
# Create tables if database does not exist
conn_exec( connection , cursor , '''CREATE TABLE IF NOT EXISTS fix (path TEXT PRIMARY KEY);''')
conn_exec( connection , cursor , '''CREATE TABLE IF NOT EXISTS tx (path TEXT PRIMARY KEY);''')
conn_exec( connection , cursor , '''CREATE TABLE IF NOT EXISTS completed (fix DATE, tx DATE);''')
conn_comit( connection )
应该是数据库的内部问题… 对我来说,这是在尝试用“SQLite管理器”浏览数据库后表现出来的… 所以,如果你找不到另一个连接到数据库的进程,你也无法修复它, 试试这个激进的解决方案:
提供导出您的表(您可以在Firefox上使用“SQLite管理器”) 如果迁移改变了数据库方案,请删除上次失败的迁移 重命名“数据库”。sqlite”文件 执行“rake db:migrate”创建一个新的工作数据库 提供给正确的权限数据库表的导入 导入备份的表 编写新的迁移 执行"rake db:migrate"
我的锁是由系统崩溃引起的,而不是由挂起进程引起的。为了解决这个问题,我简单地重命名了文件,然后将其复制回原来的名称和位置。
使用Linux shell将是:
mv mydata.db temp.db
cp temp.db mydata.db
正如Seun Osewa所说,有时僵尸进程会占用终端中的锁,即使您认为这是不可能的。您的脚本运行,崩溃,然后返回到提示,但是在某个库调用生成了一个僵尸进程,并且该进程拥有锁。
关闭您所在的终端(在OSX上)可能有用。重启就可以了。你可以寻找(例如)没有做任何事情的“python”进程,并杀死它们。
删除-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文件,并更改内容以指示是否有要回滚的部分事务。