【问题标题】:sqlite, accessing a single DB file from multiple processessqlite,从多个进程访问单个数据库文件
【发布时间】:2018-04-21 05:20:26
【问题描述】:

我有一个设置,将 消息 从 ONE 进程发送到 OTHER 进程,发送由以下人员完成:

  1. 将消息添加到sqlite数据库
  2. 将消息发送到下一个进程
  3. 从 sqlite 数据库中删除 消息

为了测试,我将 4 个 filter 和一个最终的 server 连接在一起,服务器只会回显消息……所有这些都是 2x4+1=9 insert 并在 4+1=5 个过程中在很短的时间内删除。所有 5 个进程都使用具有私有数据库句柄的 same 数据库。为了至少完成 一些 步骤……我为每个新的 sql 操作打开并关闭 db-handel。如果我不这样做并且我不使用 WAL 事务格式,sqlite 数据库总是在 2 步后失败。

简而言之,sqlite 每次都失败...... sqlite 工作了几个步骤,但最终以无限的 SQLITE_BUSY 结束。我尝试了很多不同的配置……我的最新编译指示是:

EXEC(4,"PRAGMA synchronous  = NORMAL    ;")
EXEC(5,"PRAGMA journal_mode = WAL       ;")
EXEC(6,"PRAGMA locking_mode = NORMAL    ;")

典型的输出是:

  1. ft0-3 是 过滤器
  2. sv0 是 服务器
  3. transLId 是 sqlite rowid
  4. db 是职责中的数据库句柄

例子……

---- service-2-2-(1|binary|uds|c.uds.spawn) start
S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlInsertReadTrans }: START insert: db<(nil)>
S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlInsertReadTrans }: DONE  insert: db<0x24e0f98>, transLId<1>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlInsertReadTrans }: START insert: db<(nil)>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlInsertReadTrans }: DONE  insert: db<0xa096a8>, transLId<2>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlInsertReadTrans }: START insert: db<(nil)>
S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlDeleteReadTrans }: START delete: db<0x24e0328>, transLId<1>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlInsertReadTrans }: SQLITE_BUSY:  db<0x1018bc8>
S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlDeleteReadTrans }: DONE  delete: db<0x24e0328>, transLId<1>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlInsertReadTrans }: DONE  insert: db<0x1018bc8>, transLId<3>
S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlInsertReadTrans }: START insert: db<(nil)>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: START delete: db<0xa08d08>, transLId<2>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlInsertReadTrans }: DONE  insert: db<0x1ffc028>, transLId<4>
S> {sv0         :pid(64418):tid(0x7f275dffc780):B:dlv(0):ctxId( 0):rc(2):ctx(0x2045be0     ):pSqlInsertReadTrans }: START insert: db<(nil)>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: START delete: db<0x1017858>, transLId<3>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
S> {sv0         :pid(64418):tid(0x7f275dffc780):B:dlv(0):ctxId( 0):rc(2):ctx(0x2045be0     ):pSqlInsertReadTrans }: DONE  insert: db<0x204ec78>, transLId<5>
S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlDeleteReadTrans }: START delete: db<0x1ffb2a8>, transLId<4>
S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlDeleteReadTrans }: DONE  delete: db<0x1ffb2a8>, transLId<4>
C> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(1):ctx(0x1ff4a60     ):pSqlInsertReadTrans }: START insert: db<(nil)>
C> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(1):ctx(0x1ff4a60     ):pSqlInsertReadTrans }: DONE  insert: db<0x1ffe8c8>, transLId<6>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>

问题:有什么想法可以走得更远?

【问题讨论】:

  • 你从来没有提到过busy_timeout。为什么要使用针对单个作者优化的数据库?
  • 我现在没有设置“busy_timeout”……但我在 SQLITE_BUSY 后“休眠”了 10000 微秒……
  • 添加... EXEC(1,"PRAGMA busy_timeout = 10 ;") 没有帮助。
  • 为什么是 10 毫秒?试试 10000。
  • pragma 值为 "ms" = 毫秒 = 10^-3……但我已经测试过了……没有任何帮助……

标签: sqlite


【解决方案1】:

first 评论是我的答案……使用带有“#memdb#”的 sqlite 是 no 问题……但是……no 可以持久化。

  # This fails with a FILE based database… "sqlite" is NOT able to share a database 
  # with multiple processes or threads
  test service-2-2-($I|$B|$C|$S) {mass "@" with TRANSACTION} \
      -setup {
        #set testdb  [file join . [file tail [MakeFile {} .dat]]]
        set testdb  "#memdb#"
        set CON1    [list {*}[FindFreeConnection $S] --storage $testdb]

        set cmd     [list {*}[getFilter Filter3.$S] --name "ft0" {*}$CON1 @]
        foreach i {1 2 3} {
          lappend cmd Filter3 --storage $testdb --name "ft$i" @
        }
        lappend cmd {*}[getServer $S] --storage $testdb --name "sv0"

        proc otFWRD {ctx} {
          $ctx Send "R" "I" [$ctx StorageCount]
        }
        set RET ""
        proc otRESU {ctx} {
          $ctx ReadT_START
          lappend ::RET [$ctx ReadC]
          $ctx ReadT_END
          lappend ::RET [$ctx ReadI]
        }
        Bg @stderr {*}$cmd
        foreach {FIRST CTX} [Create $I $CON1] break
      } \
      -body           {
        $CTX ServiceCreate FWRD otFWRD
        $CTX ServiceCreate RESU otRESU
        $CTX Send "T" RESU "FWRD:(C)" ident
        $CTX ProcessEvent -wait ONCE
        $CTX ProcessEvent -wait ONCE
        set RET
      } \
      -cleanup {
        rename $FIRST ""
      } \
      -returnCodes    ok \
      -result         "ident 1"

【讨论】:

    猜你喜欢
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 2017-04-27
    相关资源
    最近更新 更多