【发布时间】:2014-03-26 21:52:23
【问题描述】:
SQLite 文档说 (here) 可以通过在单独的线程上运行检查点来避免 WAL 模式下的检查点暂停。我试过这个,但它似乎不起作用:'-wal'文件无限增长,不清楚是否有任何东西实际上被复制回主数据库文件,以及(最重要的)在-wal之后文件已经变得足够大(超过 1 GB),主线程开始不得不等待检查指针。
在我的应用程序中,主线程不断地做一些与此基本相同的事情,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 不支持在多个线程之间共享连接。)更改为 FULL 或 RESTART 检查点没有帮助 - 然后检查点就会失败。
我怎样才能让它真正发挥作用?需要:1) 主线程永远不必等待,2) 日志文件不会无限制地增长。
【问题讨论】:
-
有趣。是否仅在示例代码中省略了事务?
-
@mlvljr Python sqlite 绑定隐藏了事务。如果事务未打开,则每个 INSERT 都会隐式执行 BEGIN,并且每次
batch_limit迭代,对db.commit的调用都会发出一个 COMMIT。
标签: python multithreading sqlite journal