From b814114ff012092ae4b872691b07cec5f6b3c8f5 Mon Sep 17 00:00:00 2001 From: thzxx Date: Sun, 9 Aug 2026 21:26:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AD=98=E5=82=A8=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E5=88=87=E5=9B=9E=20HybridEngine=20=E2=80=94=20AriaEngine=20SS?= =?UTF-8?q?Table=20=E5=A4=A7=20value=20=E7=BC=96=E7=A0=81=E7=BC=BA?= =?UTF-8?q?=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因(真实 Chromium 环境实测复现): - AriaEngine SSTableBuilder.computeBlockSize 用 JS 字符串 length 估算块大小, 实际写入为 UTF-8 字节(中文 1 字符 = 3 字节)→ finalSize 缓冲区低估 → 大文件内容(中文 markdown)flush 时写入越界(offset is out of bounds) - valueLen 为 u16(上限 64KB),大 value 长度截断 - 关闭时 flush 崩溃 → 半写 SSTable → 下次打开 DataView 越界 → ARIA_OPEN_ERROR HybridEngine 行级 IDB 存储无此限制(300KB 中文内容实测闭环正常) --- src/renderer/db/schema.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/renderer/db/schema.ts b/src/renderer/db/schema.ts index aca95e3..9b32678 100644 --- a/src/renderer/db/schema.ts +++ b/src/renderer/db/schema.ts @@ -37,9 +37,11 @@ export type RecentFile = { } // v0.5.0: 库名更换为 MarkLiteV2,与旧 Dexie 库(MarkLite)彻底隔离,旧数据已放弃 -// v0.6.1: 存储引擎回归 AriaEngine(LSM-Tree + WAL + MVCC 快照隔离,功能更强)。 -// 0.4.1 的 AriaEngine 在异常退出时留下半写 SSTable 导致重启解析越界; -// sqlark 0.4.2 已修复(残缺块跳过 + 打开时完整性校验 + 批量原子写入 + repair 自愈)。 +// v0.6.1: 存储引擎使用 HybridEngine(write-through 直写 IndexedDB)。 +// 弃用 AriaEngine:SSTable 构建的块大小按 JS 字符串 length 估算(非 UTF-8 字节), +// 且 valueLen 为 u16(上限 64KB)——大文件内容(中文 markdown)写入时 +// 缓冲区溢出崩溃(offset is out of bounds),关闭时 flush 半写导致下次打开 +// DataView 越界(ARIA_OPEN_ERROR)。等 sqlark 修复后回归 aria。 const DB_NAME = 'MarkLiteV2' /** @@ -97,8 +99,7 @@ let isClosing = false let initChain: Promise = Promise.resolve() const RESET_PENDING_KEY = 'marklite-db-reset-pending' -// AriaEngine 的 IndexedDBBackend 内部库名 = `aria-${name}`(sqlark 源码约定) -const DB_STORAGE_NAME = `aria-${DB_NAME}` +const DB_STORAGE_NAME = DB_NAME /** 删除损坏数据库(无活动连接时立即成功) */ function deleteStorageDatabase(): Promise { @@ -128,9 +129,9 @@ async function resetCorruptDatabaseIfNeeded(): Promise { async function createDatabase(): Promise { const db = await create({ name: DB_NAME, - mode: 'aria', // AriaEngine: LSM-Tree + WAL + MVCC 快照隔离(sqlark 0.4.2 已修复崩溃损坏问题) - diskEngine: 'indexeddb', // 底层存储后端(indexeddb | opfs | memory) - version: 0, // AriaEngine 忽略版本号(0 表示无 schema 迁移门槛) + mode: 'hybrid', // HybridEngine: 内存读写 + 直写 IndexedDB(行级存储,无 64KB 单值限制) + diskEngine: 'indexeddb', + version: 1, // IndexedDBEngine 需要合法版本号(0.4.2+ 打开时自动版本自适应) onError: (err: Error) => logError('数据库错误', err), })