【问题标题】:Python / SQLite - database locked despite large timeoutsPython / SQLite - 尽管超时时间很大,但数据库仍被锁定
【发布时间】:2011-02-05 15:04:53
【问题描述】:

我确定我遗漏了一些非常明显的东西,但我无法终生阻止我的 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()ing,而不是在选择脚本上提交。最终,因为我只有一个脚本实际上进行了任何修改,所以我真的不明白为什么会发生这种锁定。我注意到,随着时间的推移,当数据库变得更大时,情况会变得更糟。它最近是 13 MB,有 3 个大小相同的表,大约是 1 天的数据量。创建一个新文件显着改善了这一点,这似乎可以理解,但最终似乎并没有遵守超时。

非常感谢任何指针。

编辑:自从询问以来,我已经能够稍微重构我的代码并使用信号在每 5 秒一次事务中定期写入 0 到 150 次更新。这显着减少了锁定的发生,与每分钟左右一次相比,每小时少于一次。我想我可以通过确保在读取其他脚本中的数据时将写入数据的时间偏移几秒钟来走得更远,但基本上我正在解决一个问题,因为我认为它不需要超时,这并不似乎还是不对。塔。

【问题讨论】:

    标签: python database sqlite locked


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我当然更愿意使用合适的数据库,但由于各种原因无法使用。
    • 好吧,那就做好一些慢的准备吧。实在没办法。
    【解决方案3】:

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

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

    【讨论】:

    • 你的意思是关闭整个数据库?持有锁我很好,但两个脚本都没有等待足够长的时间来释放锁。
    • 是的,我的意思是从正在写入的连接关闭到数据库的连接。
    • 好吧,我每隔几秒钟就写入一次数据库,肯定关闭它不会真正改变任何东西吗?打开和关闭还有额外的工作,所以这不会让情况变得更糟吗?而且,如果我在关闭之前提交更改,那么关闭它也没有任何好处,因为它不再被锁定。
    • 当然 - 我只是在解释这个问题,因为您确定没有竞争条件。但正如我现在所读的那样——您的应用程序相对写入量大,并发读写不适合 sqlite,所以对于这个用例,我会更改数据库。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-06
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      相关资源
      最近更新 更多