Skip to content

Replication-apply / full-copy re-encode mints shared structures off the saveStructures CAS (root cause behind #1506) #1508

Description

@kriszyp

Summary

The replication-receive thread builds its own in-memory classic shared-structures dictionary (its replication-stream / full-copy encounter order) without reconciling through RecordEncoder.saveStructures. Under concurrent v4→v5 upgrade write load this order diverges from the canonical durable order the local HTTP-write thread commits, and because the divergent dictionary is never persisted (and never reloaded — see #1506), every subsequent decode on that thread hits a present-but-wrong structure → Unexpected end of MessagePack data / Data read, but end of buffer not reached → reads return null and the node wedges.

This is the creation path for the divergence that #1506 recovers from. #1506 makes the condition self-healing (durable-wins reload on decode); this issue is the prevention.

Evidence

4-node 4.7.34 → 5.1.14 in-place rolling upgrade @ 100 w/s. On the wedged node, structure-level instrumentation showed:

  • The forking thread is the replication-receive thread ([replication] Connected to wss://…, Requesting full copy of database data, received and broadcasting committed update from …).
  • That thread never appears in saveStructures (no CAS commit for the table) yet holds a complete in-memory named dictionary that is a permutation of durable (same shapes, different ids) — e.g. in-memory id0 = [tags,id,name,…] vs durable id0 = [level,items,child].
  • The local HTTP-write thread does all the saveStructures commits, monotonic and faithful → durable is canonical.

Proposed fix

Make the replication-apply / full-copy re-encode path reconcile structures through the same CAS every other writer uses — i.e. adopt the durable dictionary before minting, and persist any new structure via saveStructures (so all workers converge on one order) — rather than building a private in-memory order. Pairs with the #1455 seed fix (separate issue) so workers start from one canonical order.

Refs #1506, #1453, #1445

— filed by KrAIs (Claude) on Kris's behalf

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:replicationReplication, clusteringarea:storageStorage engine, LMDB/RocksDB, compactionbugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions