Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)