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

Commit864f35b

Browse files
committed
Support VACCUM ONLY LOCAL and rewrite replicate of functions accessing temporary tables
1 parentb4a0f07 commit864f35b

File tree

3 files changed

+107
-20
lines changed

3 files changed

+107
-20
lines changed

‎contrib/mmts/multimaster.c

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5139,12 +5139,60 @@ void MtmUpdateLockGraph(int nodeId, void const* messageBody, int messageSize)
51395139
MTM_LOG1("Update deadlock graph for node %d size %d",nodeId,messageSize);
51405140
}
51415141

5142+
staticboolMtmIsTempType(TypeName*typeName)
5143+
{
5144+
boolisTemp= false;
5145+
5146+
if (typeName!=NULL)
5147+
{
5148+
TypetypeTuple=LookupTypeName(NULL,typeName,NULL, false);
5149+
if (typeTuple!=NULL)
5150+
{
5151+
Form_pg_typetypeStruct= (Form_pg_type)GETSTRUCT(typeTuple);
5152+
Oidrelid=typeStruct->typrelid;
5153+
ReleaseSysCache(typeTuple);
5154+
5155+
if (relid!=InvalidOid)
5156+
{
5157+
HeapTupleclassTuple=SearchSysCache1(RELOID,relid);
5158+
Form_pg_classclassStruct= (Form_pg_class)GETSTRUCT(classTuple);
5159+
if (classStruct->relpersistence=='t')
5160+
isTemp= true;
5161+
ReleaseSysCache(classTuple);
5162+
}
5163+
}
5164+
}
5165+
returnisTemp;
5166+
}
5167+
5168+
staticboolMtmFunctionProfileDependsOnTempTable(CreateFunctionStmt*func)
5169+
{
5170+
ListCell*elem;
5171+
5172+
if (MtmIsTempType(func->returnType))
5173+
{
5174+
return true;
5175+
}
5176+
foreach (elem,func->parameters)
5177+
{
5178+
FunctionParameter*param= (FunctionParameter*)lfirst(elem);
5179+
if (MtmIsTempType(param->argType))
5180+
{
5181+
return true;
5182+
}
5183+
}
5184+
return false;
5185+
}
5186+
5187+
5188+
51425189
staticvoidMtmProcessUtility(Node*parsetree,constchar*queryString,
51435190
ProcessUtilityContextcontext,ParamListInfoparams,
51445191
DestReceiver*dest,char*completionTag)
51455192
{
51465193
boolskipCommand= false;
51475194
boolexecuted= false;
5195+
boolprevMyXactAccessedTempRel;
51485196

51495197
MTM_LOG2("%d: Process utility statement tag=%d, context=%d, issubtrans=%d, creating_extension=%d, query=%s",
51505198
MyProcPid,nodeTag(parsetree),context,IsSubTransaction(),creating_extension,queryString);
@@ -5226,19 +5274,24 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
52265274
break;
52275275

52285276
caseT_VacuumStmt:
5229-
skipCommand= true;
5230-
if (context==PROCESS_UTILITY_TOPLEVEL) {
5231-
MtmProcessDDLCommand(queryString, false);
5232-
MtmTx.isDistributed= false;
5233-
}elseif (MtmApplyContext!=NULL) {
5234-
MemoryContextoldContext=MemoryContextSwitchTo(MtmApplyContext);
5235-
Assert(oldContext!=MtmApplyContext);
5236-
MtmVacuumStmt= (VacuumStmt*)copyObject(parsetree);
5237-
MemoryContextSwitchTo(oldContext);
5238-
return;
5239-
}
5240-
break;
5241-
5277+
{
5278+
VacuumStmt*vacuum= (VacuumStmt*)parsetree;
5279+
skipCommand= true;
5280+
if ((vacuum->options&VACOPT_LOCAL)==0&& !MtmVolksWagenMode)
5281+
{
5282+
if (context==PROCESS_UTILITY_TOPLEVEL) {
5283+
MtmProcessDDLCommand(queryString, false);
5284+
MtmTx.isDistributed= false;
5285+
}elseif (MtmApplyContext!=NULL) {
5286+
MemoryContextoldContext=MemoryContextSwitchTo(MtmApplyContext);
5287+
Assert(oldContext!=MtmApplyContext);
5288+
MtmVacuumStmt= (VacuumStmt*)copyObject(parsetree);
5289+
MemoryContextSwitchTo(oldContext);
5290+
return;
5291+
}
5292+
}
5293+
break;
5294+
}
52425295
caseT_CreateDomainStmt:
52435296
/* Detect temp tables access */
52445297
{
@@ -5403,6 +5456,14 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
54035456
}
54045457
}
54055458
}
5459+
caseT_CreateFunctionStmt:
5460+
{
5461+
if (MtmTx.isReplicated)
5462+
{
5463+
// disable functiob body cehck at replica
5464+
check_function_bodies= false;
5465+
}
5466+
}
54065467
break;
54075468
}
54085469

@@ -5420,6 +5481,8 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
54205481
}
54215482
elseMTM_LOG3("Skip utility statement '%s': skip=%d, insideDDL=%d",queryString,skipCommand,MtmDDLStatement!=NULL);
54225483

5484+
prevMyXactAccessedTempRel=MyXactAccessedTempRel;
5485+
54235486
if (PreviousProcessUtilityHook!=NULL)
54245487
{
54255488
PreviousProcessUtilityHook(parsetree,queryString,context,
@@ -5435,6 +5498,19 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
54355498
MTM_ELOG(ERROR,"Isolation level %s is not supported by multimaster",isoLevelStr[XactIsoLevel]);
54365499
}
54375500
#endif
5501+
/* Allow replication of functions operating on temporary tables.
5502+
* Even through temporary table doesn't exist at replica, diasabling functoin body check makes it possible to create such function at replica.
5503+
* And it can be accessed later at replica if correspondent temporary table will be created.
5504+
* But disable replication of functions returning temporary tables: such functions can not be created at replica in any case.
5505+
*/
5506+
if (IsA(parsetree,CreateFunctionStmt))
5507+
{
5508+
if (MtmFunctionProfileDependsOnTempTable((CreateFunctionStmt*)parsetree))
5509+
{
5510+
prevMyXactAccessedTempRel= true;
5511+
}
5512+
MyXactAccessedTempRel=prevMyXactAccessedTempRel;
5513+
}
54385514
if (MyXactAccessedTempRel)
54395515
{
54405516
MTM_LOG1("Xact accessed temp table, stopping replication of statement '%s'",queryString);

‎src/backend/parser/gram.y

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
413413

414414
%type<boolean>opt_autonomous
415415
%type<boolean>opt_instead
416-
%type<boolean>opt_uniqueopt_concurrentlyopt_verboseopt_full
416+
%type<boolean>opt_uniqueopt_concurrentlyopt_verboseopt_fullopt_local
417417
%type<boolean>opt_freezeopt_defaultopt_recheck
418418
%type<defelt>opt_binaryopt_oidscopy_delimiter
419419

@@ -9650,7 +9650,7 @@ cluster_index_specification:
96509650
*
96519651
*****************************************************************************/
96529652

9653-
VacuumStmt:VACUUMopt_fullopt_freezeopt_verbose
9653+
VacuumStmt:VACUUMopt_fullopt_freezeopt_verboseopt_local
96549654
{
96559655
VacuumStmt *n = makeNode(VacuumStmt);
96569656
n->options = VACOPT_VACUUM;
@@ -9660,11 +9660,13 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
96609660
n->options |= VACOPT_FREEZE;
96619661
if ($4)
96629662
n->options |= VACOPT_VERBOSE;
9663+
if ($5)
9664+
n->options |= VACOPT_LOCAL;
96639665
n->relation =NULL;
96649666
n->va_cols = NIL;
96659667
$$ = (Node *)n;
96669668
}
9667-
|VACUUMopt_fullopt_freezeopt_verbosequalified_name
9669+
|VACUUMopt_fullopt_freezeopt_verboseopt_localqualified_name
96689670
{
96699671
VacuumStmt *n = makeNode(VacuumStmt);
96709672
n->options = VACOPT_VACUUM;
@@ -9674,20 +9676,24 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
96749676
n->options |= VACOPT_FREEZE;
96759677
if ($4)
96769678
n->options |= VACOPT_VERBOSE;
9677-
n->relation =$5;
9679+
if ($5)
9680+
n->options |= VACOPT_LOCAL;
9681+
n->relation =$6;
96789682
n->va_cols = NIL;
96799683
$$ = (Node *)n;
96809684
}
9681-
|VACUUMopt_fullopt_freezeopt_verboseAnalyzeStmt
9685+
|VACUUMopt_fullopt_freezeopt_verboseopt_localAnalyzeStmt
96829686
{
9683-
VacuumStmt *n = (VacuumStmt *)$5;
9687+
VacuumStmt *n = (VacuumStmt *)$6;
96849688
n->options |= VACOPT_VACUUM;
96859689
if ($2)
96869690
n->options |= VACOPT_FULL;
96879691
if ($3)
96889692
n->options |= VACOPT_FREEZE;
96899693
if ($4)
96909694
n->options |= VACOPT_VERBOSE;
9695+
if ($5)
9696+
n->options |= VACOPT_LOCAL;
96919697
$$ = (Node *)n;
96929698
}
96939699
|VACUUM'('vacuum_option_list')'
@@ -9773,6 +9779,10 @@ opt_freeze: FREEZE{ $$ = TRUE; }
97739779
|/*EMPTY*/{$$ =FALSE; }
97749780
;
97759781

9782+
opt_local:ONLYLOCAL {$$ =TRUE; }
9783+
|/*EMPTY*/{$$ =FALSE; }
9784+
;
9785+
97769786
opt_name_list:
97779787
'('name_list')'{$$ =$2; }
97789788
|/*EMPTY*/{$$ = NIL; }

‎src/include/nodes/parsenodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2876,7 +2876,8 @@ typedef enum VacuumOption
28762876
VACOPT_FULL=1 <<4,/* FULL (non-concurrent) vacuum */
28772877
VACOPT_NOWAIT=1 <<5,/* don't wait to get lock (autovacuum only) */
28782878
VACOPT_SKIPTOAST=1 <<6,/* don't process the TOAST table, if any */
2879-
VACOPT_DISABLE_PAGE_SKIPPING=1 <<7/* don't skip any pages */
2879+
VACOPT_DISABLE_PAGE_SKIPPING=1 <<7,/* don't skip any pages */
2880+
VACOPT_LOCAL=1 <<8/* Multimaster: perform vacuum only on local node */
28802881
}VacuumOption;
28812882

28822883
typedefstructVacuumStmt

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp