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