SQLite文档指出(这里)可以通过在单独的线程上运行检查点来避免检查点在WAL模式下的停顿。我尝试过这一点,但它似乎不起作用:“-wal
”文件在没有绑定的情况下增长,还不清楚是否有任何内容实际上被复制回主数据库文件,(最重要的是)在-wal
文件变得足够大(超过千兆字节)之后,主线程开始等待检查指针。
在我的应用程序中,主线程连续地执行一些与此基本等价的操作,其中generate_data
将列出要插入的一百万行的顺序:
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
检查点线程执行以下操作:
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)日志文件在没有绑定的情况下不会增长。
发布于 2014-03-27 08:03:10
检查点需要锁定整个数据库,因此必须阻止所有其他读取器和写操作。(被动检查点刚刚中止。)
因此,在单独的线程中运行检查点不会增加并发性。( SQLite文档提出这一点只是因为主线程可能不适合在空闲时刻处理检查点。)
如果您继续访问数据库,则无法检查。如果批处理操作使WAL文件变得太大,则应该在该循环中插入显式检查点(或依赖自动检查点)。
https://stackoverflow.com/questions/22673833
复制相似问题