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

Commit6cb4aff

Browse files
committed
Avoid setup work for invalidation messages at start-of-(sub)xact.
Instead of initializing a new TransInvalidationInfo for everytransaction or subtransaction, we can just do it for thosetransactions or subtransactions that actually need to queueinvalidation messages. That also avoids needing to free thoseentries at the end of a transaction or subtransaction that doesnot generate any invalidation messages, which is by far thecommon case.Patch by me. Review by Simon Riggs and Andres Freund.
1 parent8f8314b commit6cb4aff

File tree

3 files changed

+81
-50
lines changed

3 files changed

+81
-50
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,6 @@ StartTransaction(void)
18381838
* initialize other subsystems for new transaction
18391839
*/
18401840
AtStart_GUC();
1841-
AtStart_Inval();
18421841
AtStart_Cache();
18431842
AfterTriggerBeginXact();
18441843

@@ -4151,7 +4150,6 @@ StartSubTransaction(void)
41514150
*/
41524151
AtSubStart_Memory();
41534152
AtSubStart_ResourceOwner();
4154-
AtSubStart_Inval();
41554153
AtSubStart_Notify();
41564154
AfterTriggerBeginSubXact();
41574155

‎src/backend/utils/cache/inval.c

Lines changed: 81 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -693,19 +693,32 @@ AcceptInvalidationMessages(void)
693693
}
694694

695695
/*
696-
*AtStart_Inval
697-
*Initialize inval listsat start of a maintransaction.
696+
*PrepareInvalidationState
697+
*Initialize inval listsfor the current (sub)transaction.
698698
*/
699-
void
700-
AtStart_Inval(void)
699+
staticvoid
700+
PrepareInvalidationState(void)
701701
{
702-
Assert(transInvalInfo==NULL);
703-
transInvalInfo= (TransInvalidationInfo*)
702+
TransInvalidationInfo*myInfo;
703+
704+
if (transInvalInfo!=NULL&&
705+
transInvalInfo->my_level==GetCurrentTransactionNestLevel())
706+
return;
707+
708+
myInfo= (TransInvalidationInfo*)
704709
MemoryContextAllocZero(TopTransactionContext,
705710
sizeof(TransInvalidationInfo));
706-
transInvalInfo->my_level=GetCurrentTransactionNestLevel();
707-
SharedInvalidMessagesArray=NULL;
708-
numSharedInvalidMessagesArray=0;
711+
myInfo->parent=transInvalInfo;
712+
myInfo->my_level=GetCurrentTransactionNestLevel();
713+
714+
/*
715+
* If there's any previous entry, this one should be for a deeper
716+
* nesting level.
717+
*/
718+
Assert(transInvalInfo==NULL||
719+
myInfo->my_level>transInvalInfo->my_level);
720+
721+
transInvalInfo=myInfo;
709722
}
710723

711724
/*
@@ -726,24 +739,6 @@ PostPrepare_Inval(void)
726739
AtEOXact_Inval(false);
727740
}
728741

729-
/*
730-
* AtSubStart_Inval
731-
*Initialize inval lists at start of a subtransaction.
732-
*/
733-
void
734-
AtSubStart_Inval(void)
735-
{
736-
TransInvalidationInfo*myInfo;
737-
738-
Assert(transInvalInfo!=NULL);
739-
myInfo= (TransInvalidationInfo*)
740-
MemoryContextAllocZero(TopTransactionContext,
741-
sizeof(TransInvalidationInfo));
742-
myInfo->parent=transInvalInfo;
743-
myInfo->my_level=GetCurrentTransactionNestLevel();
744-
transInvalInfo=myInfo;
745-
}
746-
747742
/*
748743
* Collect invalidation messages into SharedInvalidMessagesArray array.
749744
*/
@@ -803,8 +798,16 @@ xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs,
803798
{
804799
MemoryContextoldcontext;
805800

801+
/* Quick exit if we haven't done anything with invalidation messages. */
802+
if (transInvalInfo==NULL)
803+
{
804+
*RelcacheInitFileInval= false;
805+
*msgs=NULL;
806+
return0;
807+
}
808+
806809
/* Must be at top of stack */
807-
Assert(transInvalInfo!=NULL&&transInvalInfo->parent==NULL);
810+
Assert(transInvalInfo->my_level==1&&transInvalInfo->parent==NULL);
808811

809812
/*
810813
* Relcache init file invalidation requires processing both before and
@@ -904,11 +907,15 @@ ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs,
904907
void
905908
AtEOXact_Inval(boolisCommit)
906909
{
910+
/* Quick exit if no messages */
911+
if (transInvalInfo==NULL)
912+
return;
913+
914+
/* Must be at top of stack */
915+
Assert(transInvalInfo->my_level==1&&transInvalInfo->parent==NULL);
916+
907917
if (isCommit)
908918
{
909-
/* Must be at top of stack */
910-
Assert(transInvalInfo!=NULL&&transInvalInfo->parent==NULL);
911-
912919
/*
913920
* Relcache init file invalidation requires processing both before and
914921
* after we send the SI messages. However, we need not do anything
@@ -926,17 +933,16 @@ AtEOXact_Inval(bool isCommit)
926933
if (transInvalInfo->RelcacheInitFileInval)
927934
RelationCacheInitFilePostInvalidate();
928935
}
929-
elseif (transInvalInfo!=NULL)
936+
else
930937
{
931-
/* Must be at top of stack */
932-
Assert(transInvalInfo->parent==NULL);
933-
934938
ProcessInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs,
935939
LocalExecuteInvalidationMessage);
936940
}
937941

938942
/* Need not free anything explicitly */
939943
transInvalInfo=NULL;
944+
SharedInvalidMessagesArray=NULL;
945+
numSharedInvalidMessagesArray=0;
940946
}
941947

942948
/*
@@ -960,18 +966,38 @@ AtEOXact_Inval(bool isCommit)
960966
void
961967
AtEOSubXact_Inval(boolisCommit)
962968
{
963-
intmy_level=GetCurrentTransactionNestLevel();
969+
intmy_level;
964970
TransInvalidationInfo*myInfo=transInvalInfo;
965971

966-
if (isCommit)
972+
/* Quick exit if no messages. */
973+
if (myInfo==NULL)
974+
return;
975+
976+
/* Also bail out quickly if messages are not for this level. */
977+
my_level=GetCurrentTransactionNestLevel();
978+
if (myInfo->my_level!=my_level)
967979
{
968-
/* Must be at non-top of stack */
969-
Assert(myInfo!=NULL&&myInfo->parent!=NULL);
970-
Assert(myInfo->my_level==my_level);
980+
Assert(myInfo->my_level<my_level);
981+
return;
982+
}
971983

984+
if (isCommit)
985+
{
972986
/* If CurrentCmdInvalidMsgs still has anything, fix it */
973987
CommandEndInvalidationMessages();
974988

989+
/*
990+
* We create invalidation stack entries lazily, so the parent might
991+
* not have one. Instead of creating one, moving all the data over,
992+
* and then freeing our own, we can just adjust the level of our own
993+
* entry.
994+
*/
995+
if (myInfo->parent==NULL||myInfo->parent->my_level<my_level-1)
996+
{
997+
myInfo->my_level--;
998+
return;
999+
}
1000+
9751001
/* Pass up my inval messages to parent */
9761002
AppendInvalidationMessages(&myInfo->parent->PriorCmdInvalidMsgs,
9771003
&myInfo->PriorCmdInvalidMsgs);
@@ -986,11 +1012,8 @@ AtEOSubXact_Inval(bool isCommit)
9861012
/* Need not free anything else explicitly */
9871013
pfree(myInfo);
9881014
}
989-
elseif (myInfo!=NULL&&myInfo->my_level==my_level)
1015+
else
9901016
{
991-
/* Must be at non-top of stack */
992-
Assert(myInfo->parent!=NULL);
993-
9941017
ProcessInvalidationMessages(&myInfo->PriorCmdInvalidMsgs,
9951018
LocalExecuteInvalidationMessage);
9961019

@@ -1074,6 +1097,12 @@ CacheInvalidateHeapTuple(Relation relation,
10741097
if (IsToastRelation(relation))
10751098
return;
10761099

1100+
/*
1101+
* If we're not prepared to queue invalidation messages for this
1102+
* subtransaction level, get ready now.
1103+
*/
1104+
PrepareInvalidationState();
1105+
10771106
/*
10781107
* First let the catcache do its thing
10791108
*/
@@ -1159,6 +1188,8 @@ CacheInvalidateCatalog(Oid catalogId)
11591188
{
11601189
OiddatabaseId;
11611190

1191+
PrepareInvalidationState();
1192+
11621193
if (IsSharedRelation(catalogId))
11631194
databaseId=InvalidOid;
11641195
else
@@ -1182,6 +1213,8 @@ CacheInvalidateRelcache(Relation relation)
11821213
OiddatabaseId;
11831214
OidrelationId;
11841215

1216+
PrepareInvalidationState();
1217+
11851218
relationId=RelationGetRelid(relation);
11861219
if (relation->rd_rel->relisshared)
11871220
databaseId=InvalidOid;
@@ -1202,6 +1235,8 @@ CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
12021235
OiddatabaseId;
12031236
OidrelationId;
12041237

1238+
PrepareInvalidationState();
1239+
12051240
relationId=HeapTupleGetOid(classTuple);
12061241
if (classtup->relisshared)
12071242
databaseId=InvalidOid;
@@ -1221,6 +1256,8 @@ CacheInvalidateRelcacheByRelid(Oid relid)
12211256
{
12221257
HeapTupletup;
12231258

1259+
PrepareInvalidationState();
1260+
12241261
tup=SearchSysCache1(RELOID,ObjectIdGetDatum(relid));
12251262
if (!HeapTupleIsValid(tup))
12261263
elog(ERROR,"cache lookup failed for relation %u",relid);

‎src/include/utils/inval.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ typedef void (*RelcacheCallbackFunction) (Datum arg, Oid relid);
2525

2626
externvoidAcceptInvalidationMessages(void);
2727

28-
externvoidAtStart_Inval(void);
29-
30-
externvoidAtSubStart_Inval(void);
31-
3228
externvoidAtEOXact_Inval(boolisCommit);
3329

3430
externvoidAtEOSubXact_Inval(boolisCommit);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp