diff --git a/src/renderer/db/schema.ts b/src/renderer/db/schema.ts index a142b57..3faf359 100644 --- a/src/renderer/db/schema.ts +++ b/src/renderer/db/schema.ts @@ -37,10 +37,9 @@ export type RecentFile = { } // v0.5.0: 库名更换为 MarkLiteV2,与旧 Dexie 库(MarkLite)彻底隔离,旧数据已放弃 -// v0.6.0: 存储引擎改用 HybridEngine(write-through:内存读写 + 直写 IndexedDB)。 -// 弃用 AriaEngine 原因:其 SSTable/WAL 多 key 非原子写入在异常退出/强杀时 -// 留下半写文件,重启解析越界(offset is out of bounds)导致反复损坏。 -// Hybrid 每行单 key 原子写入 IDB,强杀/关闭中断不损坏(已实测)。 +// v0.6.1: 存储引擎回归 AriaEngine(LSM-Tree + WAL + MVCC 快照隔离,功能更强)。 +// 0.4.1 的 AriaEngine 在异常退出时留下半写 SSTable 导致重启解析越界; +// sqlark 0.4.2 已修复(残缺块跳过 + 打开时完整性校验 + 批量原子写入 + repair 自愈)。 const DB_NAME = 'MarkLiteV2' /** @@ -93,11 +92,13 @@ let initFailedNotified = false let healTriggered = false const RESET_PENDING_KEY = 'marklite-db-reset-pending' +// AriaEngine 的 IndexedDBBackend 内部库名 = `aria-${name}`(sqlark 源码约定) +const DB_STORAGE_NAME = `aria-${DB_NAME}` /** 删除损坏数据库(无活动连接时立即成功) */ function deleteStorageDatabase(): Promise { return new Promise(resolve => { - const req = indexedDB.deleteDatabase(DB_NAME) + const req = indexedDB.deleteDatabase(DB_STORAGE_NAME) req.onsuccess = () => resolve() req.onerror = () => resolve() req.onblocked = () => resolve() @@ -122,14 +123,13 @@ async function resetCorruptDatabaseIfNeeded(): Promise { async function createDatabase(): Promise { const db = await create({ name: DB_NAME, - mode: 'hybrid', // HybridEngine: write-through — 内存读写 + 直写 IndexedDB(每行单 key 原子写入,强杀不损坏) - diskEngine: 'indexeddb', - // v0.6.1: sqlark 0.4.2 版本自适应打开(VersionError 时自动解析当前版本重试) - version: 1, + mode: 'aria', // AriaEngine: LSM-Tree + WAL + MVCC 快照隔离(sqlark 0.4.2 已修复崩溃损坏问题) + diskEngine: 'indexeddb', // 底层存储后端(indexeddb | opfs | memory) + version: 0, // AriaEngine 忽略版本号(0 表示无 schema 迁移门槛) onError: (err: Error) => logError('数据库错误', err), }) - // 幂等建表(getTableNames 基于持久化的 __metona_schema,重启后不会重复升级版本) + // 幂等建表(getTableNames 基于持久化 schema,重启后不会重复建表) const tables = await db.getTableNames() if (!tables.includes('tabSnapshots')) await db.defineTable('tabSnapshots', TAB_SNAPSHOTS_COLUMNS) if (!tables.includes('settings')) await db.defineTable('settings', SETTINGS_COLUMNS)