Python / SQLite - 尽管有大量超时,数据库已锁定

时间:2010-04-08 09:35:09

标签: python database sqlite locked

我确定我错过了一些非常明显的东西,但我不能为我的生活停止我的pysqlite脚本崩溃与数据库锁定错误。我有两个脚本,一个用于将数据加载到数据库中,另一个用于读取数据,但两者都会频繁地立即崩溃,具体取决于另一个脚本在任何给定时间对数据库执行的操作。我将两个脚本的超时设置为30秒:

cx = sqlite.connect("database.sql", timeout=30.0)

并且我认为我可以看到一些超时的证据,我得到了一个似乎是时间戳(例如0.12343827e-06 0.1 - 以及如何阻止被打印?)偶尔在我的诅咒中间倾倒格式化的输出屏幕,但没有延迟,在30秒超时附近远程,但仍然其中一个一次又一次地从此崩溃。我在64位4 CPU HS21 IBM刀片上运行RHEL 5.4,并且听说过有关多线程问题的一些提及,我不确定这是否相关。正在使用的软件包是sqlite-3.3.6-5和python-sqlite-1.1.7-1.2.1,升级到Red Hat官方规定之外的新版本对我来说不是一个好选择。可能,但由于整体环境不可取。

我之前在两个脚本中都有过autocommit=1,但之后两者都被禁用了,我现在cx.commit()插入脚本而不是提交选择脚本。最终,因为我只有一个脚本实际上做了任何修改,我真的不明白为什么这种锁定应该发生。我注意到随着时间的推移,当数据库变得更大时,情况会更糟。它最近是13 MB,有3个相同大小的表,这是大约1天的数据。创建一个新文件已经显着改善了这一点,这似乎是可以理解的,但最终似乎没有遵守超时。

任何指针都非常赞赏。

编辑:因为我要求我能够稍微重构我的代码并使用信号在每5秒一次事务中定期写入0到150次更新。这显着地减少了锁定的发生,小于一小时而不是每分钟一次。我想我可以进一步确保写入数据的时间在我读取其他脚本中的数据时偏移了几秒钟,但从根本上我正在解决一个问题,因为我对它进行了调整,不需要超时,这不会看起来还不错。 TA

4 个答案:

答案 0 :(得分:3)

在pysqlite的早期版本中,timeout的{​​{1}}参数显然被解释为毫秒。因此,sqlite.connect应为timeout=30.0

答案 1 :(得分:1)

SQLite根本没有针对大量写入工作负载进行优化,也没有假装(但它不介意在一个事务中写得太多)。听起来,你可能已经到了需要切换到MySQL,PostgreSQL,Oracle或DB2等其他数据库的地步。其中一些选项确实很昂贵,但对于某些工作负载而言,这正是您所需要的。 (另请注意,使用专用数据库服务器解决方案也可以更好地完成大量写入工作负载,尽管这会增加部署成本和复杂性。有些事情只是成本。)

答案 2 :(得分:0)

SQLite为每次写入使用数据库锁定(update / insert / delete / ...)。恕我直言,此锁定一直持续到交易结束。这是跨线程/进程AFAIK持有的单个锁。

因此,我尝试显式结束用于编写脚本的事务和连接,并在读取脚本时显式提交并尝试调试并发问题。

答案 3 :(得分:0)

您的 sqlite3 可能在没有 create_filter <- function(dat, Species, Sepal.Width = NA, ...){ lst_arg <- list(dat, Species, Sepal.Width, ...) if (!"data.frame" %in% class(dat)){ stop("First input must be dataframe") } ln <- Sepal.Width sp <- Species args <- enquos(...) ex_args <- unname(imap(args, function(expr, name) quo(!!sym(name)==!!expr))) dat <- dat %>% filter(!!!ex_args) if(is.na(Sepal.Width) && (Species == 'setosa')){ dat %>% filter(Species == 'setosa' & Sepal.Width > 5 )} else{ dat %>% filter(Sepal.Width %in% (ln),Species %in% (sp)) } } 的情况下编译,这会使并发线程在重试之前等待几秒钟。 https://beets.io/blog/sqlite-nightmare.html