SQLite 运行模式

SQLite 从日志模式(journal_mode) 、同步模式(synchronous) 、访问模式 两个维度划分,工程上最核心是 journal_mode,其次是synchronous。

一、Journal 日志模式

(核心,决定锁机制、读写并发、掉电安全)

1. DELETE(删除模式,默认旧版)

PRAGMA journal_mode;

  • 原理:传统回滚日志。写事务前把原始数据写入xxx-journal文件;事务提交后,直接删除journal文件。

  • 锁:全局库锁,写的时候所有读阻塞。

  • 特点:

    • 无额外shm/wal文件

    • 读写互斥,并发差

    • 事务崩溃恢复依赖journal

  • ✅适用:低频率写入,简单日志

  • ❌不推荐你的场景:高频JT808/J1939报文写入,容易database is locked

2. WAL 预写日志模式

PRAGMA journal_mode=WAL;

  • 原理:修改先写入wal文件(xxx-wal),不直接改写主db;读从主文件读,写追加到wal。检查点(checkpoint)时机,把wal数据合并入主库。

  • 锁机制:读和写可以并发,写仍然是串行(同一时间只能一个写事务)

  • 产生文件:xxx.db + xxx.db-wal + xxx.db-shm(共享内存文件)

  • 优势:

    1. 大幅降低database is locked,一边写报文、一边查询待上传数据互不阻塞

    2. 事务提交更快

  • 缺点:

    1. 多2个附属文件,异常断电wal文件可能残留

    2. 只读文件系统不能使用WAL

  • WAL三个检查点模式:PASSIVE / FULL / RESTART / TRUNCATE PRAGMA wal_autocheckpoint=1000; 写满N页自动触发checkpoint

3. PERSIST 持久日志

journal文件提交后不删除,仅清空内容,减少文件创建销毁开销。锁机制同DELETE。

适合大量短事务频繁开关场景,现在WAL基本替代它。

4. TRUNCATE 截断日志

提交事务时把journal文件截断为0,不是删除。和DELETE行为接近。

5. MEMORY 内存日志

回滚日志直接放在内存,磁盘只存主db。

  • 崩溃直接丢事务数据,掉电不安全

  • 速度快;只适合临时内存数据库,车载业务禁止。

二、Synchronous 同步模式

(掉电安全等级,配合WAL一起配置)

PRAGMA synchronous = ?;控制操作系统刷盘策略

模式 说明 掉电风险 性能 推荐场景
FULL 每次事务提交强制刷磁盘,OS缓存落盘 最低 最慢 关键数据,安全优先
NORMAL WAL模式:仅checkpoint阶段刷盘;事务提交不强制刷盘 中等 均衡 ✅车载终端推荐
OFF 完全不刷盘,交给OS缓存 极高,断电极易库损坏 最快 仅临时日志,禁止存原始报文

工程最佳组合:journal_mode=WAL + synchronous=NORMAL 兼顾写入速度 + 崩溃恢复能力,商用车盒子通用方案。

三、数据库访问模式(打开模式)

  1. File-based 文件模式 (你在用的) jdbc:sqlite:/data/vehicle/terminal.db,持久化到闪存,重启数据保留。

  2. 内存模式 :memory: 数据库完全在内存,无磁盘文件,进程退出/断电全部丢失。 适合临时统计、临时缓存,不能存JT808原始报文。

  3. 只读打开模式 PRAGMA query_only = true; 或连接串指定只读。用于单独读取待上传数据,不允许写入。

四、锁模式补充(WAL下的锁)

WAL模式下有4种锁,按顺序:

  1. SHARED 共享锁:读

  2. RESERVED:准备写

  3. PENDING:等待现有读结束

  4. EXCLUSIVE排他锁:写事务执行阶段

WAL读不阻塞写,写不阻塞读 ,但是同一时刻只能1个写事务。所以业务层依然要做单写队列,防止多线程并发写报locked。

五、其它重要PRAGMA配套(车载常用)

复制代码
-- WAL开启
PRAGMA journal_mode=WAL;
-- 同步等级
PRAGMA synchronous=NORMAL;
-- 缓存页大小
PRAGMA cache_size=-2000; -- 单位KB,设置缓存
-- 开启外键(默认关闭,业务不需要可以关掉节省开销)
PRAGMA foreign_keys=OFF;
-- 自动checkpoint
PRAGMA wal_autocheckpoint=500;

六、选型决策表(直接用于方案文档)

方案组合 并发读写 掉电安全 写入性能 适用场景
DELETE + FULL 读写互斥,差 高 慢 极少写入,简单日志
WAL + FULL 读写并发 高 中等 ADAS报警事件(重要告警不能丢)
WAL + NORMAL 读写并发 中等 优秀 ✅JT808/J1939高频报文,断网缓存
WAL + OFF 读写并发 低 极快 临时统计数据,原始报文不可用

七、工程坑点

  1. WAL模式下直接复制db文件备份会损坏,备份前要执行PRAGMA wal_checkpoint(FULL);

  2. 只读分区无法启用WAL,会自动回退DELETE模式,锁冲突大量出现

  3. shm/wal文件权限问题:车载linux下进程要有读写权限,否则WAL启用失败

  4. WAL会持续增大wal文件,需要定时checkpoint,不然占用存储空间

如果你需要,我可以补充:

  1. Java启动SQLite时自动设置WAL+同步模式代码

  2. WAL checkpoint自动回收脚本

  3. 数据库损坏检测与修复SQL脚本。

相关推荐
zzu123zsw10 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号11 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场11 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠12 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David13 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放13 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog13 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友
用户37215742613513 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java
小嘉丶学长14 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
字节探索14 小时前
Spring Boot 接口幂等性设计:从唯一索引到 Redis+Lua 的工程实践
java·spring boot