Update minimum recovery point on truncation during WAL replay of abort record.
authorFujii Masao <[email protected]>
Wed, 28 Jul 2021 16:35:52 +0000 (01:35 +0900)
committerFujii Masao <[email protected]>
Wed, 28 Jul 2021 16:35:52 +0000 (01:35 +0900)
If a file is truncated, we must update minRecoveryPoint. Once a file is
truncated, there's no going back; it would not be safe to stop recovery
at a point earlier than that anymore.

Commit 7bffc9b7bf changed xact_redo_commit() so that it updates
minRecoveryPoint on truncation, but forgot to change xact_redo_abort().

Back-patch to all supported versions.

Reported-by: [email protected]
Author: Fujii Masao
Reviewed-by: Heikki Linnakangas
Discussion: https://postgr.es/m/b029fce3-4fac-4265-968e-16f36ff4d075[email protected]

src/backend/access/transam/xact.c

index e75062e0f96e0c7c94e12198e10bbc0c6c21a6c8..2ccb582100e1399181e0bb7db4d2330d93b58f33 100644 (file)
@@ -5545,7 +5545,8 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
  * because subtransaction commit is never WAL logged.
  */
 static void
-xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
+xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
+               XLogRecPtr lsn)
 {
    TransactionId max_xid;
 
@@ -5607,7 +5608,16 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
    }
 
    /* Make sure files supposed to be dropped are dropped */
-   DropRelationFiles(parsed->xnodes, parsed->nrels, true);
+   if (parsed->nrels > 0)
+   {
+       /*
+        * See comments about update of minimum recovery point on truncation,
+        * in xact_redo_commit().
+        */
+       XLogFlush(lsn);
+
+       DropRelationFiles(parsed->xnodes, parsed->nrels, true);
+   }
 }
 
 void
@@ -5651,12 +5661,12 @@ xact_redo(XLogReaderState *record)
        if (info == XLOG_XACT_ABORT)
        {
            Assert(!TransactionIdIsValid(parsed.twophase_xid));
-           xact_redo_abort(&parsed, XLogRecGetXid(record));
+           xact_redo_abort(&parsed, XLogRecGetXid(record), record->EndRecPtr);
        }
        else
        {
            Assert(TransactionIdIsValid(parsed.twophase_xid));
-           xact_redo_abort(&parsed, parsed.twophase_xid);
+           xact_redo_abort(&parsed, parsed.twophase_xid, record->EndRecPtr);
            RemoveTwoPhaseFile(parsed.twophase_xid, false);
        }
    }