IndexedDB 底下那台发动机换了:Chrome 150 用 SQLite 顶替 LevelDB——API 一行没变,同一数据库的写事务并发行为变了

Chrome 的 IndexedDB 底层已经不是 LevelDB 了。2026 年 4 月 27 日,Chromium 在 blink-dev 发出 Web-Facing Change PSA:IndexedDB 实现整个重写在 SQLite 之上,替换掉原来「LevelDB + 平面文件」的混合方案。Chrome 150(2026 年 6 月 30 日进稳定版)起,新写入的数据存储都落在 SQLite。Web API 一行没变,但有一处 web 可见的行为跟着变了——同一数据库上的并发 readwrite 事务,从「可能并行」变成「整库排队」,和 Firefox、Safari 完全对齐。

十五年前为 Chrome 而生的 LevelDB,到站了

LevelDB 是 2011 年 Jeffrey Dean 和 Sanjay Ghemawat 写的键值存储,写它的动机之一就是给 Chrome 的 IndexedDB 当引擎。十五年过去,Chromium 团队在 PSA 里给它的评语很直白:

  • 实现「高度依赖一个不再被维护、也不具备完整关系型数据库能力的引擎」;
  • 「许多复杂 web 应用报告高发的丢数据、数据损坏」,老龄后端的 bug 难查难修;
  • SQLite 有活跃的开发团队和社区,原生事务支持本身就是可靠性的底牌。

关键是:Firefox 和 Safari 的 IndexedDB 从来就是 SQLite(PSA 里 Gecko 和 WebKit 的状态都是 Shipped)。Chromium 换过去之后,三大引擎的 IndexedDB 底层终于一致——同一批数据在 Safari 里好好的、在 Chrome 里偶发损坏的那个悬案,根源大概率在这。

三步走:现在刚走完第二步

阶段 内容 时间
第 1 步 无痕/内存上下文先用 SQLite,限制新 bug 影响面,暂不碰磁盘数据迁移 PSA 2025-12
第 2 步 新数据存储写入 SQLite,存量 LevelDB 数据不动 PSA 2026-04-27;DevTrial 在 Chrome 148,随 Chrome 150 进稳定版
第 3 步 把 LevelDB 里的存量数据迁移到 SQLite 未启动,届时单独发 PSA

注意第 2 步的语义:只对新 store 生效。用户的老数据还躺在 LevelDB 里,新旧两套并行。如果你的站点愿意丢弃本地缓存(本来就是服务端数据的小缓存),清一次站点数据就能立刻跑上新后端;不想丢数据,就等第 3 步。

唯一一处 web 可见的变化:同库写事务不再并行

PSA 原话说这次改动包含一个「关于 IDB 事务调度边界情况的 web 可见行为变化」,新旧行为都符合规范,Chromium 只是对齐了 Firefox 和 Safari。官方对照 demo(idb-txn-scopes)把话说得更明白:

  • 规范只规定了一组基础调度约束;
  • 旧 Chromium 更宽松:同一数据库上多个 readwrite 事务,哪怕操作的是不同 object store,也允许重叠执行;
  • Firefox/Safari 一直更严格:同一数据库的 readwrite 事务整体互斥;
  • 「出于 ACID 方面的技术原因,Chromium 正在向其他浏览器看齐。」

before(Chrome 150 之前,两个事务可能同时跑):

const db = await openDB('shop');
const txA = db.transaction(['orders'], 'readwrite');
const txB = db.transaction(['carts'], 'readwrite');
txA.objectStore('orders').put(order, 1); // 旧 Chrome:A、B 可能并行
txB.objectStore('carts').put(cart, 1);

after(Chrome 150 起,同一个 db 的两个 readwrite 事务整库排队,和 Firefox/Safari 一样):

// 官方 take-away:要并发写,就拆成两个数据库,而不是同一库两个 object store
const dbOrders = await openDB('orders-db');
const dbCarts  = await openDB('carts-db');
// 或者用 Storage Buckets 给每个写入路径单独隔离

如果你的页面把高吞吐写入寄托在同库多事务并行上,升到 Chrome 150 之后排队会拉长尾延迟——这正是官方建议改用不同 database(或 Storage Buckets)而不是同库分 store 的原因。

性能特征全会变,但方向要你自己测

PSA 点名了这些都会变化的量:可靠性、运行时 + CPU 占用、内存、磁盘访问、存储占用,「具体变化因站点用法而异」。它特别警告了一个场景:在设备能力极限上运行的应用(例如极端存储受限硬件上的 kiosk 应用),换引擎后可能真的撞墙。

没变的部分:Web API、DevTools 的 IndexedDB 面板、按 origin 分桶的数据隔离;新旧两套实现都重新过了 fuzz 测试,WPT 的 IndexedDB 套件全程覆盖。

接下来做什么

  1. 跑一遍官方 demo,对比「旧 Chrome / Chrome 150+ / Firefox / Safari」四份结果,确认没有依赖同库并行写的隐性假设;
  2. 吞吐敏感的写路径评估分库或 Storage Buckets;
  3. 盯第 3 步迁移的单独 PSA——存量数据搬家那天,磁盘占用和首次访问行为还会再变一次。

参考来源:blink-dev Web-Facing Change PSA: IndexedDB: SQLite backend(2026-04-27);Chrome 150 Beta 发布说明;官方 demo evanstade.github.io/web-storage-demos/idb-txn-scopes;ChromeStatus feature 5161589557821440,tracking bug 498644996。

评论区

0 条评论

登录后可评论。

铁锈·Rust工具链 21 阅读