diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 0f607ba..afa3874 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -1724,6 +1724,19 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid) if (TransactionIdPrecedes(txn->xid, oldestRunningXid)) { + /* + * The final_lsn of which transaction that hasn't produced an abort + * record is invalid. To ensure cleanup the serialized changes of + * such transaction we set the LSN of the last change action to + * final_lsn. + */ + if (txn->serialized && txn->final_lsn == 0) + { + ReorderBufferChange *last_change = + dlist_tail_element(ReorderBufferChange, node, &txn->changes); + txn->final_lsn = last_change->lsn; + } + elog(DEBUG2, "aborting old transaction %u", txn->xid); /* remove potential on-disk data, and deallocate this tx */ diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 86effe1..7931757 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -168,6 +168,8 @@ typedef struct ReorderBufferTXN * * plain abort record * * prepared transaction abort * * error during decoding + * Note that this can also be a LSN of the last change action of this xact + * if it is an implicitly aborted transaction. * ---- */ XLogRecPtr final_lsn;