Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux SQLite问题-DB已锁定解决方法_Linux_Sqlite - Fatal编程技术网

Linux SQLite问题-DB已锁定解决方法

Linux SQLite问题-DB已锁定解决方法,linux,sqlite,Linux,Sqlite,我有两个进程连接到同一个数据库。 第一个用于从数据库读取数据,第二个用于写入数据库。 在linux上,第一个进程通过消息队列将要执行的写过程发送给第二个进程 在prepare、step、finalize例程中执行每个SQL语句;准备和步骤在10000次循环中进行,直到成功(这样做是为了克服数据库锁定问题) 要添加表,请执行以下步骤: 第一个进程通过msg-q向第二个进程发送请求,以添加一个表并以journal_mode=OFF模式在其行中插入垃圾 然后,第一个进程检查现有表,以便它可以继续其算法

我有两个进程连接到同一个数据库。 第一个用于从数据库读取数据,第二个用于写入数据库。 在linux上,第一个进程通过消息队列将要执行的写过程发送给第二个进程

在prepare、step、finalize例程中执行每个SQL语句;准备和步骤在10000次循环中进行,直到成功(这样做是为了克服数据库锁定问题)

要添加表,请执行以下步骤:

  • 第一个进程通过msg-q向第二个进程发送请求,以添加一个表并以journal_mode=OFF模式在其行中插入垃圾

  • 然后,第一个进程检查现有表,以便它可以继续其算法。(在迭代之间,它使用usleep命令在循环中检查它。)

  • 问题是第二个进程卡在“PRAGMA journal_mode=OFF;”的执行步骤中因为它说DB是锁定的(在这里,我也使用usleep的10000次迭代来检查10000次DB的空闲时间,正如我前面提到的)

    当我向“检查现有表”循环中的第一个进程添加关闭连接的操作时,第二个进程就可以了。但现在,当我添加表和值时,有时会在Step语句中得到“callbackrequestedqueryabort”


    这里发生了什么有什么帮助吗?

    使用WAL模式。它允许一个作者和任意数量的读者没有任何问题。您不需要检查锁定状态并执行重试等操作

    WAL限制:数据库必须位于本地驱动器上

    性能:大型事务(1000次插入或类似)比经典的回滚日志慢,但除此之外,速度非常相似,有时甚至更好。感知性能(等待DB写入完成的UI)显著提高

    WAL是一项新技术,但已经用于Firefox、Adroid/iOS手机等。我用两个线程全速运行进行了测试,一个线程在写,另一个线程在读,没有遇到任何问题


    当采用WAL模式时,您可以简化应用程序。

    当另一个进程正在向数据库写入数据时,您的进程可能希望关闭日志模式。在关闭日志模式之前,请尝试执行回滚。第一个进程没有写入数据库,只有一个用于读取数据库的连接。第二个进程是关闭日志模式并稍后写入该数据库的进程。在等待写入的过程中,是否有任何结果集/游标在读卡器端打开?可能是读取进程正在从数据库读取,并且有一个sqlite3 stmt打开,但为什么它会干扰写入进程?无论如何,我检查了在journal\u mode=WAL和journal\u mode=OFF中写入DB的性能,没有太大的差异。最终,WAL速度更快,因此我使用它而不是关闭日记模式。我发现WAL速度与关闭速度一样快。我必须快速,因为在init过程中我必须构建所有表,并在运行时更新其中的值。是否有加快初始化过程的建议?init过程不必像运行时过程那样稳定,因此数据库可能有损坏的风险。在没有任何日志的情况下运行(在init期间)怎么样?您还可以使用PRAGMA synchronous=0和locking_mode=EXCLUSIVE。然后用标准设置和WAL重新打开DB。关于并发性的更多信息:我发现了一个奇怪的问题:当connection1打开读取(未完成的准备语句),然后connection2进行一些写入,然后connection1必须关闭(完成)读取才能进行写入。听起来有点复杂,但一般的教训很简单:只要读写是在不同的连接中完成的,没有并发问题。我们已启用WAL并看到此异常。您的sqlite3可能在编译时没有
    have_USLEEP
    ,这会使并发线程在重试前等待数秒,并导致超时。