SQLite persistence: peer row notice drops metadata for another row
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 48/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- sqlite, typescript
调研方向
Start with packages/db-sqlite-persistence-core/tests/sync-metadata-session-persisted.test.ts and its persisted receiving driver, then read the shared law, model, grammar, and comparison in packages/db/tests/sync-metadata-session-oracle.ts. Run the supplied Vitest replay command to reproduce the missing row 2 metadata at the peer checkpoint. Done means the replay passes after the repair, fails on the parent, and a hostile mutant fails at that checkpoint.
由索引模型根据 Issue 内容生成。
描述
Describe the bug
The persisted sync-metadata session oracle found a history in which a peer row notice for row 1 makes row 2's metadata disappear from the source-facing read. At that checkpoint, the model expects row 2's earlier metadata write to remain visible.
Found by the random SQLite core campaign in PR #2314's CI job. The exact replay also fails on the PR's merge-base, so the indexing changes in #2314 do not introduce this failure.
To reproduce
From the repository root, run:
TANSTACK_DB_ORACLE_PROPERTY=sync-metadata-session.persisted-peers \
TANSTACK_DB_ORACLE_SEED=346038028 \
TANSTACK_DB_ORACLE_PATH=36:2:4:6:10:14:16:14:14:13:13:13 \
pnpm --filter @tanstack/db-sqlite-persistence-core exec vitest run \
tests/sync-metadata-session-persisted.test.ts \
--coverage.enabled=false --typecheck.enabled=false --maxWorkers=2
Verified on both commits:
| Tree | Commit | Result |
|---|---|---|
| PR #2314 | a0d2c4e3780307a770ef7734b64a2d4adf5bd3ce |
Same metadata assertion failure; 37 other tests pass and one existing expected failure remains |
| Unchanged merge-base | bfd1da1a7e752d66fd667adfd3cdf54f60732b22 |
Same failure at the same checkpoint; 37 other tests pass and one existing expected failure remains |
The base run used a complete git archive snapshot with the same installed dependencies and the package's source aliases. Neither the production code nor the oracle was changed for either replay.
Fast-check originally failed after 37 generated histories and shrank 11 times. Both direct replays fail after one history, without further shrinking.
The first failing prefix, with zero-based step 11 as the final action:
[
{ "type": "seed", "key": 2, "narrow": false, "bare": true },
{ "type": "begin" },
{ "type": "begin" },
{ "type": "rowSet", "key": 2 },
{ "type": "commit" },
{ "type": "upsert", "key": 2, "metadata": false },
{ "type": "commit" },
{ "type": "commit" },
{ "type": "truncate" },
{ "type": "collectionDelete", "key": "cursor" },
{ "type": "release" },
{ "type": "peer", "key": 1, "notice": "row", "keepsValue": true }
]
The generated counterexample continues with commit, another identical peer action, a bare seed for key 1, collectionSet(cursor), and release. The mismatch occurs before that suffix executes.
Expected and actual behavior
The existing sync-metadata session contract gives the source read-your-writes and own reads in serialization order. The shared model requires this source-facing metadata.row.get observation at the peer checkpoint:
law: source reads its row metadata (metadata.row.get)
at step 11 (peer)
expected: {"1":{"peer":{"s":11}},"2":{"s":3}}
actual: {"1":{"peer":{"s":11}},"2":"<absent>"}
Row 1's peer metadata agrees. Row 2's metadata is missing. This is a reproducible assertion mismatch, not a timeout or setup error. The root cause has not been diagnosed.
Additional context
- Production path:
persistedCollectionOptions, with an in-memory persistence adapter and a controlled peer notice through the coordinator. - Persisted receiving driver.
- Shared law, model, grammar and comparison.
- The observation is source-facing row metadata. This controlled witness does not establish durable row loss or behavior with two real browser coordinators; that receiving coverage is tracked separately in #2272.
- CI used Ubuntu and Vitest/jsdom; local replay used macOS, Vitest 4.1.12 and fast-check 3.23.2.
Keep this trace as a replay through the existing model, driver and comparison during the repair. Show RED on the parent, GREEN after the fix, and a hostile mutant that fails at the metadata checkpoint.
- 主要语言
- TypeScript
- 星标
- 4k
- 派生
- 277
- 平均合并
- 1 天 7 小时
- 30 天内合并 PR
- 176
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
TanStack/db 的其他 Issue
-
难度 1/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
OfflineExecutor.dispose() never settles pendingTransactionPromises可能重新可做 @Claire-ovo 于 8 天前认领,目前没有进行中的 PR。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
Two @tanstack/db tests time out under CPU load because a cold module import counts against the 5 s default timeout可能已有人在做 @jp-knj 于 6 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 52/100
维护者通常 1 天内回复
相似的 Issue
-
needs investigation
难度 2/5 1-3 小时 新手友好度 60/100
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
area:visualizer tech-debt
难度 2/5 1 小时以内 新手友好度 66/100
jmbarzee/temporal-architect#292 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 66/100
riverqueue/river#1576 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
colbymchenry/codegraph#3228 ·
维护者通常 1 天内回复