@@ -156,7 +156,7 @@ static void MtmShmemStartup(void);
156
156
static BgwPool * MtmPoolConstructor (void );
157
157
static bool MtmRunUtilityStmt (PGconn * conn , char const * sql , char * * errmsg );
158
158
static void MtmBroadcastUtilityStmt (char const * sql , bool ignoreError );
159
- static bool MtmProcessDDLCommand (char const * queryString , bool transactional , bool contextFree );
159
+ static bool MtmProcessDDLCommand (char const * queryString , bool transactional );
160
160
161
161
MtmState * Mtm ;
162
162
@@ -885,6 +885,7 @@ MtmPrePrepareTransaction(MtmCurrentTrans* x)
885
885
ts -> procno = MyProc -> pgprocno ;
886
886
ts -> votingCompleted = false;
887
887
ts -> participantsMask = (((nodemask_t )1 << Mtm -> nAllNodes ) - 1 ) & ~Mtm -> disabledNodeMask & ~((nodemask_t )1 << (MtmNodeId - 1 ));
888
+ ts -> nConfigChanges = Mtm -> nConfigChanges ;
888
889
ts -> votedMask = 0 ;
889
890
ts -> nSubxids = xactGetCommittedChildren (& subxids );
890
891
if (!ts -> isActive ) {
@@ -979,14 +980,20 @@ void MtmPrecommitTransaction(char const* gid)
979
980
static bool
980
981
MtmVotingCompleted (MtmTransState * ts )
981
982
{
982
- nodemask_t liveNodesMask = (((nodemask_t )1 << Mtm -> nAllNodes ) - 1 ) & ~Mtm -> disabledNodeMask & ~((nodemask_t )1 << (MtmNodeId - 1 ));
983
- if (!ts -> isPrepared && ts -> participantsMask != liveNodesMask )
984
- {
985
- elog (WARNING , "Abort transaction %d (%s) because cluster configuration is changed from %lx to %lx since transaction start" ,
986
- ts -> xid , ts -> gid , ts -> participantsMask , liveNodesMask );
987
- MtmAbortTransaction (ts );
988
- return true;
983
+ nodemask_t liveNodesMask = (((nodemask_t )1 << Mtm -> nAllNodes ) - 1 ) & ~Mtm -> disabledNodeMask & ~((nodemask_t )1 << (MtmNodeId - 1 ));
984
+
985
+ if (!ts -> isPrepared ) { /* We can not just abort precommitted transactions */
986
+ if (ts -> nConfigChanges != Mtm -> nConfigChanges )
987
+ {
988
+ elog (WARNING , "Abort transaction %s (%d) because cluster configuration is changed from %lx to %lx since transaction start" ,
989
+ ts -> gid , ts -> xid , ts -> participantsMask , liveNodesMask );
990
+ MtmAbortTransaction (ts );
991
+ return true;
992
+ }
993
+ /* If cluster configuration was not changed, then node mask should not changed as well */
994
+ Assert (ts -> participantsMask == liveNodesMask );
989
995
}
996
+
990
997
if (ts -> votingCompleted ) {
991
998
return true;
992
999
}
@@ -1071,9 +1078,9 @@ Mtm2PCVoting(MtmCurrentTrans* x, MtmTransState* ts)
1071
1078
x -> isSuspended = true;
1072
1079
} else {
1073
1080
if (Mtm -> status != MTM_ONLINE ) {
1074
- elog (WARNING , "Commit of distributed transaction is canceled because node is switched to %s mode" , MtmNodeStatusMnem [Mtm -> status ]);
1081
+ elog (WARNING , "Commit of distributed transaction %s (%d) is canceled because node is switched to %s mode" , ts -> gid , ts -> xid , MtmNodeStatusMnem [Mtm -> status ]);
1075
1082
} else {
1076
- elog (WARNING , "Commit of distributed transaction is canceled because cluster configuration was changed" );
1083
+ elog (WARNING , "Commit of distributed transaction %s (%d) is canceled because cluster configuration was changed" , ts -> gid , ts -> xid );
1077
1084
}
1078
1085
MtmAbortTransaction (ts );
1079
1086
}
@@ -1201,7 +1208,7 @@ MtmAbortPreparedTransaction(MtmCurrentTrans* x)
1201
1208
MtmUnlock ();
1202
1209
x -> status = TRANSACTION_STATUS_ABORTED ;
1203
1210
} else {
1204
- MTM_LOG1 ("Transaction %d with gid='%s' is already aborted" , x -> xid , x -> gid );
1211
+ MTM_LOG1 ("Transaction %s (%d) is already aborted" , x -> gid , x -> xid );
1205
1212
}
1206
1213
}
1207
1214
@@ -1262,7 +1269,7 @@ MtmEndTransaction(MtmCurrentTrans* x, bool commit)
1262
1269
Mtm -> nActiveTransactions -= 1 ;
1263
1270
MtmAdjustSubtransactions (ts );
1264
1271
} else {
1265
- MTM_LOG1 ("%d: abort transaction %d gid='%s' is called from MtmEndTransaction" , MyProcPid , x -> xid , x -> gid );
1272
+ MTM_LOG1 ("%d: abort transaction %s (%d) is called from MtmEndTransaction" , MyProcPid , x -> gid , x -> xid );
1266
1273
MtmAbortTransaction (ts );
1267
1274
}
1268
1275
}
@@ -1272,7 +1279,7 @@ MtmEndTransaction(MtmCurrentTrans* x, bool commit)
1272
1279
* Send notification only if ABORT happens during transaction processing at replicas,
1273
1280
* do not send notification if ABORT is received from master
1274
1281
*/
1275
- MTM_LOG1 ("%d: send ABORT notification for transaction %d (%s) to coordinator %d" , MyProcPid , x -> gtid .xid , x -> gid , x -> gtid .node );
1282
+ MTM_LOG1 ("%d: send ABORT notification for transaction %d (%s) local xid=%d to coordinator %d" , MyProcPid , x -> gtid .xid , x -> gid , x -> xid , x -> gtid .node );
1276
1283
if (ts == NULL ) {
1277
1284
bool found ;
1278
1285
Assert (TransactionIdIsValid (x -> xid ));
@@ -1441,6 +1448,7 @@ static void MtmLoadPreparedTransactions(void)
1441
1448
ts -> nSubxids = 0 ;
1442
1449
ts -> votingCompleted = true;
1443
1450
ts -> participantsMask = (((nodemask_t )1 << Mtm -> nAllNodes ) - 1 ) & ~Mtm -> disabledNodeMask & ~((nodemask_t )1 << (MtmNodeId - 1 ));
1451
+ ts -> nConfigChanges = Mtm -> nConfigChanges ;
1444
1452
ts -> votedMask = 0 ;
1445
1453
strcpy (ts -> gid , gid );
1446
1454
MtmTransactionListAppend (ts );
@@ -1601,9 +1609,9 @@ void MtmAbortTransaction(MtmTransState* ts)
1601
1609
Assert (MtmLockCount != 0 ); /* should be invoked with exclsuive lock */
1602
1610
if (ts -> status != TRANSACTION_STATUS_ABORTED ) {
1603
1611
if (ts -> status == TRANSACTION_STATUS_COMMITTED ) {
1604
- elog (LOG , "Attempt to rollback already committed transaction %d (%s )" , ts -> xid , ts -> gid );
1612
+ elog (LOG , "Attempt to rollback already committed transaction %s (%d )" , ts -> gid , ts -> xid );
1605
1613
} else {
1606
- MTM_LOG1 ("Rollback active transaction %d:%d (local xid %d) status %s" , ts -> gtid . node , ts -> gtid .xid , ts -> xid , MtmTxnStatusMnem [ts -> status ]);
1614
+ MTM_LOG1 ("Rollback active transaction %s ( %d) %d:%d status %s" , ts -> gid , ts -> xid , ts -> gtid .node , ts -> gtid . xid , MtmTxnStatusMnem [ts -> status ]);
1607
1615
ts -> status = TRANSACTION_STATUS_ABORTED ;
1608
1616
MtmAdjustSubtransactions (ts );
1609
1617
if (ts -> isActive ) {
@@ -3094,9 +3102,9 @@ void MtmReleaseRecoverySlot(int nodeId)
3094
3102
void MtmRollbackPreparedTransaction (int nodeId , char const * gid )
3095
3103
{
3096
3104
XidStatus status = MtmExchangeGlobalTransactionStatus (gid , TRANSACTION_STATUS_ABORTED );
3097
- MTM_LOG1 ("Abort prepared transaction %s status %s" , gid , MtmTxnStatusMnem [status ]);
3105
+ MTM_LOG1 ("Abort prepared transaction %s status %s from node %d originId=%d " , gid , MtmTxnStatusMnem [status ], nodeId , Mtm -> nodes [ nodeId - 1 ]. originId );
3098
3106
if (status == TRANSACTION_STATUS_UNKNOWN ) {
3099
- MTM_LOG2 ("PGLOGICAL_ABORT_PREPARED commit: gid=%s #2" , gid );
3107
+ MTM_LOG1 ("PGLOGICAL_ABORT_PREPARED commit: gid=%s #2" , gid );
3100
3108
MtmResetTransaction ();
3101
3109
StartTransactionCommand ();
3102
3110
MtmBeginSession (nodeId );
@@ -3806,6 +3814,7 @@ mtm_get_trans_by_gid(PG_FUNCTION_ARGS)
3806
3814
values [11 ] = BoolGetDatum (ts -> votingCompleted );
3807
3815
values [12 ] = Int64GetDatum (ts -> participantsMask );
3808
3816
values [13 ] = Int64GetDatum (ts -> votedMask );
3817
+ values [14 ] = Int32GetDatum (ts -> nConfigChanges );
3809
3818
}
3810
3819
MtmUnlock ();
3811
3820
@@ -4246,12 +4255,12 @@ static bool MtmTwoPhaseCommit(MtmCurrentTrans* x)
4246
4255
} else {
4247
4256
CommitTransactionCommand ();
4248
4257
if (x -> isSuspended ) {
4249
- elog (WARNING , "Transaction %s is left in prepared state because coordinator node is not online" , x -> gid );
4258
+ elog (WARNING , "Transaction %s (%d) is left in prepared state because coordinator node is not online" , x -> gid , x -> xid );
4250
4259
} else {
4251
4260
StartTransactionCommand ();
4252
4261
if (x -> status == TRANSACTION_STATUS_ABORTED ) {
4253
4262
FinishPreparedTransaction (x -> gid , false);
4254
- elog (ERROR , "Transaction aborted by DTM" );
4263
+ elog (ERROR , "Transaction %s (%d) is aborted by DTM" , x -> gid , x -> xid );
4255
4264
} else {
4256
4265
FinishPreparedTransaction (x -> gid , true);
4257
4266
}
@@ -4382,14 +4391,13 @@ static void MtmGucSet(VariableSetStmt *stmt, const char *queryStr)
4382
4391
MemoryContextSwitchTo (oldcontext );
4383
4392
}
4384
4393
4385
- static char * MtmGucSerialize (void )
4394
+ char * MtmGucSerialize (void )
4386
4395
{
4387
4396
StringInfo serialized_gucs ;
4388
4397
dlist_iter iter ;
4389
4398
int nvars = 0 ;
4390
4399
4391
4400
serialized_gucs = makeStringInfo ();
4392
- appendStringInfoString (serialized_gucs , "RESET SESSION AUTHORIZATION; reset all; " );
4393
4401
4394
4402
dlist_foreach (iter , & MtmGucList )
4395
4403
{
@@ -4423,30 +4431,16 @@ static char * MtmGucSerialize(void)
4423
4431
* -------------------------------------------
4424
4432
*/
4425
4433
4426
- static bool MtmProcessDDLCommand (char const * queryString , bool transactional , bool contextFree )
4434
+ static bool MtmProcessDDLCommand (char const * queryString , bool transactional )
4427
4435
{
4428
- char * queryWithContext = (char * ) queryString ;
4429
- char * gucContext ;
4430
-
4431
- if (!contextFree ) {
4432
- /* Append global GUC to utility stmt. */
4433
- gucContext = MtmGucSerialize ();
4434
- if (gucContext )
4435
- {
4436
- queryWithContext = palloc (strlen (gucContext ) + strlen (queryString ) + 1 );
4437
- strcpy (queryWithContext , gucContext );
4438
- strcat (queryWithContext , queryString );
4439
- }
4440
- }
4441
-
4442
- MTM_LOG3 ("Sending utility: %s" , queryWithContext );
4436
+ MTM_LOG3 ("Sending utility: %s" , queryString );
4443
4437
if (transactional ) {
4444
4438
/* DDL */
4445
- LogLogicalMessage ("D" , queryWithContext , strlen (queryWithContext ) + 1 , true);
4439
+ LogLogicalMessage ("D" , queryString , strlen (queryString ) + 1 , true);
4446
4440
MtmTx .containsDML = true;
4447
4441
} else {
4448
4442
/* CONCURRENT DDL */
4449
- XLogFlush (LogLogicalMessage ("C" , queryWithContext , strlen (queryWithContext ) + 1 , false));
4443
+ XLogFlush (LogLogicalMessage ("C" , queryString , strlen (queryString ) + 1 , false));
4450
4444
}
4451
4445
return false;
4452
4446
}
@@ -4718,9 +4712,9 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
4718
4712
MtmUtilityProcessedInXid = GetCurrentTransactionId ();
4719
4713
4720
4714
if (context == PROCESS_UTILITY_TOPLEVEL )
4721
- MtmProcessDDLCommand (queryString , true, false );
4715
+ MtmProcessDDLCommand (queryString , true);
4722
4716
else
4723
- MtmProcessDDLCommand (ActivePortal -> sourceText , true, false );
4717
+ MtmProcessDDLCommand (ActivePortal -> sourceText , true);
4724
4718
4725
4719
executed = true;
4726
4720
}
@@ -4777,7 +4771,7 @@ MtmExecutorStart(QueryDesc *queryDesc, int eflags)
4777
4771
}
4778
4772
4779
4773
if (ddl_generating_call && !MtmTx .isReplicated )
4780
- MtmProcessDDLCommand (ActivePortal -> sourceText , true, false );
4774
+ MtmProcessDDLCommand (ActivePortal -> sourceText , true);
4781
4775
4782
4776
if (PreviousExecutorStartHook != NULL )
4783
4777
PreviousExecutorStartHook (queryDesc , eflags );
0 commit comments