[YSQL] [Buffering] AbortSubTransaction flushes buffered operations instead of dropping them
#31.655 aberto em 15 de mai. de 2026
Métricas do repositório
- Stars
- (8.229 stars)
- Métricas de merge de PR
- (Mesclagem média 17d 21h) (92 fundiu PRs em 30d)
Description
Jira Link: DB-21409
Problem
In AbortSubTransaction() (src/postgres/src/backend/access/transam/xact.c:5604), the
call chain on subtransaction abort flushes buffered operations to the tserver
before clearing them, instead of just dropping them:
AbortSubTransaction() // xact.c:5604
...
AtSubAbort_Snapshot(s->nestingLevel) // xact.c:5743
-> YBCOnActiveSnapshotChange() // snapmgr.c:1172
-> YBCPgRestoreReadPoint(handle) // snapmgr.c:326
-> PgApiImpl::RestoreReadPoint() // pggate.cc:2682
-> FlushBufferedOperations(...) // pggate.cc:2683 <-- FLUSH (not clear)
-> pg_txn_manager_->RestoreReadPoint // pggate.cc:2684
YBCRollbackToSubTransaction(s->subTransactionId) // xact.c:5746
-> PgApiImpl::RollbackToSubTransaction() // pggate.cc:2258
-> ClearSessionState() // pggate.cc:2259
-> pg_session_->ClearState() // pggate.cc:2663
-> buffer_.Clear() // pg_session.cc:731 <-- DROP
Since the subtransaction is being aborted, the buffered operations are going to be rolled back anyway. Flushing them to the tserver first is wasted work and can also cause spurious errors / side effects to surface from operations that were destined to be discarded.
Proposal
Move the YBCRollbackToSubTransaction(s->subTransactionId) call at
xact.c:5746 to before the if (s->curTransactionOwner) { block at
xact.c:5698, so that the buffered operations are dropped (via
buffer_.Clear()) before AtSubAbort_Snapshot() runs and triggers
FlushBufferedOperations().
This way RestoreReadPoint has nothing left in the buffer to flush, and we
get the intended "drop, not flush" behavior on subtransaction abort.