You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么通过Lua脚本访问SQLite会删除WAL模式下的-wal文件?

核心原因

WAL文件被删除的根本原因是Lua脚本中打开的数据库连接未启用WAL模式:SQLite的journal_mode是连接级配置,仅在C侧的连接上设置WAL模式不生效,Lua脚本调用lsqlite3.open()打开的是独立新连接,默认使用DELETE日志模式,该连接访问数据库时会自动将日志模式切回DELETE,直接删除现有-wal文件,之前在C侧设置的SQLITE_FCNTL_PERSIST_WAL对Lua侧的独立连接完全无效。

修复方案
  1. Lua侧打开数据库后第一时间设置与C++侧对齐的WAL相关参数,修改后的Lua脚本如下:
function prequire(name)
    local status, lib = pcall(require, name)
    if(status) then return lib end
    -- 加载库失败直接返回空
    return nil
end

print("start lua")

local sqlite3 = prequire("lsqlite3complete")
if sqlite3 == nil then
    print('No lsqlite3')
    return
end

local db = sqlite3.open('/data/data/ru.chromesearcher.sqlitewal/files/database.sqlite3')
if db == nil then
    print("db open failed")
    return
end

-- 新增WAL模式配置,和C++侧配置保持一致
db:exec([[
PRAGMA journal_mode=WAL;
PRAGMA synchronous=FULL;
]])

print("query start")

local stmt = db:prepare('SELECT * FROM paymentevents where pe_amount=?')
local amount = 3000
stmt:bind_values(amount)
stmt:finalize()

db:close()
  1. 如需全局启用WAL持久化,需在所有数据库连接(包括C++、Lua侧的所有连接)上都设置SQLITE_FCNTL_PERSIST_WAL参数,避免单个连接未配置导致规则失效。
  2. 配置后可执行PRAGMA journal_mode;查询返回值,确认返回结果为wal即可确认配置生效。
之前尝试无效的原因
  • PRAGMA locking_mode=EXCLUSIVE、synchronous=EXTRA均不影响日志模式的连接级特性,只要存在任意一个使用DELETE模式的连接访问数据库,就会触发WAL文件删除
  • 仅在C侧设置SQLITE_FCNTL_PERSIST_WAL仅作用于当前C连接,对Lua侧新建的独立连接不生效

内容的提问来源于stack exchange,提问作者chromesearcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 19:45:03