1. Andrew Dunstan
  2. pgdevel

Commits

Simon Riggs  committed c2b3218

Update comments on rd_newRelfilenodeSubid.
Ensure comments accurately reflect state of code
given new understanding, and recent changes.
Include example code from Noah Misch to
illustrate how rd_newRelfilenodeSubid can be
reset deterministically. No code changes.

  • Participants
  • Parent commits ae9aba6
  • Branches master

Comments (0)

Files changed (2)

File src/backend/commands/copy.c

View file
  • Ignore whitespace
 	 * routine first.
 	 *
 	 * As mentioned in comments in utils/rel.h, the in-same-transaction test
-	 * is not completely reliable, since in rare cases rd_createSubid or
-	 * rd_newRelfilenodeSubid can be cleared before the end of the transaction.
+	 * is not always set correctly, since in rare cases rd_newRelfilenodeSubid
+	 * can be cleared before the end of the transaction. The exact case is
+	 * when a relation sets a new relfilenode twice in same transaction, yet
+	 * the second one fails in an aborted subtransaction, e.g.
+	 *
+	 * BEGIN;
+	 * TRUNCATE t;
+	 * SAVEPOINT save;
+	 * TRUNCATE t;
+	 * ROLLBACK TO save;
+	 * COPY ...
+	 *
 	 * However this is OK since at worst we will fail to make the optimization.
 	 *
 	 * Also, if the target file is new-in-transaction, we assume that checking
 		 * which subtransaction created it is crucial for correctness
 		 * of this optimisation.
 		 *
-		 * Note that because the test is unreliable in case of relcache reset
-		 * we cannot guarantee that we can honour the request to FREEZE.
-		 * If we cannot honour the request we do so silently, firstly to
-		 * avoid noise for the user and also to avoid obscure test failures.
+		 * As noted above rd_newRelfilenodeSubid is not set in all cases
+		 * where we can apply the optimization, so in those rare cases
+		 * where we cannot honour the request we do so silently.
 		 */
 		if (cstate->freeze &&
 			ThereAreNoPriorRegisteredSnapshots() &&

File src/include/utils/rel.h

View file
  • Ignore whitespace
 	/*
 	 * rd_createSubid is the ID of the highest subtransaction the rel has
 	 * survived into; or zero if the rel was not created in the current top
-	 * transaction.  This should be relied on only for optimization purposes;
-	 * it is possible for new-ness to be "forgotten" (eg, after CLUSTER).
+	 * transaction.  This can be now be relied on, whereas previously it
+	 * could be "forgotten" in earlier releases.
 	 * Likewise, rd_newRelfilenodeSubid is the ID of the highest
 	 * subtransaction the relfilenode change has survived into, or zero if not
 	 * changed in the current transaction (or we have forgotten changing it).
+	 * rd_newRelfilenodeSubid can be forgotten when a relation has multiple
+	 * new relfilenodes within a single transaction, with one of them occuring
+	 * in a subsequently aborted subtransaction, e.g.
+	 * 		BEGIN;
+	 * 		TRUNCATE t;
+	 * 		SAVEPOINT save;
+	 * 		TRUNCATE t;
+	 * 		ROLLBACK TO save;
+	 * 		-- rd_newRelfilenode is now forgotten
 	 */
 	SubTransactionId rd_createSubid;	/* rel was created in current xact */
 	SubTransactionId rd_newRelfilenodeSubid;	/* new relfilenode assigned in