18
18
#include "catalog/pg_type.h"
19
19
20
20
#include "executor/spi.h"
21
+ #include "commands/vacuum.h"
22
+ #include "commands/defrem.h"
23
+ #include "parser/parse_utilcmd.h"
21
24
22
25
#include "libpq/pqformat.h"
23
26
@@ -70,7 +73,7 @@ static void UserTableUpdateOpenIndexes(EState *estate, TupleTableSlot *slot);
70
73
static void UserTableUpdateIndexes (EState * estate , TupleTableSlot * slot );
71
74
72
75
static bool process_remote_begin (StringInfo s );
73
- static void process_remote_message (StringInfo s );
76
+ static bool process_remote_message (StringInfo s );
74
77
static void process_remote_commit (StringInfo s );
75
78
static void process_remote_insert (StringInfo s , Relation rel );
76
79
static void process_remote_update (StringInfo s , Relation rel );
@@ -353,20 +356,22 @@ process_remote_begin(StringInfo s)
353
356
return true;
354
357
}
355
358
356
- static void
359
+ static bool
357
360
process_remote_message (StringInfo s )
358
361
{
359
362
char action = pq_getmsgbyte (s );
360
363
int messageSize = pq_getmsgint (s , 4 );
361
364
char const * messageBody = pq_getmsgbytes (s , messageSize );
362
-
365
+ bool standalone = false;
366
+
363
367
switch (action )
364
368
{
365
369
case 'C' :
366
370
{
367
371
MTM_LOG1 ("%d: Executing non-tx utility statement %s" , MyProcPid , messageBody );
368
372
SetCurrentStatementStartTimestamp ();
369
373
StartTransactionCommand ();
374
+ standalone = true;
370
375
/* intentional falldown to the next case */
371
376
}
372
377
case 'D' :
@@ -376,21 +381,59 @@ process_remote_message(StringInfo s)
376
381
MTM_LOG1 ("%d: Executing utility statement %s" , MyProcPid , messageBody );
377
382
SPI_connect ();
378
383
ActivePortal -> sourceText = messageBody ;
384
+ MtmVacuumStmt = NULL ;
385
+ MtmIndexStmt = NULL ;
379
386
rc = SPI_execute (messageBody , false, 0 );
380
387
SPI_finish ();
381
- if (rc < 0 )
388
+ if (rc < 0 ) {
382
389
elog (ERROR , "Failed to execute utility statement %s" , messageBody );
390
+ } else {
391
+ if (MtmVacuumStmt != NULL ) {
392
+ ExecVacuum (MtmVacuumStmt , 1 );
393
+ } else if (MtmIndexStmt != NULL ) {
394
+ MemoryContext saveCtx = TopTransactionContext ;
395
+ Oid relid ;
396
+
397
+ TopTransactionContext = MtmApplyContext ;
398
+ relid = RangeVarGetRelidExtended (MtmIndexStmt -> relation , ShareUpdateExclusiveLock ,
399
+ false, false,
400
+ NULL ,
401
+ NULL );
402
+
403
+ /* Run parse analysis ... */
404
+ MtmIndexStmt = transformIndexStmt (relid , MtmIndexStmt , messageBody );
405
+
406
+ PushActiveSnapshot (GetTransactionSnapshot ());
407
+
408
+ DefineIndex (relid , /* OID of heap relation */
409
+ MtmIndexStmt ,
410
+ InvalidOid , /* no predefined OID */
411
+ false, /* is_alter_table */
412
+ true, /* check_rights */
413
+ false, /* skip_build */
414
+ false); /* quiet */
415
+
416
+ TopTransactionContext = saveCtx ;
417
+
418
+ if (ActiveSnapshotSet ())
419
+ PopActiveSnapshot ();
420
+
421
+ }
422
+ }
423
+ if (standalone ) {
424
+ CommitTransactionCommand ();
425
+ }
383
426
break ;
384
427
}
385
428
case 'L' :
386
429
{
387
430
MTM_LOG3 ("%ld: Process deadlock message with size %d from %d" , MtmGetSystemTime (), messageSize , MtmReplicationNodeId );
388
431
MtmUpdateLockGraph (MtmReplicationNodeId , messageBody , messageSize );
432
+ standalone = true;
389
433
break ;
390
434
}
391
435
}
392
-
393
-
436
+ return standalone ;
394
437
}
395
438
396
439
static void
@@ -968,8 +1011,6 @@ process_remote_delete(StringInfo s, Relation rel)
968
1011
CommandCounterIncrement ();
969
1012
}
970
1013
971
- static MemoryContext ApplyContext ;
972
-
973
1014
void MtmExecutor (void * work , size_t size )
974
1015
{
975
1016
StringInfoData s ;
@@ -982,14 +1023,14 @@ void MtmExecutor(void* work, size_t size)
982
1023
s .maxlen = -1 ;
983
1024
s .cursor = 0 ;
984
1025
985
- if (ApplyContext == NULL ) {
986
- ApplyContext = AllocSetContextCreate (TopMemoryContext ,
1026
+ if (MtmApplyContext == NULL ) {
1027
+ MtmApplyContext = AllocSetContextCreate (TopMemoryContext ,
987
1028
"MessageContext" ,
988
1029
ALLOCSET_DEFAULT_MINSIZE ,
989
1030
ALLOCSET_DEFAULT_INITSIZE ,
990
1031
ALLOCSET_DEFAULT_MAXSIZE );
991
1032
}
992
- MemoryContextSwitchTo (ApplyContext );
1033
+ MemoryContextSwitchTo (MtmApplyContext );
993
1034
replorigin_session_origin = InvalidRepOriginId ;
994
1035
PG_TRY ();
995
1036
{
@@ -1058,7 +1099,9 @@ void MtmExecutor(void* work, size_t size)
1058
1099
}
1059
1100
case 'M' :
1060
1101
{
1061
- process_remote_message (& s );
1102
+ if (process_remote_message (& s )) {
1103
+ break ;
1104
+ }
1062
1105
continue ;
1063
1106
}
1064
1107
default :
@@ -1069,7 +1112,7 @@ void MtmExecutor(void* work, size_t size)
1069
1112
}
1070
1113
PG_CATCH ();
1071
1114
{
1072
- MemoryContext oldcontext = MemoryContextSwitchTo (ApplyContext );
1115
+ MemoryContext oldcontext = MemoryContextSwitchTo (MtmApplyContext );
1073
1116
MtmHandleApplyError ();
1074
1117
MemoryContextSwitchTo (oldcontext );
1075
1118
EmitErrorReport ();
@@ -1083,6 +1126,6 @@ void MtmExecutor(void* work, size_t size)
1083
1126
if (spill_file >= 0 ) {
1084
1127
MtmCloseSpillFile (spill_file );
1085
1128
}
1086
- MemoryContextResetAndDeleteChildren (ApplyContext );
1129
+ MemoryContextResetAndDeleteChildren (MtmApplyContext );
1087
1130
}
1088
1131
0 commit comments