新创建SQLite数据库出现database is locked错误求助
SQLite数据库锁定错误排查:新创建数据库也报
sqlite3.OperationalError: database is locked 问题背景
一段稳定运行多年的Python代码近期突发异常:即使创建全新SQLite数据库,也会触发sqlite3.OperationalError: database is locked错误。相关代码片段:
dbfile = os.path.expanduser(dbfile) import sqlite3 as sqlite dbsetup = not os.path.isfile(dbfile) conn = sqlite.connect(dbfile) c = conn.cursor() if dbsetup: c.execute("create table counters (module text, counter int)") c.execute("select counter from counters where module = '%s'" % name) r = c.fetchone()
调用y=global_counter('x','~/test.db')时的报错栈:
y=global_counter('x','~/test.db')
Traceback (most recent call last):
File "", line 1, in
File "/data/jwst/scheduling/tools/com/spss_sys_util.py", line 1227, in global_counter
c.execute("create table counters (module text, counter int)")
sqlite3.OperationalError: database is locked
可能原因
- 文件系统权限不足:目标目录(如
~/)的读写权限变更,导致运行代码的进程无法创建数据库文件或SQLite锁文件,触发锁定错误。 - SQLite临时锁文件残留:之前的异常运行可能留下
test.db-journal、test.db-wal等临时锁文件,即使原数据库文件不存在,这些残留文件也会导致锁冲突。 - 未关闭的数据库连接:
global_counter函数未正确关闭数据库连接(无conn.close()),多次调用后残留的连接持有锁,新请求无法获取锁。 - 文件系统异常:存储设备挂载为只读、磁盘空间耗尽或IO错误,导致SQLite无法完成数据库创建和锁操作。
- 并发访问冲突:其他进程(如定时任务、同进程的其他线程)同时尝试访问/创建同一个数据库文件,触发SQLite的锁机制。
排查方向
- 验证目录权限:执行
ls -ld ~确认目标目录权限,用touch ~/test_perm_check.txt测试是否能在目录下创建文件,确保运行代码的用户有读写权限。 - 清理临时文件:检查目标目录下是否存在
*.db-journal、*.db-wal、*.db-shm类文件,手动删除后重试代码。 - 修复连接管理:改用
with语句自动管理连接(with sqlite.connect(dbfile) as conn:),确保每次调用后连接被自动释放;或在代码末尾添加conn.close()。 - 排查并发进程:用
lsof ~/test.db(若文件已创建)或fuser ~/查看是否有其他进程占用相关文件/目录。 - 检查文件系统状态:执行
df -h确认磁盘空间,mount查看挂载模式,检查系统日志(/var/log/messages或dmesg)是否有IO错误。 - 修复SQL注入隐患:原代码用字符串拼接生成SQL语句,存在注入风险,改为参数化查询:
c.execute("select counter from counters where module = ?", (name,))。
内容的提问来源于stack exchange,提问作者Don Chance
相关产品推荐
相关产品推荐

