10

我确定我遗漏了一些非常明显的东西,但我无法终生阻止我的 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 次更新。这显着减少了锁定的发生率,减少到每小时不到一次,而不是每分钟一次左右。我想我可以通过确保在读取其他脚本中的数据时将写入数据的时间偏移几秒钟来走得更远,但基本上我正在解决一个问题,因为我认为它不需要超时,这并不似乎还是不对。塔。

4

4 回答 4

6

在 pysqlite 的早期版本中,timeout参数 tosqlite.connect显然被解释为毫秒。所以你timeout=30.0应该是timeout=30000

于 2010-09-07T13:56:26.920 回答
1

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

于 2010-05-12T21:08:08.067 回答
0

SQLite 对每次写入(更新/插入/删除/...)使用数据库锁定。恕我直言,这个锁会一直持有到交易结束。这是跨线程/进程持有的单锁,A​​FAIK。

因此,我会尝试显式结束事务和连接以编写脚本,甚至在阅读脚本时显式提交并尝试调试并发问题。

于 2010-04-08T09:51:06.363 回答
0

您的 sqlite3 可能会被编译,而HAVE_USLEEP这会使并发线程在重试之前等待几秒钟。https://beets.io/blog/sqlite-nightmare.html

于 2021-05-18T21:51:55.153 回答