fix: v0.6.0 复查修正 — KVStore 快照损坏水位 bug(metaSeq 误跳日志)+ 快照损坏测试盲区修复(此前篡改未生效)+ metaSeq 回归测试 + KVStoreEngine 真实浏览器 e2e(3 用例)+ 版本/配置文档校准
This commit is contained in:
Vendored
+8
-23
@@ -980,10 +980,6 @@ class SharedMemoryBackend {
|
||||
static clearRegistry() {
|
||||
registry.clear();
|
||||
}
|
||||
/** 注册表中的库数量(测试诊断用) */
|
||||
static registrySize() {
|
||||
return registry.size;
|
||||
}
|
||||
async open(name) {
|
||||
this.dbName = name;
|
||||
if (!registry.has(name)) {
|
||||
@@ -1396,10 +1392,6 @@ class KVStore {
|
||||
this.medium = medium ?? defaultMedium();
|
||||
this.checkpointThreshold = checkpointThreshold;
|
||||
}
|
||||
/** 底层介质(测试/诊断用) */
|
||||
getMedium() {
|
||||
return this.medium;
|
||||
}
|
||||
isOpen() {
|
||||
return this.opened;
|
||||
}
|
||||
@@ -1415,17 +1407,8 @@ class KVStore {
|
||||
this.index = new Map();
|
||||
this.seq = 0;
|
||||
this.logBytes = 0;
|
||||
// 1. 读 meta(可能缺失/损坏)
|
||||
let metaSeq = 0;
|
||||
const metaRaw = await this.medium.read(META_KEY);
|
||||
if (metaRaw) {
|
||||
try {
|
||||
const meta = JSON.parse(new TextDecoder().decode(metaRaw));
|
||||
metaSeq = Number(meta.seq) || 0;
|
||||
}
|
||||
catch { /* meta 损坏:回退全量日志 */ }
|
||||
}
|
||||
// 2. 加载快照(损坏则全量日志重放)
|
||||
// 1. 加载快照(损坏则全量日志重放;快照内嵌 seq 为日志水位权威)
|
||||
// meta(checkpoint 写入)仅标记库存在,不参与水位判断
|
||||
let snapshotSeq = 0;
|
||||
const snapshotRaw = await this.medium.read(SNAPSHOT_KEY);
|
||||
if (snapshotRaw) {
|
||||
@@ -1443,10 +1426,15 @@ class KVStore {
|
||||
}
|
||||
}
|
||||
// 3. 重放日志(seq > 快照水位的记录)
|
||||
// v0.6.1-fix: 快照水位只信任快照内嵌 seq(snapshotSeq)。
|
||||
// 此前 baseSeq = max(metaSeq, snapshotSeq):快照损坏回退全量重放时,
|
||||
// meta.seq(最后一次 checkpoint 水位)会错误跳过日志中 checkpoint 后
|
||||
// 的有效记录(日志被截断过,metaSeq 不代表日志内容水位)→ 丢数据。
|
||||
// meta 仅在库存在性标记,不参与水位判断。
|
||||
const logRaw = await this.medium.read(LOG_KEY);
|
||||
if (logRaw && logRaw.byteLength > 0) {
|
||||
const log = new Uint8Array(logRaw);
|
||||
const baseSeq = Math.max(metaSeq, snapshotSeq);
|
||||
const baseSeq = snapshotSeq;
|
||||
const corruptOffsets = [];
|
||||
const applied = parseLogRecords(log, (record) => {
|
||||
if (record.seq <= baseSeq)
|
||||
@@ -1517,9 +1505,6 @@ class KVStore {
|
||||
size() {
|
||||
return this.index.size;
|
||||
}
|
||||
getSeq() {
|
||||
return this.seq;
|
||||
}
|
||||
// =======================================================================
|
||||
// 写入(原子事务)
|
||||
// =======================================================================
|
||||
|
||||
Reference in New Issue
Block a user