Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c2b3218

Browse files
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.
1 parent ae9aba6 commit c2b3218

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

src/backend/commands/copy.c

+15-6
Original file line numberDiff line numberDiff line change
@@ -1963,8 +1963,18 @@ CopyFrom(CopyState cstate)
19631963
* routine first.
19641964
*
19651965
* As mentioned in comments in utils/rel.h, the in-same-transaction test
1966-
* is not completely reliable, since in rare cases rd_createSubid or
1967-
* rd_newRelfilenodeSubid can be cleared before the end of the transaction.
1966+
* is not always set correctly, since in rare cases rd_newRelfilenodeSubid
1967+
* can be cleared before the end of the transaction. The exact case is
1968+
* when a relation sets a new relfilenode twice in same transaction, yet
1969+
* the second one fails in an aborted subtransaction, e.g.
1970+
*
1971+
* BEGIN;
1972+
* TRUNCATE t;
1973+
* SAVEPOINT save;
1974+
* TRUNCATE t;
1975+
* ROLLBACK TO save;
1976+
* COPY ...
1977+
*
19681978
* However this is OK since at worst we will fail to make the optimization.
19691979
*
19701980
* Also, if the target file is new-in-transaction, we assume that checking
@@ -1994,10 +2004,9 @@ CopyFrom(CopyState cstate)
19942004
* which subtransaction created it is crucial for correctness
19952005
* of this optimisation.
19962006
*
1997-
* Note that because the test is unreliable in case of relcache reset
1998-
* we cannot guarantee that we can honour the request to FREEZE.
1999-
* If we cannot honour the request we do so silently, firstly to
2000-
* avoid noise for the user and also to avoid obscure test failures.
2007+
* As noted above rd_newRelfilenodeSubid is not set in all cases
2008+
* where we can apply the optimization, so in those rare cases
2009+
* where we cannot honour the request we do so silently.
20012010
*/
20022011
if (cstate->freeze &&
20032012
ThereAreNoPriorRegisteredSnapshots() &&

src/include/utils/rel.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,20 @@ typedef struct RelationData
9090
/*
9191
* rd_createSubid is the ID of the highest subtransaction the rel has
9292
* survived into; or zero if the rel was not created in the current top
93-
* transaction. This should be relied on only for optimization purposes;
94-
* it is possible for new-ness to be "forgotten" (eg, after CLUSTER).
93+
* transaction. This can be now be relied on, whereas previously it
94+
* could be "forgotten" in earlier releases.
9595
* Likewise, rd_newRelfilenodeSubid is the ID of the highest
9696
* subtransaction the relfilenode change has survived into, or zero if not
9797
* changed in the current transaction (or we have forgotten changing it).
98+
* rd_newRelfilenodeSubid can be forgotten when a relation has multiple
99+
* new relfilenodes within a single transaction, with one of them occuring
100+
* in a subsequently aborted subtransaction, e.g.
101+
* BEGIN;
102+
* TRUNCATE t;
103+
* SAVEPOINT save;
104+
* TRUNCATE t;
105+
* ROLLBACK TO save;
106+
* -- rd_newRelfilenode is now forgotten
98107
*/
99108
SubTransactionId rd_createSubid; /* rel was created in current xact */
100109
SubTransactionId rd_newRelfilenodeSubid; /* new relfilenode assigned in

0 commit comments

Comments
 (0)