Skip to content

Commit feaff21

Browse files
knizhnikkelvich
authored andcommitted
Support VACCUM ONLY LOCAL and rewrite replicate of functions accessing temporary tables
1 parent 62d8936 commit feaff21

File tree

1 file changed

+89
-13
lines changed

1 file changed

+89
-13
lines changed

multimaster.c

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

4811+
static bool MtmIsTempType(TypeName* typeName)
4812+
{
4813+
bool isTemp = false;
4814+
4815+
if (typeName != NULL)
4816+
{
4817+
Type typeTuple = LookupTypeName(NULL, typeName, NULL, false);
4818+
if (typeTuple != NULL)
4819+
{
4820+
Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
4821+
Oid relid = typeStruct->typrelid;
4822+
ReleaseSysCache(typeTuple);
4823+
4824+
if (relid != InvalidOid)
4825+
{
4826+
HeapTuple classTuple = SearchSysCache1(RELOID, relid);
4827+
Form_pg_class classStruct = (Form_pg_class) GETSTRUCT(classTuple);
4828+
if (classStruct->relpersistence == 't')
4829+
isTemp = true;
4830+
ReleaseSysCache(classTuple);
4831+
}
4832+
}
4833+
}
4834+
return isTemp;
4835+
}
4836+
4837+
static bool MtmFunctionProfileDependsOnTempTable(CreateFunctionStmt* func)
4838+
{
4839+
ListCell* elem;
4840+
4841+
if (MtmIsTempType(func->returnType))
4842+
{
4843+
return true;
4844+
}
4845+
foreach (elem, func->parameters)
4846+
{
4847+
FunctionParameter* param = (FunctionParameter*) lfirst(elem);
4848+
if (MtmIsTempType(param->argType))
4849+
{
4850+
return true;
4851+
}
4852+
}
4853+
return false;
4854+
}
4855+
4856+
4857+
48114858
static void MtmProcessUtility(Node *parsetree, const char *queryString,
48124859
ProcessUtilityContext context, ParamListInfo params,
48134860
DestReceiver *dest, char *completionTag)
48144861
{
48154862
bool skipCommand = false;
48164863
bool executed = false;
4864+
bool prevMyXactAccessedTempRel;
48174865

48184866
MTM_LOG2("%d: Process utility statement tag=%d, context=%d, issubtrans=%d, creating_extension=%d, query=%s",
48194867
MyProcPid, nodeTag(parsetree), context, IsSubTransaction(), creating_extension, queryString);
@@ -4895,19 +4943,24 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
48954943
break;
48964944

48974945
case T_VacuumStmt:
4898-
skipCommand = true;
4899-
if (context == PROCESS_UTILITY_TOPLEVEL) {
4900-
MtmProcessDDLCommand(queryString, false);
4901-
MtmTx.isDistributed = false;
4902-
} else if (MtmApplyContext != NULL) {
4903-
MemoryContext oldContext = MemoryContextSwitchTo(MtmApplyContext);
4904-
Assert(oldContext != MtmApplyContext);
4905-
MtmVacuumStmt = (VacuumStmt*)copyObject(parsetree);
4906-
MemoryContextSwitchTo(oldContext);
4907-
return;
4908-
}
4909-
break;
4910-
4946+
{
4947+
VacuumStmt* vacuum = (VacuumStmt*)parsetree;
4948+
skipCommand = true;
4949+
if ((vacuum->options & VACOPT_LOCAL) == 0 && !MtmVolksWagenMode)
4950+
{
4951+
if (context == PROCESS_UTILITY_TOPLEVEL) {
4952+
MtmProcessDDLCommand(queryString, false);
4953+
MtmTx.isDistributed = false;
4954+
} else if (MtmApplyContext != NULL) {
4955+
MemoryContext oldContext = MemoryContextSwitchTo(MtmApplyContext);
4956+
Assert(oldContext != MtmApplyContext);
4957+
MtmVacuumStmt = (VacuumStmt*)copyObject(parsetree);
4958+
MemoryContextSwitchTo(oldContext);
4959+
return;
4960+
}
4961+
}
4962+
break;
4963+
}
49114964
case T_CreateDomainStmt:
49124965
/* Detect temp tables access */
49134966
{
@@ -5072,6 +5125,14 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
50725125
}
50735126
}
50745127
}
5128+
case T_CreateFunctionStmt:
5129+
{
5130+
if (MtmTx.isReplicated)
5131+
{
5132+
// disable functiob body cehck at replica
5133+
check_function_bodies = false;
5134+
}
5135+
}
50755136
break;
50765137
}
50775138

@@ -5089,6 +5150,8 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
50895150
}
50905151
else MTM_LOG3("Skip utility statement '%s': skip=%d, insideDDL=%d", queryString, skipCommand, MtmDDLStatement != NULL);
50915152

5153+
prevMyXactAccessedTempRel = MyXactAccessedTempRel;
5154+
50925155
if (PreviousProcessUtilityHook != NULL)
50935156
{
50945157
PreviousProcessUtilityHook(parsetree, queryString, context,
@@ -5104,6 +5167,19 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
51045167
MTM_ELOG(ERROR, "Isolation level %s is not supported by multimaster", isoLevelStr[XactIsoLevel]);
51055168
}
51065169
#endif
5170+
/* Allow replication of functions operating on temporary tables.
5171+
* Even through temporary table doesn't exist at replica, diasabling functoin body check makes it possible to create such function at replica.
5172+
* And it can be accessed later at replica if correspondent temporary table will be created.
5173+
* But disable replication of functions returning temporary tables: such functions can not be created at replica in any case.
5174+
*/
5175+
if (IsA(parsetree, CreateFunctionStmt))
5176+
{
5177+
if (MtmFunctionProfileDependsOnTempTable((CreateFunctionStmt*)parsetree))
5178+
{
5179+
prevMyXactAccessedTempRel = true;
5180+
}
5181+
MyXactAccessedTempRel = prevMyXactAccessedTempRel;
5182+
}
51075183
if (MyXactAccessedTempRel)
51085184
{
51095185
MTM_LOG1("Xact accessed temp table, stopping replication of statement '%s'", queryString);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy