@@ -1964,6 +1964,7 @@ static void MtmEnableNode(int nodeId)
1964
1964
if (BIT_SET (Mtm -> disabledNodeMask , nodeId - 1 )) {
1965
1965
BIT_CLEAR (Mtm -> disabledNodeMask , nodeId - 1 );
1966
1966
BIT_CLEAR (Mtm -> reconnectMask , nodeId - 1 );
1967
+ BIT_SET (Mtm -> recoveredNodeMask , nodeId - 1 );
1967
1968
Mtm -> nConfigChanges += 1 ;
1968
1969
Mtm -> nodes [nodeId - 1 ].lastStatusChangeTime = MtmGetSystemTime ();
1969
1970
Mtm -> nodes [nodeId - 1 ].lastHeartbeat = 0 ; /* defuse watchdog until first heartbeat is received */
@@ -2132,6 +2133,7 @@ bool MtmRecoveryCaughtUp(int nodeId, lsn_t walEndPtr)
2132
2133
Assert (BIT_CHECK (Mtm -> disabledNodeMask , nodeId - 1 ));
2133
2134
BIT_CLEAR (Mtm -> originLockNodeMask , nodeId - 1 );
2134
2135
BIT_CLEAR (Mtm -> disabledNodeMask , nodeId - 1 );
2136
+ BIT_SET (Mtm -> recoveredNodeMask , nodeId - 1 );
2135
2137
Mtm -> nLiveNodes += 1 ;
2136
2138
MtmCheckQuorum ();
2137
2139
} else {
@@ -2271,6 +2273,22 @@ MtmBuildConnectivityMatrix(nodemask_t* matrix)
2271
2273
}
2272
2274
2273
2275
2276
+ static int MtmGetNumberOfVotingNodes ()
2277
+ {
2278
+ int i ;
2279
+ int nVotingNodes = Mtm -> nAllNodes ;
2280
+ notebask_t deadNodeMask = Mtm -> deadNodeMask ;
2281
+ for (i = 0 ; deadNodeMask != 0 ; i ++ ) {
2282
+ if (BIT_CHECK (deadNodeMask , i )) {
2283
+ if (!BIT_CHECK (newClique , i )) {
2284
+ nVotingNodes -= 1 ;
2285
+ }
2286
+ BIT_CLEAR (deadNodeMask , i );
2287
+ }
2288
+ }
2289
+ return nVotingNodes ;
2290
+ }
2291
+
2274
2292
/**
2275
2293
* Build connectivity graph, find clique in it and extend disabledNodeMask by nodes not included in clique.
2276
2294
* This function is called by arbiter monitor process with period MtmHeartbeatSendTimeout
@@ -2281,9 +2299,7 @@ void MtmRefreshClusterStatus()
2281
2299
nodemask_t matrix [MAX_NODES ];
2282
2300
int cliqueSize ;
2283
2301
nodemask_t oldClique = ~Mtm -> disabledNodeMask & (((nodemask_t )1 << Mtm -> nAllNodes )- 1 );
2284
- nodemask_t arbitratorDisabledMask ;
2285
2302
int nVotingNodes ;
2286
- int i ;
2287
2303
2288
2304
MtmBuildConnectivityMatrix (matrix );
2289
2305
newClique = MtmFindMaxClique (matrix , Mtm -> nAllNodes , & cliqueSize );
@@ -2304,16 +2320,7 @@ void MtmRefreshClusterStatus()
2304
2320
newClique = MtmFindMaxClique (matrix , Mtm -> nAllNodes , & cliqueSize );
2305
2321
} while (newClique != oldClique );
2306
2322
2307
- nVotingNodes = Mtm -> nAllNodes ;
2308
- arbitratorDisabledMask = Mtm -> arbitratorDisabledMask ;
2309
- for (i = 0 ; arbitratorDisabledMask != 0 ; i ++ ) {
2310
- if (BIT_CHECK (arbitratorDisabledMask , i )) {
2311
- if (!BIT_CHECK (newClique , i )) {
2312
- nVotingNodes -= 1 ;
2313
- }
2314
- BIT_CLEAR (arbitratorDisabledMask , i );
2315
- }
2316
- }
2323
+ nVotingNodes = MtmGetNumberOfVotingNodes ();
2317
2324
if (cliqueSize >= nVotingNodes /2 + 1 || (cliqueSize == (nVotingNodes + 1 )/2 && MtmMajorNode )) { /* have quorum */
2318
2325
fprintf (stderr , "Old mask: " );
2319
2326
for (i = 0 ; i < Mtm -> nAllNodes ; i ++ ) {
@@ -2378,7 +2385,9 @@ void MtmRefreshClusterStatus()
2378
2385
*/
2379
2386
void MtmCheckQuorum (void )
2380
2387
{
2381
- if (Mtm -> nLiveNodes >= Mtm -> nAllNodes /2 + 1 || (Mtm -> nLiveNodes == (Mtm -> nAllNodes + 1 )/2 && MtmMajorNode )) { /* have quorum */
2388
+ int nVotingNodes = MtmGetNumberOfVotingNodes ();
2389
+
2390
+ if (Mtm -> nLiveNodes >= nVotingNodes /2 + 1 || (Mtm -> nLiveNodes == (nVotingNodes + 1 )/2 && MtmMajorNode )) { /* have quorum */
2382
2391
if (Mtm -> status == MTM_IN_MINORITY ) {
2383
2392
MTM_LOG1 ("Node is in majority: disabled mask %llx" , Mtm -> disabledNodeMask );
2384
2393
MtmSwitchClusterMode (MTM_ONLINE );
@@ -2626,7 +2635,8 @@ static void MtmInitialize()
2626
2635
Mtm -> disabledNodeMask = 0 ;
2627
2636
Mtm -> stalledNodeMask = 0 ;
2628
2637
Mtm -> stoppedNodeMask = 0 ;
2629
- Mtm -> arbitratorDisabledMask = 0 ;
2638
+ Mtm -> deadNodeMask = 0 ;
2639
+ Mtm -> recoveredNodeMask = 0 ;
2630
2640
Mtm -> pglogicalReceiverMask = 0 ;
2631
2641
Mtm -> pglogicalSenderMask = 0 ;
2632
2642
Mtm -> inducedLockNodeMask = 0 ;
@@ -5444,6 +5454,14 @@ Datum mtm_check_deadlock(PG_FUNCTION_ARGS)
5444
5454
5445
5455
Datum mtm_arbitrator_poll (PG_FUNCTION_ARGS )
5446
5456
{
5447
- Mtm -> arbitratorDisabledMask = PG_GETARG_INT64 (0 );
5448
- PG_RETURN_INT64 (Mtm -> disabledNodeMask );
5457
+ nodemask_t recoveredNodeMask ;
5458
+
5459
+ MtmLock (LW_EXCLUSIVE );
5460
+ recoveredNodeMask = Mtm -> recoveredNodeMask ;
5461
+ Mtm -> deadNodeMask = PG_GETARG_INT64 (0 );
5462
+ Mtm -> recoveredNodeMask &= ~Mtm -> deadNodeMask ;
5463
+ MtmCheckQuorum ();
5464
+ MtmUnlock ();
5465
+
5466
+ PG_RETURN_INT64 (recoveredNodeMask );
5449
5467
}
0 commit comments