Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1bf3d61

Browse files
committed
Fix subtransaction behavior for large objects, temp namespace, files,
password/group files. Also allow read-only subtransactions of a read-writeparent, but not vice versa. These are the reasonably noncontroversialparts of Alvaro's recent mop-up patch, plus further work on large objectsto minimize use of the TopTransactionResourceOwner.
1 parentcc813fc commit1bf3d61

File tree

17 files changed

+572
-205
lines changed

17 files changed

+572
-205
lines changed

‎src/backend/access/transam/xact.c

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.172 2004/07/27 05:10:49 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.173 2004/07/28 14:23:27 tgl Exp $
1212
*
1313
* NOTES
1414
*Transaction aborts can now occur two ways:
@@ -224,6 +224,7 @@ typedef struct TransactionStateData
224224
ResourceOwnercurTransactionOwner;/* my query resources */
225225
List*childXids;/* subcommitted child XIDs */
226226
AclIdcurrentUser;/* subxact start current_user */
227+
boolprevXactReadOnly;/* entry-time xact r/o state */
227228
structTransactionStateData*parent;/* back link to parent */
228229
}TransactionStateData;
229230

@@ -284,6 +285,7 @@ static TransactionStateData TopTransactionStateData = {
284285
NULL,/* cur transaction resource owner */
285286
NIL,/* subcommitted child Xids */
286287
0,/* entry-time current userid */
288+
false,/* entry-time xact r/o state */
287289
NULL/* link to parent state block */
288290
};
289291

@@ -1242,7 +1244,8 @@ StartTransaction(void)
12421244
* check the current transaction state
12431245
*/
12441246
if (s->state!=TRANS_DEFAULT)
1245-
elog(WARNING,"StartTransaction and not in default state");
1247+
elog(WARNING,"StartTransaction while in %s state",
1248+
TransStateAsString(s->state));
12461249

12471250
/*
12481251
* set the current transaction state information appropriately during
@@ -1287,6 +1290,8 @@ StartTransaction(void)
12871290
* you won't because it doesn't work during startup; the userid isn't
12881291
* set yet during a backend's first transaction start. We only use
12891292
* the currentUser field in sub-transaction state structs.
1293+
*
1294+
* prevXactReadOnly is also valid only in sub-transactions.
12901295
*/
12911296

12921297
/*
@@ -1319,7 +1324,8 @@ CommitTransaction(void)
13191324
* check the current transaction state
13201325
*/
13211326
if (s->state!=TRANS_INPROGRESS)
1322-
elog(WARNING,"CommitTransaction and not in in-progress state");
1327+
elog(WARNING,"CommitTransaction while in %s state",
1328+
TransStateAsString(s->state));
13231329
Assert(s->parent==NULL);
13241330

13251331
/*
@@ -1351,14 +1357,14 @@ CommitTransaction(void)
13511357

13521358
AtCommit_Portals();
13531359

1354-
/* handle commit for large objects [ PA, 7/17/98 ] */
1355-
/* XXX probably this does not belong here */
1356-
lo_commit(true);
1360+
/* close large objects before lower-level cleanup */
1361+
AtEOXact_LargeObject(true);
13571362

13581363
/* NOTIFY commit must come before lower-level cleanup */
13591364
AtCommit_Notify();
13601365

13611366
/* Update the flat password file if we changed pg_shadow or pg_group */
1367+
/* This should be the last step before commit */
13621368
AtEOXact_UpdatePasswordFile(true);
13631369

13641370
/*
@@ -1486,7 +1492,8 @@ AbortTransaction(void)
14861492
* check the current transaction state
14871493
*/
14881494
if (s->state!=TRANS_INPROGRESS)
1489-
elog(WARNING,"AbortTransaction and not in in-progress state");
1495+
elog(WARNING,"AbortTransaction while in %s state",
1496+
TransStateAsString(s->state));
14901497
Assert(s->parent==NULL);
14911498

14921499
/*
@@ -1515,7 +1522,7 @@ AbortTransaction(void)
15151522
*/
15161523
DeferredTriggerAbortXact();
15171524
AtAbort_Portals();
1518-
lo_commit(false);/* 'false' means it's abort */
1525+
AtEOXact_LargeObject(false);/* 'false' means it's abort */
15191526
AtAbort_Notify();
15201527
AtEOXact_UpdatePasswordFile(false);
15211528

@@ -1870,6 +1877,9 @@ CleanupAbortedSubTransactions(bool returnName)
18701877
s=CurrentTransactionState;
18711878
}
18721879

1880+
AssertState(s->blockState==TBLOCK_SUBINPROGRESS||
1881+
s->blockState==TBLOCK_INPROGRESS);
1882+
18731883
returnname;
18741884
}
18751885

@@ -2866,7 +2876,8 @@ StartSubTransaction(void)
28662876
TransactionStates=CurrentTransactionState;
28672877

28682878
if (s->state!=TRANS_DEFAULT)
2869-
elog(WARNING,"StartSubTransaction and not in default state");
2879+
elog(WARNING,"StartSubTransaction while in %s state",
2880+
TransStateAsString(s->state));
28702881

28712882
s->state=TRANS_START;
28722883

@@ -2889,6 +2900,7 @@ StartSubTransaction(void)
28892900
* Finish setup of other transaction state fields.
28902901
*/
28912902
s->currentUser=GetUserId();
2903+
s->prevXactReadOnly=XactReadOnly;
28922904

28932905
/*
28942906
* Initialize other subsystems for new subtransaction
@@ -2913,7 +2925,8 @@ CommitSubTransaction(void)
29132925
ShowTransactionState("CommitSubTransaction");
29142926

29152927
if (s->state!=TRANS_INPROGRESS)
2916-
elog(WARNING,"CommitSubTransaction and not in in-progress state");
2928+
elog(WARNING,"CommitSubTransaction while in %s state",
2929+
TransStateAsString(s->state));
29172930

29182931
/* Pre-commit processing */
29192932
AtSubCommit_Portals(s->parent->transactionIdData,
@@ -2930,9 +2943,18 @@ CommitSubTransaction(void)
29302943
/* Post-commit cleanup */
29312944
AtSubCommit_smgr();
29322945

2933-
AtSubEOXact_Inval(true);
2946+
AtEOSubXact_Inval(true);
29342947
AtEOSubXact_SPI(true,s->transactionIdData);
29352948

2949+
AtEOSubXact_LargeObject(true,s->transactionIdData,
2950+
s->parent->transactionIdData);
2951+
AtEOSubXact_UpdatePasswordFile(true,s->transactionIdData,
2952+
s->parent->transactionIdData);
2953+
AtEOSubXact_Files(true,s->transactionIdData,
2954+
s->parent->transactionIdData);
2955+
AtEOSubXact_Namespace(true,s->transactionIdData,
2956+
s->parent->transactionIdData);
2957+
29362958
/*
29372959
* Note that we just release the resource owner's resources and don't
29382960
* delete it. This is because locks are not actually released here.
@@ -2953,6 +2975,13 @@ CommitSubTransaction(void)
29532975
AtEOSubXact_on_commit_actions(true,s->transactionIdData,
29542976
s->parent->transactionIdData);
29552977

2978+
/*
2979+
* We need to restore the upper transaction's read-only state,
2980+
* in case the upper is read-write while the child is read-only;
2981+
* GUC will incorrectly think it should leave the child state in place.
2982+
*/
2983+
XactReadOnly=s->prevXactReadOnly;
2984+
29562985
CurrentResourceOwner=s->parent->curTransactionOwner;
29572986
CurTransactionResourceOwner=s->parent->curTransactionOwner;
29582987
s->curTransactionOwner=NULL;
@@ -2973,7 +3002,8 @@ AbortSubTransaction(void)
29733002
ShowTransactionState("AbortSubTransaction");
29743003

29753004
if (s->state!=TRANS_INPROGRESS)
2976-
elog(WARNING,"AbortSubTransaction and not in in-progress state");
3005+
elog(WARNING,"AbortSubTransaction while in %s state",
3006+
TransStateAsString(s->state));
29773007

29783008
HOLD_INTERRUPTS();
29793009

@@ -3010,7 +3040,16 @@ AbortSubTransaction(void)
30103040
AtEOSubXact_SPI(false,s->transactionIdData);
30113041
AtSubAbort_Portals(s->parent->transactionIdData,
30123042
s->parent->curTransactionOwner);
3013-
AtSubEOXact_Inval(false);
3043+
AtEOSubXact_Inval(false);
3044+
3045+
AtEOSubXact_LargeObject(false,s->transactionIdData,
3046+
s->parent->transactionIdData);
3047+
AtEOSubXact_UpdatePasswordFile(false,s->transactionIdData,
3048+
s->parent->transactionIdData);
3049+
AtEOSubXact_Files(false,s->transactionIdData,
3050+
s->parent->transactionIdData);
3051+
AtEOSubXact_Namespace(false,s->transactionIdData,
3052+
s->parent->transactionIdData);
30143053

30153054
ResourceOwnerRelease(s->curTransactionOwner,
30163055
RESOURCE_RELEASE_BEFORE_LOCKS,
@@ -3041,6 +3080,13 @@ AbortSubTransaction(void)
30413080
*/
30423081
SetUserId(s->currentUser);
30433082

3083+
/*
3084+
* Restore the upper transaction's read-only state, too. This should
3085+
* be redundant with GUC's cleanup but we may as well do it for
3086+
* consistency with the commit case.
3087+
*/
3088+
XactReadOnly=s->prevXactReadOnly;
3089+
30443090
CommandCounterIncrement();
30453091

30463092
RESUME_INTERRUPTS();
@@ -3057,7 +3103,8 @@ CleanupSubTransaction(void)
30573103
ShowTransactionState("CleanupSubTransaction");
30583104

30593105
if (s->state!=TRANS_ABORT)
3060-
elog(WARNING,"CleanupSubTransaction and not in aborted state");
3106+
elog(WARNING,"CleanupSubTransaction while in %s state",
3107+
TransStateAsString(s->state));
30613108

30623109
AtSubCleanup_Portals();
30633110

@@ -3088,7 +3135,8 @@ StartAbortedSubTransaction(void)
30883135
TransactionStates=CurrentTransactionState;
30893136

30903137
if (s->state!=TRANS_DEFAULT)
3091-
elog(WARNING,"StartAbortedSubTransaction and not in default state");
3138+
elog(WARNING,"StartAbortedSubTransaction while in %s state",
3139+
TransStateAsString(s->state));
30923140

30933141
s->state=TRANS_START;
30943142

@@ -3168,7 +3216,8 @@ PopTransaction(void)
31683216
TransactionStates=CurrentTransactionState;
31693217

31703218
if (s->state!=TRANS_DEFAULT)
3171-
elog(WARNING,"PopTransaction and not in default state");
3219+
elog(WARNING,"PopTransaction while in %s state",
3220+
TransStateAsString(s->state));
31723221

31733222
if (s->parent==NULL)
31743223
elog(FATAL,"PopTransaction with no parent");

‎src/backend/catalog/namespace.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.67 2004/06/18 06:13:19 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.68 2004/07/28 14:23:27 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -107,12 +107,17 @@ static bool namespaceSearchPathValid = true;
107107
* myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
108108
* in a particular backend session (this happens when a CREATE TEMP TABLE
109109
* command is first executed).Thereafter it's the OID of the temp namespace.
110-
* firstTempTransaction flags whether we've committed creation of the TEMP
111-
* namespace or not.
110+
*
111+
* myTempNamespaceXID shows whether we've created the TEMP namespace in the
112+
* current transaction. The TransactionId propagates up the transaction tree,
113+
* so the main transaction will correctly recognize the flag if all
114+
* intermediate subtransactions commit. When it is InvalidTransactionId,
115+
* we either haven't made the TEMP namespace yet, or have successfully
116+
* committed its creation, depending on whether myTempNamespace is valid.
112117
*/
113118
staticOidmyTempNamespace=InvalidOid;
114119

115-
staticboolfirstTempTransaction=false;
120+
staticTransactionIdmyTempNamespaceXID=InvalidTransactionId;
116121

117122
/*
118123
* "Special" namespace for CREATE SCHEMA. If set, it's the first search
@@ -1688,7 +1693,9 @@ InitTempTableNamespace(void)
16881693
*/
16891694
myTempNamespace=namespaceId;
16901695

1691-
firstTempTransaction= true;
1696+
/* It should not be done already. */
1697+
AssertState(myTempNamespaceXID==InvalidTransactionId);
1698+
myTempNamespaceXID=GetCurrentTransactionId();
16921699

16931700
namespaceSearchPathValid= false;/* need to rebuild list */
16941701
}
@@ -1707,7 +1714,7 @@ AtEOXact_Namespace(bool isCommit)
17071714
* temp tables at backend shutdown. (We only want to register the
17081715
* callback once per session, so this is a good place to do it.)
17091716
*/
1710-
if (firstTempTransaction)
1717+
if (myTempNamespaceXID==GetCurrentTransactionId())
17111718
{
17121719
if (isCommit)
17131720
on_shmem_exit(RemoveTempRelationsCallback,0);
@@ -1716,7 +1723,7 @@ AtEOXact_Namespace(bool isCommit)
17161723
myTempNamespace=InvalidOid;
17171724
namespaceSearchPathValid= false;/* need to rebuild list */
17181725
}
1719-
firstTempTransaction=false;
1726+
myTempNamespaceXID=InvalidTransactionId;
17201727
}
17211728

17221729
/*
@@ -1729,6 +1736,32 @@ AtEOXact_Namespace(bool isCommit)
17291736
}
17301737
}
17311738

1739+
/*
1740+
* AtEOSubXact_Namespace
1741+
*
1742+
* At subtransaction commit, propagate the temp-namespace-creation
1743+
* flag to the parent transaction.
1744+
*
1745+
* At subtransaction abort, forget the flag if we set it up.
1746+
*/
1747+
void
1748+
AtEOSubXact_Namespace(boolisCommit,TransactionIdmyXid,
1749+
TransactionIdparentXid)
1750+
{
1751+
if (myTempNamespaceXID==myXid)
1752+
{
1753+
if (isCommit)
1754+
myTempNamespaceXID=parentXid;
1755+
else
1756+
{
1757+
myTempNamespaceXID=InvalidTransactionId;
1758+
/* TEMP namespace creation failed, so reset state */
1759+
myTempNamespace=InvalidOid;
1760+
namespaceSearchPathValid= false;/* need to rebuild list */
1761+
}
1762+
}
1763+
}
1764+
17321765
/*
17331766
* Remove all relations in the specified temp namespace.
17341767
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp