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

Commit9b013dc

Browse files
Improve performance of replay of AccessExclusiveLocks
A hot standby replica keeps a list of Access Exclusive locks for a toplevel transaction. These locks are released when the top level transactionends. Searching of this list is O(N^2), and each transaction had to pay theprice of searching this list for locks, even if it didn't take any AElocks itself.This patch optimizes this case by having the master server track whichtransactions took AE locks, and passes that along to the standby server inthe commit/abort record. This allows the standby to only try to releaselocks for transactions which actually took any, avoiding the majority ofthe performance issue.Refactor MyXactAccessedTempRel into MyXactFlags to allow minimal additionalcruft with this.Analysis and initial patch by David RowleyAuthor: David Rowley and Simon Riggs
1 parent1148e22 commit9b013dc

File tree

6 files changed

+59
-20
lines changed

6 files changed

+59
-20
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ relation_open(Oid relationId, LOCKMODE lockmode)
11321132

11331133
/* Make note that we've accessed a temporary relation */
11341134
if (RelationUsesLocalBuffers(r))
1135-
MyXactAccessedTempRel= true;
1135+
MyXactFlags |=XACT_FLAGS_ACCESSEDTEMPREL;
11361136

11371137
pgstat_initstats(r);
11381138

@@ -1178,7 +1178,7 @@ try_relation_open(Oid relationId, LOCKMODE lockmode)
11781178

11791179
/* Make note that we've accessed a temporary relation */
11801180
if (RelationUsesLocalBuffers(r))
1181-
MyXactAccessedTempRel= true;
1181+
MyXactFlags |=XACT_FLAGS_ACCESSEDTEMPREL;
11821182

11831183
pgstat_initstats(r);
11841184

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,11 +2065,15 @@ RecordTransactionCommitPrepared(TransactionId xid,
20652065
/* See notes in RecordTransactionCommit */
20662066
MyPgXact->delayChkpt= true;
20672067

2068-
/* Emit the XLOG commit record */
2068+
/*
2069+
* Emit the XLOG commit record. Note that we mark 2PC commits as potentially
2070+
* having AccessExclusiveLocks since we don't know whether or not they do.
2071+
*/
20692072
recptr=XactLogCommitRecord(committs,
20702073
nchildren,children,nrels,rels,
20712074
ninvalmsgs,invalmsgs,
20722075
initfileinval, false,
2076+
MyXactFlags |XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK,
20732077
xid);
20742078

20752079

@@ -2146,10 +2150,14 @@ RecordTransactionAbortPrepared(TransactionId xid,
21462150

21472151
START_CRIT_SECTION();
21482152

2149-
/* Emit the XLOG abort record */
2153+
/*
2154+
* Emit the XLOG commit record. Note that we mark 2PC aborts as potentially
2155+
* having AccessExclusiveLocks since we don't know whether or not they do.
2156+
*/
21502157
recptr=XactLogAbortRecord(GetCurrentTimestamp(),
21512158
nchildren,children,
21522159
nrels,rels,
2160+
MyXactFlags |XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK,
21532161
xid);
21542162

21552163
/* Always flush, since we're about to remove the 2PC state file */

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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@ intnParallelCurrentXids = 0;
109109
TransactionId*ParallelCurrentXids;
110110

111111
/*
112-
* MyXactAccessedTempRel is set when a temporary relation is accessed.
113-
* We don't allow PREPARE TRANSACTION in that case. (This is global
114-
* so that it can be set from heapam.c.)
112+
* Miscellaneous flag bits to record events which occur on the top level
113+
* transaction. These flags are only persisted in MyXactFlags and are intended
114+
* so we remember to do certain things later on in the transaction. This is
115+
* globally accessible, so can be set from anywhere in the code that requires
116+
* recording flags.
115117
*/
116-
boolMyXactAccessedTempRel= false;
117-
118+
intMyXactFlags;
118119

119120
/*
120121
*transaction states - transaction state from server perspective
@@ -1231,6 +1232,7 @@ RecordTransactionCommit(void)
12311232
nchildren,children,nrels,rels,
12321233
nmsgs,invalMessages,
12331234
RelcacheInitFileInval,forceSyncCommit,
1235+
MyXactFlags,
12341236
InvalidTransactionId/* plain commit */ );
12351237

12361238
if (replorigin)
@@ -1583,7 +1585,7 @@ RecordTransactionAbort(bool isSubXact)
15831585
XactLogAbortRecord(xact_time,
15841586
nchildren,children,
15851587
nrels,rels,
1586-
InvalidTransactionId);
1588+
MyXactFlags,InvalidTransactionId);
15871589

15881590
/*
15891591
* Report the latest async abort LSN, so that the WAL writer knows to
@@ -1845,7 +1847,7 @@ StartTransaction(void)
18451847
XactDeferrable=DefaultXactDeferrable;
18461848
XactIsoLevel=DefaultXactIsoLevel;
18471849
forceSyncCommit= false;
1848-
MyXactAccessedTempRel=false;
1850+
MyXactFlags=0;
18491851

18501852
/*
18511853
* reinitialize within-transaction counters
@@ -2260,7 +2262,7 @@ PrepareTransaction(void)
22602262
* cases, such as a temp table created and dropped all within the
22612263
* transaction. That seems to require much more bookkeeping though.
22622264
*/
2263-
if (MyXactAccessedTempRel)
2265+
if ((MyXactFlags&XACT_FLAGS_ACCESSEDTEMPREL))
22642266
ereport(ERROR,
22652267
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22662268
errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
@@ -5108,7 +5110,7 @@ XactLogCommitRecord(TimestampTz commit_time,
51085110
intnrels,RelFileNode*rels,
51095111
intnmsgs,SharedInvalidationMessage*msgs,
51105112
boolrelcacheInval,boolforceSync,
5111-
TransactionIdtwophase_xid)
5113+
intxactflags,TransactionIdtwophase_xid)
51125114
{
51135115
xl_xact_commitxlrec;
51145116
xl_xact_xinfoxl_xinfo;
@@ -5139,6 +5141,8 @@ XactLogCommitRecord(TimestampTz commit_time,
51395141
xl_xinfo.xinfo |=XACT_COMPLETION_UPDATE_RELCACHE_FILE;
51405142
if (forceSyncCommit)
51415143
xl_xinfo.xinfo |=XACT_COMPLETION_FORCE_SYNC_COMMIT;
5144+
if ((xactflags&XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5145+
xl_xinfo.xinfo |=XACT_XINFO_HAS_AE_LOCKS;
51425146

51435147
/*
51445148
* Check if the caller would like to ask standbys for immediate feedback
@@ -5251,7 +5255,7 @@ XLogRecPtr
52515255
XactLogAbortRecord(TimestampTzabort_time,
52525256
intnsubxacts,TransactionId*subxacts,
52535257
intnrels,RelFileNode*rels,
5254-
TransactionIdtwophase_xid)
5258+
intxactflags,TransactionIdtwophase_xid)
52555259
{
52565260
xl_xact_abortxlrec;
52575261
xl_xact_xinfoxl_xinfo;
@@ -5276,6 +5280,9 @@ XactLogAbortRecord(TimestampTz abort_time,
52765280

52775281
xlrec.xact_time=abort_time;
52785282

5283+
if ((xactflags&XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5284+
xl_xinfo.xinfo |=XACT_XINFO_HAS_AE_LOCKS;
5285+
52795286
if (nsubxacts>0)
52805287
{
52815288
xl_xinfo.xinfo |=XACT_XINFO_HAS_SUBXACTS;
@@ -5427,7 +5434,8 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
54275434
* via their top-level xid only, so no need to provide subxact list,
54285435
* which will save time when replaying commits.
54295436
*/
5430-
StandbyReleaseLockTree(xid,0,NULL);
5437+
if (parsed->xinfo&XACT_XINFO_HAS_AE_LOCKS)
5438+
StandbyReleaseLockTree(xid,0,NULL);
54315439
}
54325440

54335441
if (parsed->xinfo&XACT_XINFO_HAS_ORIGIN)
@@ -5563,7 +5571,8 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
55635571
/*
55645572
* Release locks, if any. There are no invalidations to send.
55655573
*/
5566-
StandbyReleaseLockTree(xid,parsed->nsubxacts,parsed->subxacts);
5574+
if (parsed->xinfo&XACT_XINFO_HAS_AE_LOCKS)
5575+
StandbyReleaseLockTree(xid,parsed->nsubxacts,parsed->subxacts);
55675576
}
55685577

55695578
/* Make sure files supposed to be dropped are dropped */

‎src/backend/commands/tablecmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12471,7 +12471,7 @@ PreCommit_on_commit_actions(void)
1247112471
* relations, we can skip truncating ON COMMIT DELETE ROWS
1247212472
* tables, as they must still be empty.
1247312473
*/
12474-
if (MyXactAccessedTempRel)
12474+
if ((MyXactFlags&XACT_FLAGS_ACCESSEDTEMPREL))
1247512475
oids_to_truncate=lappend_oid(oids_to_truncate,oc->relid);
1247612476
break;
1247712477
caseONCOMMIT_DROP:

‎src/backend/storage/ipc/standby.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,7 @@ LogAccessExclusiveLock(Oid dbOid, Oid relOid)
10631063
xlrec.relOid=relOid;
10641064

10651065
LogAccessExclusiveLocks(1,&xlrec);
1066+
MyXactFlags |=XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK;
10661067
}
10671068

10681069
/*

‎src/include/access/xact.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,27 @@ typedef enum
7171
/* Synchronous commit level */
7272
externintsynchronous_commit;
7373

74-
/* Kluge for 2PC support */
75-
externboolMyXactAccessedTempRel;
74+
/*
75+
* Miscellaneous flag bits to record events which occur on the top level
76+
* transaction. These flags are only persisted in MyXactFlags and are intended
77+
* so we remember to do certain things later in the transaction. This is
78+
* globally accessible, so can be set from anywhere in the code which requires
79+
* recording flags.
80+
*/
81+
externintMyXactFlags;
82+
83+
/*
84+
* XACT_FLAGS_ACCESSEDTEMPREL - set when a temporary relation is accessed. We
85+
* don't allow PREPARE TRANSACTION in that case.
86+
*/
87+
#defineXACT_FLAGS_ACCESSEDTEMPREL(1U << 0)
88+
89+
/*
90+
* XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK - records whether the top level xact
91+
* logged any Access Exclusive Locks.
92+
*/
93+
#defineXACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK(1U << 1)
94+
7695

7796
/*
7897
*start- and end-of-transaction callbacks for dynamically loaded modules
@@ -137,6 +156,7 @@ typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid,
137156
#defineXACT_XINFO_HAS_INVALS(1U << 3)
138157
#defineXACT_XINFO_HAS_TWOPHASE(1U << 4)
139158
#defineXACT_XINFO_HAS_ORIGIN(1U << 5)
159+
#defineXACT_XINFO_HAS_AE_LOCKS(1U << 6)
140160

141161
/*
142162
* Also stored in xinfo, these indicating a variety of additional actions that
@@ -364,12 +384,13 @@ extern XLogRecPtr XactLogCommitRecord(TimestampTz commit_time,
364384
intnrels,RelFileNode*rels,
365385
intnmsgs,SharedInvalidationMessage*msgs,
366386
boolrelcacheInval,boolforceSync,
387+
intxactflags,
367388
TransactionIdtwophase_xid);
368389

369390
externXLogRecPtrXactLogAbortRecord(TimestampTzabort_time,
370391
intnsubxacts,TransactionId*subxacts,
371392
intnrels,RelFileNode*rels,
372-
TransactionIdtwophase_xid);
393+
intxactflags,TransactionIdtwophase_xid);
373394
externvoidxact_redo(XLogReaderState*record);
374395

375396
/* xactdesc.c */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp