checkValidity(nodeName, "Transferring mastership");
/* Check if the replica is alive. */
Feeder feeder = feederManager.getFeeder(nodeName);
if (feeder == null) {
throw new MasterTransferFailureException
("Replica is going to be the master is not alive, transfer " +
"fails, master doesn't change.");
}
long catchupTimeout =
getConfigManager().getDuration(CATCHUP_MASTER_TIMEOUT);
long catchupPhase2Timeout =
getConfigManager().getDuration(CATCHUP_MASTER_PHASE2_TIMEOUT);
try {
/*
* First phase: the replica catches up with the master.
*
* Transactions commits are not blocked at this time. Even though
* application writes are blocked, note that internal transactions
* may be in active and may cause the currentTxnEndVLSN to advance.
*
* In this first phase, the replica only needs to catch up with the
* currentTxnEndVLSN value in order for the phase to complete.
*/
replicaCatchupMaster(feeder, catchupTimeout, true);
/*
* Second phase: transferring the state.
*
* During this phase, MasterTxn commits/aborts are blocked.
*/
repImpl.createAndSetBlockLatch();
/*
* Now we stop all the transactions, both internal and those
* started by users. In this case, we expect the feederVLSN to be
* the same as the currentTxnEndVLSN value after the catch up.
*/
replicaCatchupMaster(feeder, catchupPhase2Timeout, false);
} catch (Exception e) {
/*
* Release the transaction blocking latch if the catching up phase
* is not successfully finished.
*/
repImpl.countDownBlockLatch();
throw new MasterTransferFailureException(e.getMessage());
}
TestHookExecute.doHookIfSet(masterTransferHook);
/* Broadcast the result message to elect a new master. */