@@ -155,7 +155,8 @@ char const* const MtmNodeStatusMnem[] =
155
155
"Offline" ,
156
156
"Connected" ,
157
157
"Online" ,
158
- "Recovery"
158
+ "Recovery" ,
159
+ "InMinor"
159
160
};
160
161
161
162
bool MtmDoReplication ;
@@ -631,10 +632,11 @@ MtmBeginTransaction(MtmCurrentTrans* x)
631
632
x -> isReplicated = false;
632
633
x -> isDistributed = MtmIsUserTransaction ();
633
634
x -> isPrepared = false;
634
- if (x -> isDistributed && Mtm -> status != MTM_ONLINE ) {
635
+ x -> isTransactionBlock = IsTransactionBlock ();
636
+ /* Application name can be cahnged usnig PGAPPNAME environment variable */
637
+ if (x -> isDistributed && Mtm -> status != MTM_ONLINE && strcmp (application_name , MULTIMASTER_ADMIN ) != 0 ) {
635
638
/* reject all user's transactions at offline cluster */
636
639
MtmUnlock ();
637
- Assert (Mtm -> status == MTM_ONLINE );
638
640
elog (ERROR , "Multimaster node is not online: current status %s" , MtmNodeStatusMnem [Mtm -> status ]);
639
641
}
640
642
x -> containsDML = false;
@@ -981,11 +983,14 @@ bool MtmIsRecoveredNode(int nodeId)
981
983
* We have to maintain two bitmasks: one is marking wal sender, another - correspondent nodes.
982
984
* Is there some better way to establish mapping between nodes ad WAL-seconder?
983
985
*/
986
+ elog (WARNING ,"Node %d is catching up" , nodeId );
984
987
MtmLock (LW_EXCLUSIVE );
985
988
BIT_SET (Mtm -> nodeLockerMask , nodeId - 1 );
986
989
BIT_SET (Mtm -> walSenderLockerMask , MyWalSnd - WalSndCtl -> walsnds );
987
990
Mtm -> nLockers += 1 ;
988
991
MtmUnlock ();
992
+ } else {
993
+ MTM_INFO ("Continue recovery of node %d, slot position %lx, WAL position %lx, lockers %d\n" , nodeId , MyWalSnd -> sentPtr , GetXLogInsertRecPtr (), Mtm -> nLockers );
989
994
}
990
995
return true;
991
996
}
@@ -1022,7 +1027,7 @@ MtmCheckClusterLock()
1022
1027
break ;
1023
1028
} else {
1024
1029
/* recovered replica catched up with master */
1025
- elog (WARNING , "WAL-sender %d complete receovery " , i );
1030
+ elog (WARNING , "WAL-sender %d complete recovery " , i );
1026
1031
BIT_CLEAR (Mtm -> walSenderLockerMask , i );
1027
1032
}
1028
1033
}
@@ -1608,8 +1613,9 @@ void MtmReceiverStarted(int nodeId)
1608
1613
if (!BIT_CHECK (Mtm -> pglogicalNodeMask , nodeId - 1 )) {
1609
1614
BIT_SET (Mtm -> pglogicalNodeMask , nodeId - 1 );
1610
1615
if (++ Mtm -> nReceivers == Mtm -> nNodes - 1 ) {
1611
- Assert (Mtm -> status == MTM_CONNECTED );
1612
- MtmSwitchClusterMode (MTM_ONLINE );
1616
+ if (Mtm -> status == MTM_CONNECTED ) {
1617
+ MtmSwitchClusterMode (MTM_ONLINE );
1618
+ }
1613
1619
}
1614
1620
}
1615
1621
SpinLockRelease (& Mtm -> spinlock );
@@ -1622,19 +1628,28 @@ void MtmReceiverStarted(int nodeId)
1622
1628
*/
1623
1629
MtmSlotMode MtmReceiverSlotMode (int nodeId )
1624
1630
{
1631
+ bool recovery = false;
1625
1632
while (Mtm -> status != MTM_CONNECTED && Mtm -> status != MTM_ONLINE ) {
1633
+ MTM_INFO ("%d: receiver slot mode %s\n" , MyProcPid , MtmNodeStatusMnem [Mtm -> status ]);
1626
1634
if (Mtm -> status == MTM_RECOVERY ) {
1635
+ recovery = true;
1627
1636
if (Mtm -> recoverySlot == 0 || Mtm -> recoverySlot == nodeId ) {
1628
1637
/* Choose for recovery first available slot */
1638
+ elog (WARNING , "Start recovery from node %d" , nodeId );
1629
1639
Mtm -> recoverySlot = nodeId ;
1630
1640
return SLOT_OPEN_EXISTED ;
1631
1641
}
1632
1642
}
1633
1643
/* delay opening of other slots until recovery is completed */
1634
1644
MtmSleep (STATUS_POLL_DELAY );
1635
1645
}
1646
+ if (recovery ) {
1647
+ elog (WARNING , "Recreate replication slot for node %d after end of recovery" , nodeId );
1648
+ } else {
1649
+ MTM_INFO ("%d: Reuse replication slot for node %d\n" , MyProcPid , nodeId );
1650
+ }
1636
1651
/* After recovery completion we need to drop all other slots to avoid receive of redundant data */
1637
- return Mtm -> recoverySlot ? SLOT_CREATE_NEW : SLOT_OPEN_ALWAYS ;
1652
+ return recovery ? SLOT_CREATE_NEW : SLOT_OPEN_ALWAYS ;
1638
1653
}
1639
1654
1640
1655
static bool MtmIsBroadcast ()
@@ -1690,7 +1705,11 @@ MtmReplicationShutdownHook(struct PGLogicalShutdownHookArgs* args)
1690
1705
static bool
1691
1706
MtmReplicationTxnFilterHook (struct PGLogicalTxnFilterArgs * args )
1692
1707
{
1693
- return args -> origin_id == InvalidRepOriginId || MtmIsRecoveredNode (MtmReplicationNodeId );
1708
+ bool res = Mtm -> status != MTM_RECOVERY
1709
+ && (args -> origin_id == InvalidRepOriginId
1710
+ || MtmIsRecoveredNode (MtmReplicationNodeId ));
1711
+ MTM_TRACE ("%d: MtmReplicationTxnFilterHook->%d\n" , MyProcPid , res );
1712
+ return res ;
1694
1713
}
1695
1714
1696
1715
void MtmSetupReplicationHooks (struct PGLogicalHooks * hooks )
0 commit comments