5.0.10 exception log claims "discarded" for operations that replayed OK
Commit 9cc70cd ("spock_apply: surface real exception_log cause, not
'unavailable'", in v5.0.10, states "Diagnostic change only:
discard/disable/LSN behaviour is unchanged") replaces the former
unavailable placeholder with discard_collateral_message():
discard: tuple discarded due to exception at command_counter N
discard: statement discarded due to exception at command_counter N
Under exception_behaviour = discard these rows are the other
operations of an errored transaction — which are replayed in
subtransactions and, when they succeed, are applied (demonstrated
above on 5.0.9 where the same rows said unavailable; on our 5.0.10
subscriber, row-level checksums AND a full information_schema.columns
checksum, 8,303 columns, are identical between provider and subscriber
despite ~20k "discarded" entries).
Operators reading "tuple discarded" for tuples that were in fact applied
cannot distinguish real data loss from noise — during our incident triage
this initially read as a whole-transaction discard (entry count ≈ 2 × the
failing command_counter). Suggested: log replayed-OK operations as
applied on exception replay (or similar), reserve "discarded" for
operations that were genuinely not applied, and document the semantics.
If tuples ARE genuinely discarded in some paths despite the observations
above, that contradiction is worth clarifying in the docs either way.
Environment
- provider: pgEdge PG 17.10, spock 5.0.9 (
ghcr.io/pgedge/pgedge-postgres:17-spock5-standard)
- subscribers: same image, spock 5.0.9 (lab) and 5.0.10 (production)
spock.enable_ddl_replication=on, spock.include_ddl_repset=off,
spock.exception_behaviour=discard, spock.exception_logging=all
- subscriptions bind
{<custom repset>, default, default_insert_only, ddl_sql}
5.0.10 exception log claims "discarded" for operations that replayed OK
Commit 9cc70cd ("spock_apply: surface real exception_log cause, not
'unavailable'", in v5.0.10, states "Diagnostic change only:
discard/disable/LSN behaviour is unchanged") replaces the former
unavailableplaceholder withdiscard_collateral_message():Under
exception_behaviour = discardthese rows are the otheroperations of an errored transaction — which are replayed in
subtransactions and, when they succeed, are applied (demonstrated
above on 5.0.9 where the same rows said
unavailable; on our 5.0.10subscriber, row-level checksums AND a full information_schema.columns
checksum, 8,303 columns, are identical between provider and subscriber
despite ~20k "discarded" entries).
Operators reading "tuple discarded" for tuples that were in fact applied
cannot distinguish real data loss from noise — during our incident triage
this initially read as a whole-transaction discard (entry count ≈ 2 × the
failing command_counter). Suggested: log replayed-OK operations as
applied on exception replay(or similar), reserve "discarded" foroperations that were genuinely not applied, and document the semantics.
If tuples ARE genuinely discarded in some paths despite the observations
above, that contradiction is worth clarifying in the docs either way.
Environment
ghcr.io/pgedge/pgedge-postgres:17-spock5-standard)spock.enable_ddl_replication=on,spock.include_ddl_repset=off,spock.exception_behaviour=discard,spock.exception_logging=all{<custom repset>, default, default_insert_only, ddl_sql}