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