Skip to content

Transaction messages are stamped with begin SCN, filtering open transactions #330

Description

@Naros

Affected: 2.0.0 (current master), works with 1.9.0 and earlier

Summary

Since commit 34fd536, every message belonging to a transaction is stamped with that transaction's begin SCN rather than the LWN SCN at the point of commit.

Because Writer::mainLoop filters outgoing messages with metadata->isNewData(msg->lwnScn, msg->lwnIdx), any transaction whose begin SCN is below the client's confirmed/continued position is discarded in its entirety when it commits, including changes made after that position. Nothing is logged on this path.

Checkpoint messages still carry the parser's lwnScn (Parser.cpp:1513), so checkpoints and change data are now stamped from two different clocks, and the stream is no longer monotonic in SCN. In one measurement against Debezium, 979 of 3279 change messages arrived at an SCN below a checkpoint the client had already received.

Impact

A client that confirms a position derived from delivered data (that was safe in 1.9), since those positions were monotonic, will permanently lose any transaction that was open at that point. A short transaction that begins later but commits first is enough to advance the client's position past an older open transaction's begin SCN.

This is silent data loss on reconnect, not merely reordering.

Questions

It looks like collateral of the parameter-list refactor rather than a deliberate protocol change:

  • The commit's stated purpose is the scn-type / timestamp-type config fields.
  • No CHANGELOG entry mentions a change to message filtering or ordering.
  • Fromat::SCN_TYPE (including the DEBEZIUM preset) affects payload fields only; Builder.cpp:701 assigns lwnScn = beginScn unconditionally, with no scnType check, so the behavior cannot be configured back.

If it is intentional, could you explain what position a client is expected to CONFIRM and resume from so that in-flight transactions are not lost? transactionBuffer->checkpoint computes minSequence / minFileOffset / minXid, which is close to what a client would need, but it is only written to the internal state file and is expressed as redo coordinates plus an XID rather than an SCN.

How to reproduce

  1. Client connects and straems, note its confirmed position P.
  2. On session A, INSERT a row without committing (transaction T, begin SCN < P is not required, it only needs to begin before the client's position advances past it).
  3. Let the client advance past T's begin SCN via any other committed transaction.
  4. Commit T

T's rows are never delivered. With 1.9.0 they are delivered normally.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions