aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/replication/logical/reorderbuffer.c19
-rw-r--r--src/include/replication/reorderbuffer.h2
2 files changed, 19 insertions, 2 deletions
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index fcc41ddb7c9..1208da29727 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -1670,8 +1670,8 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid)
* Iterate through all (potential) toplevel TXNs and abort all that are
* older than what possibly can be running. Once we've found the first
* that is alive we stop, there might be some that acquired an xid earlier
- * but started writing later, but it's unlikely and they will cleaned up
- * in a later call to ReorderBufferAbortOld().
+ * but started writing later, but it's unlikely and they will be cleaned
+ * up in a later call to this function.
*/
dlist_foreach_modify(it, &rb->toplevel_by_lsn)
{
@@ -1681,6 +1681,21 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid)
if (TransactionIdPrecedes(txn->xid, oldestRunningXid))
{
+ /*
+ * We set final_lsn on a transaction when we decode its commit or
+ * abort record, but we never see those records for crashed
+ * transactions. To ensure cleanup of these transactions, set
+ * final_lsn to that of their last change; this causes
+ * ReorderBufferRestoreCleanup to do the right thing.
+ */
+ if (txn->serialized && txn->final_lsn == 0)
+ {
+ ReorderBufferChange *last =
+ dlist_tail_element(ReorderBufferChange, node, &txn->changes);
+
+ txn->final_lsn = last->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 f52a88dcd64..0970abca52a 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
+ * * for a crashed transaction, the LSN of the last change, regardless of
+ * what it was.
* ----
*/
XLogRecPtr final_lsn;