SQLite 3.53:修掉一个 WAL 损坏 bug,顺手给 CLI 换了套表格

SQLite 3.53 修掉了一个 WAL 重置导致数据库损坏的 bug,新增结果格式化库 QRF,ALTER TABLE 可以增删约束,还多了一个 REINDEX EXPRESSIONS。最后这条是修复陈旧表达式索引的关键。

SQLite 3.53.0 是 2026 年 4 月 9 日发的。最该看的一条在列表最前面:

修掉 WAL-reset 数据库损坏 bug。

这句话没有解释、没有 CVE 号,但「数据库损坏」四个字在 SQLite 的发布说明里出现,就值得所有用它存重要数据的人升级一次。

ALTER TABLE 能改约束了

以前 SQLite 的 ALTER TABLE 能力非常有限 —— 能加列、能改名,改约束基本只能「建新表、搬数据、换名」。3.53 起可以:

  • 添加 NOT NULL 与 CHECK 约束
  • 移除 NOT NULL 与 CHECK 约束

这两件事在别的数据库里是日常操作,在 SQLite 里一直是「迁移脚本里最脏的一段」。

REINDEX EXPRESSIONS:修陈旧表达式索引

新增的 REINDEX EXPRESSIONS 用来重建表达式索引。

表达式索引(CREATE INDEX ... ON t(lower(name)))的麻烦在于:它的内容由表达式算出来,一旦表达式依赖的东西变了(比如自定义函数的实现改了、或者 COLLATE 行为变了),索引里存的值就和实际算出来的值对不上了 —— 查询结果会错,而且不报错。

以前唯一的办法是 DROP INDEX 再 CREATE INDEX。现在有一条专门的语句。

TEMP 触发器能碰主库表了

临时表上的触发器,现在可以修改或查询主 schema 里的表。以前不行,这让「用临时表做审计/影子表」的写法受限。

VACUUM INTO 能指定预留空间

VACUUM INTO 如果目标用 URI 文件名并带 reserve=N(0–255),生成的副本就按 N 预留空间。听起来很小,但 SQLite 的 reserve 是「每页末尾留多少字节给未来增长」——它影响的是数据库以后会不会因为一次更新而被迫分裂页。做副本时能对齐原库的设置,是有意义的。

QRF:CLI 终于有个正经的表格

新增一个 Query Result Formatter(QRF)库,用来把 SQL 结果格式化成人看的固定宽度表格。TCL 接口加了 format 方法,CLI 也用它。

具体效果:

  • 交互式 CLI 的默认输出模式换成 QRF,用 Unicode 制表符画框
  • 数值默认右对齐
  • 批处理会话仍然用旧格式(为了兼容脚本)

最后一条是克制的体现:改默认输出会打断所有解析 CLI 输出的脚本,所以他们只在交互模式下改。

一条不兼容

点命令结尾的裸分号现在被静默忽略。

也就是说 .tables; 不再报错,而是当成 .tables。这被官方标为「潜在不兼容」—— 如果你的脚本依赖那个分号导致报错来检测什么,就会静默失效。

我的判断

对绝大多数用 SQLite 的项目,这次升级的理由就是第一条。WAL 重置是 VACUUM、检查点、以及某些恢复路径都会碰到的机制,它出问题意味着正常操作下也可能损坏数据。

REINDEX EXPRESSIONS 是第二条值得单独记的。表达式索引出问题时的症状是「结果静默错误」,而不是崩溃 —— 这种 bug 最难发现,也最需要一个专门的重建命令。

← 返回文章列表

评论

…