git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8c37e44)
Set ReorderBufferTXN->final_lsn more eagerly
2020年1月17日 21:00:39 +0000 (18:00 -0300)
2020年1月17日 21:00:39 +0000 (18:00 -0300)
... specifically, set it incrementally as each individual change is
spilled down to disk. This way, it is set correctly when the
transaction disappears without trace, ie. without leaving an XACT_ABORT
wal record. (This happens when the server crashes midway through a
transaction.)

Failing to have final_lsn prevents ReorderBufferRestoreCleanup() from
working, since it needs the final_lsn in order to know the endpoint of
its iteration through spilled files.

Commit df9f682c7bf8 already tried to fix the problem, but it didn't set
the final_lsn in all cases. Revert that, since it's no longer needed.

Author: Vignesh C
Reviewed-by: Amit Kapila, Dilip Kumar
Discussion: https://postgr.es/m/CALDaNm2CLk+K9JDwjYST0sPbGg5AQdvhUt0jbKyX_HdAE0jk3A@mail.gmail.com


diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 332c1ff4f5bdbe8c1a2bdec8e7059c3006a6571a..cbef6f0f448c18354af3cb227872058c7706a54d 100644 (file)
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -1908,21 +1908,6 @@ 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 */
@@ -2445,8 +2430,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
sz += sizeof(SnapshotData) +
sizeof(TransactionId) * snap->xcnt +
- sizeof(TransactionId) * snap->subxcnt
- ;
+ sizeof(TransactionId) * snap->subxcnt;
/* make sure we have enough space */
ReorderBufferSerializeReserve(rb, sz);
@@ -2519,6 +2503,17 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
}
pgstat_report_wait_end();
+ /*
+ * Keep the transaction's final_lsn up to date with each change we send to
+ * disk, so that ReorderBufferRestoreCleanup works correctly. (We used to
+ * only do this on commit and abort records, but that doesn't work if a
+ * system crash leaves a transaction without its abort record).
+ *
+ * Make sure not to move it backwards.
+ */
+ if (txn->final_lsn < change->lsn)
+ txn->final_lsn = change->lsn;
+
Assert(ondisk->change.action == change->action);
}
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index 7787edf7b67cde762bab7388ad938d9b95ebffab..c41f36217897c21fed3dfbef5bf6e626a4a6f8ee 100644 (file)
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -179,9 +179,10 @@ typedef struct ReorderBufferTXN
* * prepared transaction commit
* * plain abort record
* * prepared transaction abort
- * * error during decoding
- * * for a crashed transaction, the LSN of the last change, regardless of
- * what it was.
+ *
+ * This can also become set to earlier values than transaction end when
+ * a transaction is spilled to disk; specifically it's set to the LSN of
+ * the latest change written to disk so far.
* ----
*/
XLogRecPtr final_lsn;
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /