SQLite persistence: peer row notice drops metadata for another row

未关闭
#2,317 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
sqlite, typescript
领域
databases, testing

调研方向

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

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

TanStack/db 的其他 Issue

查看 TanStack/db 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。