首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQLite WAL模式,后台线程上的检查点,wal-日志永不缩小

SQLite WAL模式,后台线程上的检查点,wal-日志永不缩小
EN

Stack Overflow用户
提问于 2014-03-26 21:52:23
回答 1查看 3.7K关注 0票数 3

SQLite文档指出(这里)可以通过在单独的线程上运行检查点来避免检查点在WAL模式下的停顿。我尝试过这一点,但它似乎不起作用:“-wal”文件在没有绑定的情况下增长,还不清楚是否有任何内容实际上被复制回主数据库文件,(最重要的是)在-wal文件变得足够大(超过千兆字节)之后,主线程开始等待检查指针。

在我的应用程序中,主线程连续地执行一些与此基本等价的操作,其中generate_data将列出要插入的一百万行的顺序:

代码语言:javascript
运行
复制
db = sqlite3.connect("database.db")
cursor = db.cursor()
cursor.execute("PRAGMA wal_autocheckpoint = 0")
for datum in generate_data():
    # It is a damned shame that there is no way to do this in one operation.
    cursor.execute("SELECT id FROM strings WHERE str = ?", (datum.text,))
    row = cursor.fetchone()
    if row is not None:
        id = row[0]
    else:
        cur.execute("INSERT INTO strings VALUES(NULL, ?)", (datum.text,))
        id = cur.lastrowid
    cursor.execute("INSERT INTO data VALUES (?, ?, ?)",
                   (id, datum.foo, datum.bar))
    batch_size += 1
    if batch_size > batch_limit:
        db.commit()
        batch_size = 0

检查点线程执行以下操作:

代码语言:javascript
运行
复制
db = sqlite3.connect("database.db")
cursor = db.cursor()
cursor.execute("PRAGMA wal_autocheckpoint = 0")
while True:
    time.sleep(10)
    cursor.execute("PRAGMA wal_checkpoint(PASSIVE)")

(在不同的线程上,它们必须有到数据库的单独连接,因为pysqlite不支持在多个线程之间共享连接。)更改为完全检查点或重新启动检查点没有帮助--那么检查点就会失败。

我该怎么做才能真正做到这一点?需要: 1)主线程不需要等待,2)日志文件在没有绑定的情况下不会增长。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-27 08:03:10

检查点需要锁定整个数据库,因此必须阻止所有其他读取器和写操作。(被动检查点刚刚中止。)

因此,在单独的线程中运行检查点不会增加并发性。( SQLite文档提出这一点只是因为主线程可能不适合在空闲时刻处理检查点。)

如果您继续访问数据库,则无法检查。如果批处理操作使WAL文件变得太大,则应该在该循环中插入显式检查点(或依赖自动检查点)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22673833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档