【问题标题】:SQLite C++ 'database is locked' when multiple processes access db in readonly mode当多个进程以只读模式访问数据库时,SQLite C++'数据库被锁定'
【发布时间】:2014-12-10 07:26:45
【问题描述】:

我有一个 不会改变的 sqlite 数据库。

多个进程使用 sqlite3_open_v2 在 SQLITE_OPEN_READONLY 模式下打开数据库连接。每个进程都是单线程的

连接是使用官方 C/C++ Interface 的单一合并 C 源文件从 MSVC 项目建立的。

根据 SQLite 常见问题解答multiple processes running SELECTs is fine

打开数据库后的每个进程都会创建 4 个准备好的 SELECT 语句,每个语句都有 2 个可绑定值。

在执行过程中,语句(一次一个)会根据需要重复调​​用以下语句

  • sqlite3_bind_int
  • sqlite3_bind_int
  • sqlite3_step(返回 SQLITE_ROW 时)
  • sqlite3_column_int(当有一行时)
  • sqlite3_reset

准备好的语句被重用,所以直到程序快结束时才对它们中的每一个调用 finalize。最后,数据库在执行结束时关闭。

问题是任何这些操作都可能失败,error code = 5: 'database is locked'

错误代码 5 是 SQLITE_BUSY,网站声明

“表示与单独的数据库连接发生冲突,可能在单独的进程中”

互联网上的其他人似乎都同意多个 READONLY 连接是可以的。我翻遍了源代码,看不出有什么问题(很遗憾,我不能在这里发布,我知道,没有帮助)

所以我把它交给你们,我可能会错过什么?

编辑 1: 数据库在本地驱动器上,文件系统是 NTFS,操作系统是 Windows 7。

编辑 2: 将所有 sqlite3 调用包装在无限循环中,检查是否返回了 SQLITE_BUSY,然后重新调用可以缓解问题。我不认为这是一个解决办法,但如果这确实是正确的做法,那么我会这样做。

【问题讨论】:

  • 在打开数据库之前,尝试调用sqlite3_config(SQLITE_CONFIG_SERIALIZED) 看看会发生什么。
  • 或者,在您的sqlite3_open 中执行SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX
  • 你在使用 LinQ 吗?
  • QLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX 根本没有帮助。源定义 SQLITE_THREADSAFE 1 所以 sqlite3_config(SQLITE_CONFIG_SERIALIZED) 不会有任何区别,1 是序列化的。

标签: c++ sql database sqlite


【解决方案1】:

所以我使用的有效答案是将所有对 sqlite 的调用包装在函数中,这些函数在返回 SQLITE_BUSY 时循环该函数。似乎没有一个简单的替代方案。

const int bindInt(sqlite3_stmt* stmt, int parameterIndex, int value)
{
    int ret;
    do
        ret = sqlite3_bind_int(stmt, parameterIndex, value);
    while (ret == SQLITE_BUSY)
    return ret;
}

【讨论】:

  • 你不断地敲击数据库,直到你没有得到 SQLITE_BUSY 所以我怀疑你可能会看到 CPU 使用率的巨大峰值。是这样吗?如果是这样,添加一个非常小的睡眠时间(比如 1 毫秒)可能会有所帮助。
  • 考虑过,但我添加了一个计数器,在我的测试中没有看到任何重试多次。不过建议不错,会做更多测试。
  • 这可能是有效的方法,因为在阅读此链接后:dba.stackexchange.com/questions/24340/… 它说:“当任何进程想要写入时,它必须在更新期间锁定整个数据库文件. 但这通常只需要几毫秒。其他进程只是等待作者完成然后继续他们的业务。为了安全起见,可能“其他进程”也应该有一个内部超时来指示数据库没有响应。
  • 在我的情况下没有写作。只有多个进程读取。
  • 所以我最近才发现这个东西,虽然sqlite.org/capi3ref.html#sqlite3_busy_handler没能成功
猜你喜欢
  • 1970-01-01
  • 2015-05-06
  • 2013-12-26
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 2011-08-05
相关资源
最近更新 更多