首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >量化程序使用 SQLite WAL:三个容易忽略的问题

量化程序使用 SQLite WAL:三个容易忽略的问题

原创
作者头像
量化行业新引擎
发布于 2026-09-28 11:05:50
发布于 2026-09-28 11:05:50
890
举报
文章被收录于专栏:AI量化视界AI量化视界

个人量化程序的数据量通常不算大,用 SQLite 保存行情、信号和回测结果很方便,不需要单独维护数据库服务。不过,当程序从单脚本拆成行情、策略和交易几个进程后,偶尔会遇到 `database is locked`。很多人第一反应是开启 WAL,但 WAL 只能改善读写并发,并不能让多个进程随意同时写入。

WAL 不是“无限并发写”

WAL 模式下,读取和写入可以同时进行,但同一时间仍然只有一个写入者。如果一个进程开启事务后又去请求行情接口,写锁会一直被占着,其他进程只能等待。

比较稳妥的做法是:网络请求和数据计算放在事务外,事务里只执行必要的 SQL,并尽快提交。

python

import sqlite3

conn = sqlite3.connect("quant.db", timeout=5)

conn.execute("PRAGMA journal_mode=WAL")

conn.execute("PRAGMA busy_timeout=3000")

# 先在事务外完成接口请求和指标计算

rows = [("000001.SZ", "2026-09-28", 10.52)]

with conn:

conn.executemany(

"INSERT OR REPLACE INTO daily_bar(symbol, trade_date, close) "

"VALUES (?, ?, ?)",

rows,

)

`busy_timeout` 可以缓解几百毫秒的短暂竞争,但解决不了长事务。如果锁冲突频繁,更合适的结构是让多个进程负责计算,统一把写入任务交给一个进程处理。

不要只复制主数据库文件

WAL 模式运行时,尚未合并的内容可能还在 `quant.db-wal` 中。程序运行期间只复制 `quant.db`,得到的备份可能缺少最近的数据。Python 可以直接使用 SQLite Backup API:

python

source = sqlite3.connect("quant.db")

target = sqlite3.connect("quant-backup.db")

source.backup(target)

target.close()

source.close()

备份完成后,建议实际打开备份库,查询最新交易日和关键表行数。能成功复制不等于能正常恢复。

注意 WAL 文件持续变大

SQLite 默认会自动执行检查点,把 WAL 中的内容合并回主数据库。如果某个读取任务长时间不结束,例如遍历多年分钟线却一直保持同一个事务,检查点可能无法完成,WAL 文件就会持续增长。

因此,长时间分析任务最好分批读取并及时结束事务,同时监控 `-wal` 文件大小。WAL 还依赖共享内存文件,只适合在同一台机器上使用,不应把数据库放到网络共享目录后让多台服务器共同读写。

对单机、小规模量化任务来说,SQLite WAL 仍然很实用。关键不是多加几次重试,而是缩短写事务、集中写入、正确备份,并避免长时间占用读取事务。超过这些边界后,再考虑迁移到服务端数据库会更省心。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • WAL 不是“无限并发写”
  • 不要只复制主数据库文件
  • 注意 WAL 文件持续变大
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档