mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
Bug#25275 SINGLE USER MODE prevents ALTER on non-ndb tables for other mysqld nodes
- refactor single user and move single user checks from api to kernel
This commit is contained in:
parent
6c25da9d5b
commit
47f37fb346
5 changed files with 143 additions and 30 deletions
|
@ -1835,9 +1835,14 @@ private:
|
||||||
Uint32 transid2);
|
Uint32 transid2);
|
||||||
void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket);
|
void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket);
|
||||||
|
|
||||||
bool getAllowStartTransaction() const {
|
bool getAllowStartTransaction(Uint32 nodeId) const {
|
||||||
if(getNodeState().getSingleUserMode())
|
if (unlikely(getNodeState().getSingleUserMode()))
|
||||||
|
{
|
||||||
|
if (getNodeState().getSingleUserApi() == nodeId)
|
||||||
return true;
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return getNodeState().startLevel < NodeState::SL_STOPPING_2;
|
return getNodeState().startLevel < NodeState::SL_STOPPING_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1199,16 +1199,14 @@ void Dbtc::execTCSEIZEREQ(Signal* signal)
|
||||||
const NodeId senderNodeId = refToNode(tapiBlockref);
|
const NodeId senderNodeId = refToNode(tapiBlockref);
|
||||||
const bool local = senderNodeId == getOwnNodeId() || senderNodeId == 0;
|
const bool local = senderNodeId == getOwnNodeId() || senderNodeId == 0;
|
||||||
|
|
||||||
if(!(senderNodeId == getNodeState().getSingleUserApi()) &&
|
{
|
||||||
!getNodeState().getSingleUserMode()) {
|
{
|
||||||
if(!(sl==NodeState::SL_SINGLEUSER &&
|
|
||||||
senderNodeId == getNodeState().getSingleUserApi())) {
|
|
||||||
if (!(sl == NodeState::SL_STARTED ||
|
if (!(sl == NodeState::SL_STARTED ||
|
||||||
(sl == NodeState::SL_STARTING && local == true))) {
|
(sl == NodeState::SL_STARTING && local == true))) {
|
||||||
jam();
|
jam();
|
||||||
|
|
||||||
Uint32 errCode;
|
Uint32 errCode = 0;
|
||||||
if(!(sl == NodeState::SL_SINGLEUSER && local))
|
if(!local)
|
||||||
{
|
{
|
||||||
switch(sl){
|
switch(sl){
|
||||||
case NodeState::SL_STARTING:
|
case NodeState::SL_STARTING:
|
||||||
|
@ -1216,6 +1214,9 @@ void Dbtc::execTCSEIZEREQ(Signal* signal)
|
||||||
break;
|
break;
|
||||||
case NodeState::SL_STOPPING_1:
|
case NodeState::SL_STOPPING_1:
|
||||||
case NodeState::SL_STOPPING_2:
|
case NodeState::SL_STOPPING_2:
|
||||||
|
if (getNodeState().getSingleUserMode() &&
|
||||||
|
getNodeState().getSingleUserApi() == senderNodeId)
|
||||||
|
break;
|
||||||
case NodeState::SL_STOPPING_3:
|
case NodeState::SL_STOPPING_3:
|
||||||
case NodeState::SL_STOPPING_4:
|
case NodeState::SL_STOPPING_4:
|
||||||
if(getNodeState().stopping.systemShutdown)
|
if(getNodeState().stopping.systemShutdown)
|
||||||
|
@ -1224,16 +1225,21 @@ void Dbtc::execTCSEIZEREQ(Signal* signal)
|
||||||
errCode = ZNODE_SHUTDOWN_IN_PROGRESS;
|
errCode = ZNODE_SHUTDOWN_IN_PROGRESS;
|
||||||
break;
|
break;
|
||||||
case NodeState::SL_SINGLEUSER:
|
case NodeState::SL_SINGLEUSER:
|
||||||
|
if (getNodeState().getSingleUserApi() == senderNodeId)
|
||||||
|
break;
|
||||||
errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errCode = ZWRONG_STATE;
|
errCode = ZWRONG_STATE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (errCode)
|
||||||
|
{
|
||||||
signal->theData[0] = tapiPointer;
|
signal->theData[0] = tapiPointer;
|
||||||
signal->theData[1] = errCode;
|
signal->theData[1] = errCode;
|
||||||
sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
|
sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}//if (!(sl == SL_SINGLEUSER))
|
}//if (!(sl == SL_SINGLEUSER))
|
||||||
} //if
|
} //if
|
||||||
}
|
}
|
||||||
|
@ -1720,8 +1726,14 @@ Dbtc::TCKEY_abort(Signal* signal, int place)
|
||||||
* Initialize object before starting error handling
|
* Initialize object before starting error handling
|
||||||
*/
|
*/
|
||||||
initApiConnectRec(signal, apiConnectptr.p, true);
|
initApiConnectRec(signal, apiConnectptr.p, true);
|
||||||
|
start_failure:
|
||||||
switch(getNodeState().startLevel){
|
switch(getNodeState().startLevel){
|
||||||
case NodeState::SL_STOPPING_2:
|
case NodeState::SL_STOPPING_2:
|
||||||
|
if (getNodeState().getSingleUserMode())
|
||||||
|
{
|
||||||
|
terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case NodeState::SL_STOPPING_3:
|
case NodeState::SL_STOPPING_3:
|
||||||
case NodeState::SL_STOPPING_4:
|
case NodeState::SL_STOPPING_4:
|
||||||
if(getNodeState().stopping.systemShutdown)
|
if(getNodeState().stopping.systemShutdown)
|
||||||
|
@ -1732,6 +1744,12 @@ Dbtc::TCKEY_abort(Signal* signal, int place)
|
||||||
case NodeState::SL_SINGLEUSER:
|
case NodeState::SL_SINGLEUSER:
|
||||||
terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
||||||
break;
|
break;
|
||||||
|
case NodeState::SL_STOPPING_1:
|
||||||
|
if (getNodeState().getSingleUserMode())
|
||||||
|
{
|
||||||
|
terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
terrorCode = ZWRONG_STATE;
|
terrorCode = ZWRONG_STATE;
|
||||||
break;
|
break;
|
||||||
|
@ -1753,6 +1771,13 @@ Dbtc::TCKEY_abort(Signal* signal, int place)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 60:
|
||||||
|
{
|
||||||
|
jam();
|
||||||
|
initApiConnectRec(signal, apiConnectptr.p, true);
|
||||||
|
apiConnectptr.p->m_exec_flag = 1;
|
||||||
|
goto start_failure;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
jam();
|
jam();
|
||||||
systemErrorLab(signal, __LINE__);
|
systemErrorLab(signal, __LINE__);
|
||||||
|
@ -2481,6 +2506,7 @@ Dbtc::seizeCacheRecord(Signal* signal)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void Dbtc::execTCKEYREQ(Signal* signal)
|
void Dbtc::execTCKEYREQ(Signal* signal)
|
||||||
{
|
{
|
||||||
|
Uint32 sendersNodeId = refToNode(signal->getSendersBlockRef());
|
||||||
UintR compare_transid1, compare_transid2;
|
UintR compare_transid1, compare_transid2;
|
||||||
UintR titcLenAiInTckeyreq;
|
UintR titcLenAiInTckeyreq;
|
||||||
UintR TkeyLength;
|
UintR TkeyLength;
|
||||||
|
@ -2526,7 +2552,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
||||||
regApiPtr->m_exec_flag |= TexecFlag;
|
regApiPtr->m_exec_flag |= TexecFlag;
|
||||||
switch (regApiPtr->apiConnectstate) {
|
switch (regApiPtr->apiConnectstate) {
|
||||||
case CS_CONNECTED:{
|
case CS_CONNECTED:{
|
||||||
if (TstartFlag == 1 && getAllowStartTransaction() == true){
|
if (TstartFlag == 1 && getAllowStartTransaction(sendersNodeId) == true){
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Initialise API connect record if transaction is started.
|
// Initialise API connect record if transaction is started.
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
@ -2534,7 +2560,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
||||||
initApiConnectRec(signal, regApiPtr);
|
initApiConnectRec(signal, regApiPtr);
|
||||||
regApiPtr->m_exec_flag = TexecFlag;
|
regApiPtr->m_exec_flag = TexecFlag;
|
||||||
} else {
|
} else {
|
||||||
if(getAllowStartTransaction() == true){
|
if(getAllowStartTransaction(sendersNodeId) == true){
|
||||||
/*------------------------------------------------------------------
|
/*------------------------------------------------------------------
|
||||||
* WE EXPECTED A START TRANSACTION. SINCE NO OPERATIONS HAVE BEEN
|
* WE EXPECTED A START TRANSACTION. SINCE NO OPERATIONS HAVE BEEN
|
||||||
* RECEIVED WE INDICATE THIS BY SETTING FIRST_TC_CONNECT TO RNIL TO
|
* RECEIVED WE INDICATE THIS BY SETTING FIRST_TC_CONNECT TO RNIL TO
|
||||||
|
@ -2544,9 +2570,9 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
* getAllowStartTransaction() == false
|
* getAllowStartTransaction(sendersNodeId) == false
|
||||||
*/
|
*/
|
||||||
TCKEY_abort(signal, 57);
|
TCKEY_abort(signal, TexecFlag ? 60 : 57);
|
||||||
return;
|
return;
|
||||||
}//if
|
}//if
|
||||||
}
|
}
|
||||||
|
@ -6161,9 +6187,11 @@ and otherwise we spread it out 310 ms.
|
||||||
void Dbtc::timeOutLoopStartLab(Signal* signal, Uint32 api_con_ptr)
|
void Dbtc::timeOutLoopStartLab(Signal* signal, Uint32 api_con_ptr)
|
||||||
{
|
{
|
||||||
Uint32 end_ptr, time_passed, time_out_value, mask_value;
|
Uint32 end_ptr, time_passed, time_out_value, mask_value;
|
||||||
|
Uint32 old_mask_value= 0;
|
||||||
const Uint32 api_con_sz= capiConnectFilesize;
|
const Uint32 api_con_sz= capiConnectFilesize;
|
||||||
const Uint32 tc_timer= ctcTimer;
|
const Uint32 tc_timer= ctcTimer;
|
||||||
const Uint32 time_out_param= ctimeOutValue;
|
const Uint32 time_out_param= ctimeOutValue;
|
||||||
|
const Uint32 old_time_out_param= c_abortRec.oldTimeOutValue;
|
||||||
|
|
||||||
ctimeOutCheckHeartbeat = tc_timer;
|
ctimeOutCheckHeartbeat = tc_timer;
|
||||||
|
|
||||||
|
@ -6184,11 +6212,39 @@ void Dbtc::timeOutLoopStartLab(Signal* signal, Uint32 api_con_ptr)
|
||||||
jam();
|
jam();
|
||||||
mask_value= 31;
|
mask_value= 31;
|
||||||
}
|
}
|
||||||
|
if (time_out_param != old_time_out_param &&
|
||||||
|
getNodeState().getSingleUserMode())
|
||||||
|
{
|
||||||
|
// abort during single user mode, use old_mask_value as flag
|
||||||
|
// and calculate value to be used for connections with allowed api
|
||||||
|
if (old_time_out_param > 300) {
|
||||||
|
jam();
|
||||||
|
old_mask_value= 63;
|
||||||
|
} else if (old_time_out_param < 30) {
|
||||||
|
jam();
|
||||||
|
old_mask_value= 7;
|
||||||
|
} else {
|
||||||
|
jam();
|
||||||
|
old_mask_value= 31;
|
||||||
|
}
|
||||||
|
}
|
||||||
for ( ; api_con_ptr < end_ptr; api_con_ptr++) {
|
for ( ; api_con_ptr < end_ptr; api_con_ptr++) {
|
||||||
Uint32 api_timer= getApiConTimer(api_con_ptr);
|
Uint32 api_timer= getApiConTimer(api_con_ptr);
|
||||||
jam();
|
jam();
|
||||||
if (api_timer != 0) {
|
if (api_timer != 0) {
|
||||||
time_out_value= time_out_param + (api_con_ptr & mask_value);
|
time_out_value= time_out_param + (api_con_ptr & mask_value);
|
||||||
|
if (unlikely(old_mask_value)) // abort during single user mode
|
||||||
|
{
|
||||||
|
apiConnectptr.i = api_con_ptr;
|
||||||
|
ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
|
||||||
|
if (getNodeState().getSingleUserApi() ==
|
||||||
|
refToNode(apiConnectptr.p->ndbapiBlockref))
|
||||||
|
{
|
||||||
|
// api allowed during single user, use original timeout
|
||||||
|
time_out_value=
|
||||||
|
old_time_out_param + (api_con_ptr & old_mask_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
time_passed= tc_timer - api_timer;
|
time_passed= tc_timer - api_timer;
|
||||||
if (time_passed > time_out_value)
|
if (time_passed > time_out_value)
|
||||||
{
|
{
|
||||||
|
@ -6805,6 +6861,33 @@ void Dbtc::timeOutFoundFragLab(Signal* signal, UintR TscanConPtr)
|
||||||
c_scan_frag_pool.getPtr(ptr, TscanConPtr);
|
c_scan_frag_pool.getPtr(ptr, TscanConPtr);
|
||||||
DEBUG(TscanConPtr << " timeOutFoundFragLab: scanFragState = "<< ptr.p->scanFragState);
|
DEBUG(TscanConPtr << " timeOutFoundFragLab: scanFragState = "<< ptr.p->scanFragState);
|
||||||
|
|
||||||
|
const Uint32 time_out_param= ctimeOutValue;
|
||||||
|
const Uint32 old_time_out_param= c_abortRec.oldTimeOutValue;
|
||||||
|
|
||||||
|
if (unlikely(time_out_param != old_time_out_param &&
|
||||||
|
getNodeState().getSingleUserMode()))
|
||||||
|
{
|
||||||
|
jam();
|
||||||
|
ScanRecordPtr scanptr;
|
||||||
|
scanptr.i = ptr.p->scanRec;
|
||||||
|
ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
|
||||||
|
ApiConnectRecordPtr TlocalApiConnectptr;
|
||||||
|
TlocalApiConnectptr.i = scanptr.p->scanApiRec;
|
||||||
|
ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
|
||||||
|
|
||||||
|
if (refToNode(TlocalApiConnectptr.p->ndbapiBlockref) ==
|
||||||
|
getNodeState().getSingleUserApi())
|
||||||
|
{
|
||||||
|
jam();
|
||||||
|
Uint32 val = ctcTimer - ptr.p->scanFragTimer;
|
||||||
|
if (val <= old_time_out_param)
|
||||||
|
{
|
||||||
|
jam();
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
// The scan fragment has expired its timeout. Check its state to decide
|
// The scan fragment has expired its timeout. Check its state to decide
|
||||||
// what to do.
|
// what to do.
|
||||||
|
@ -6866,6 +6949,7 @@ void Dbtc::timeOutFoundFragLab(Signal* signal, UintR TscanConPtr)
|
||||||
break;
|
break;
|
||||||
}//switch
|
}//switch
|
||||||
|
|
||||||
|
next:
|
||||||
signal->theData[0] = TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL;
|
signal->theData[0] = TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL;
|
||||||
signal->theData[1] = TscanConPtr + 1;
|
signal->theData[1] = TscanConPtr + 1;
|
||||||
sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
|
sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
|
||||||
|
@ -8696,6 +8780,14 @@ void Dbtc::execSCAN_TABREQ(Signal* signal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getNodeState().startLevel == NodeState::SL_SINGLEUSER &&
|
||||||
|
getNodeState().getSingleUserApi() !=
|
||||||
|
refToNode(apiConnectptr.p->ndbapiBlockref))
|
||||||
|
{
|
||||||
|
errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
||||||
|
goto SCAN_TAB_error;
|
||||||
|
}
|
||||||
|
|
||||||
seizeTcConnect(signal);
|
seizeTcConnect(signal);
|
||||||
tcConnectptr.p->apiConnect = apiConnectptr.i;
|
tcConnectptr.p->apiConnect = apiConnectptr.i;
|
||||||
tcConnectptr.p->tcConnectstate = OS_WAIT_SCAN;
|
tcConnectptr.p->tcConnectstate = OS_WAIT_SCAN;
|
||||||
|
@ -11038,7 +11130,7 @@ void Dbtc::execABORT_ALL_REQ(Signal* signal)
|
||||||
const Uint32 senderData = req->senderData;
|
const Uint32 senderData = req->senderData;
|
||||||
const BlockReference senderRef = req->senderRef;
|
const BlockReference senderRef = req->senderRef;
|
||||||
|
|
||||||
if(getAllowStartTransaction() == true && !getNodeState().getSingleUserMode()){
|
if(getAllowStartTransaction(refToNode(senderRef)) == true && !getNodeState().getSingleUserMode()){
|
||||||
jam();
|
jam();
|
||||||
|
|
||||||
ref->senderData = senderData;
|
ref->senderData = senderData;
|
||||||
|
@ -11466,6 +11558,17 @@ void Dbtc::execTCINDXREQ(Signal* signal)
|
||||||
regApiPtr->transid[1] = tcIndxReq->transId2;
|
regApiPtr->transid[1] = tcIndxReq->transId2;
|
||||||
}//if
|
}//if
|
||||||
|
|
||||||
|
if (getNodeState().startLevel == NodeState::SL_SINGLEUSER &&
|
||||||
|
getNodeState().getSingleUserApi() !=
|
||||||
|
refToNode(regApiPtr->ndbapiBlockref))
|
||||||
|
{
|
||||||
|
terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
|
||||||
|
regApiPtr->m_exec_flag |= TcKeyReq::getExecuteFlag(tcIndxRequestInfo);
|
||||||
|
apiConnectptr = transPtr;
|
||||||
|
abortErrorLab(signal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ERROR_INSERTED(8036) || !seizeIndexOperation(regApiPtr, indexOpPtr)) {
|
if (ERROR_INSERTED(8036) || !seizeIndexOperation(regApiPtr, indexOpPtr)) {
|
||||||
jam();
|
jam();
|
||||||
// Failed to allocate index operation
|
// Failed to allocate index operation
|
||||||
|
|
|
@ -405,7 +405,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
|
||||||
|
|
||||||
node.m_state = apiRegConf->nodeState;
|
node.m_state = apiRegConf->nodeState;
|
||||||
if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED ||
|
if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED ||
|
||||||
node.m_state.startLevel == NodeState::SL_SINGLEUSER)){
|
node.m_state.getSingleUserMode())){
|
||||||
set_node_alive(node, true);
|
set_node_alive(node, true);
|
||||||
} else {
|
} else {
|
||||||
set_node_alive(node, false);
|
set_node_alive(node, false);
|
||||||
|
|
|
@ -56,6 +56,8 @@ NdbTransaction* Ndb::doConnect(Uint32 tConNode)
|
||||||
// We have connections now to the desired node. Return
|
// We have connections now to the desired node. Return
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
DBUG_RETURN(getConnectedNdbTransaction(tConNode));
|
DBUG_RETURN(getConnectedNdbTransaction(tConNode));
|
||||||
|
} else if (TretCode < 0) {
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
} else if (TretCode != 0) {
|
} else if (TretCode != 0) {
|
||||||
tAnyAlive = 1;
|
tAnyAlive = 1;
|
||||||
}//if
|
}//if
|
||||||
|
@ -79,6 +81,8 @@ NdbTransaction* Ndb::doConnect(Uint32 tConNode)
|
||||||
// We have connections now to the desired node. Return
|
// We have connections now to the desired node. Return
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
DBUG_RETURN(getConnectedNdbTransaction(tNode));
|
DBUG_RETURN(getConnectedNdbTransaction(tNode));
|
||||||
|
} else if (TretCode < 0) {
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
} else if (TretCode != 0) {
|
} else if (TretCode != 0) {
|
||||||
tAnyAlive= 1;
|
tAnyAlive= 1;
|
||||||
}//if
|
}//if
|
||||||
|
@ -107,6 +111,8 @@ NdbTransaction* Ndb::doConnect(Uint32 tConNode)
|
||||||
// We have connections now to the desired node. Return
|
// We have connections now to the desired node. Return
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
DBUG_RETURN(getConnectedNdbTransaction(tNode));
|
DBUG_RETURN(getConnectedNdbTransaction(tNode));
|
||||||
|
} else if (TretCode < 0) {
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
} else if (TretCode != 0) {
|
} else if (TretCode != 0) {
|
||||||
tAnyAlive= 1;
|
tAnyAlive= 1;
|
||||||
}//if
|
}//if
|
||||||
|
@ -207,6 +213,11 @@ Ndb::NDB_connect(Uint32 tNode)
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("unsuccessful connect tReturnCode %d, tNdbCon->Status() %d",
|
("unsuccessful connect tReturnCode %d, tNdbCon->Status() %d",
|
||||||
tReturnCode, tNdbCon->Status()));
|
tReturnCode, tNdbCon->Status()));
|
||||||
|
if (theError.code == 299)
|
||||||
|
{
|
||||||
|
// single user mode so no need to retry with other node
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
DBUG_RETURN(3);
|
DBUG_RETURN(3);
|
||||||
}//if
|
}//if
|
||||||
}//Ndb::NDB_connect()
|
}//Ndb::NDB_connect()
|
||||||
|
|
|
@ -315,7 +315,8 @@ inline
|
||||||
bool
|
bool
|
||||||
TransporterFacade::get_node_stopping(NodeId n) const {
|
TransporterFacade::get_node_stopping(NodeId n) const {
|
||||||
const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
|
const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
|
||||||
return ((node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
|
return (!node.m_state.getSingleUserMode() &&
|
||||||
|
(node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
|
||||||
(node.m_state.startLevel == NodeState::SL_STOPPING_2));
|
(node.m_state.startLevel == NodeState::SL_STOPPING_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,16 +327,9 @@ TransporterFacade::getIsNodeSendable(NodeId n) const {
|
||||||
const Uint32 startLevel = node.m_state.startLevel;
|
const Uint32 startLevel = node.m_state.startLevel;
|
||||||
|
|
||||||
if (node.m_info.m_type == NodeInfo::DB) {
|
if (node.m_info.m_type == NodeInfo::DB) {
|
||||||
if(node.m_state.singleUserMode &&
|
|
||||||
ownId() == node.m_state.singleUserApi) {
|
|
||||||
return (node.compatible &&
|
|
||||||
(node.m_state.startLevel == NodeState::SL_STOPPING_1 ||
|
|
||||||
node.m_state.startLevel == NodeState::SL_STARTED ||
|
|
||||||
node.m_state.startLevel == NodeState::SL_SINGLEUSER));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return node.compatible && (startLevel == NodeState::SL_STARTED ||
|
return node.compatible && (startLevel == NodeState::SL_STARTED ||
|
||||||
startLevel == NodeState::SL_STOPPING_1);
|
startLevel == NodeState::SL_STOPPING_1 ||
|
||||||
|
node.m_state.getSingleUserMode());
|
||||||
} else if (node.m_info.m_type == NodeInfo::REP) {
|
} else if (node.m_info.m_type == NodeInfo::REP) {
|
||||||
/**
|
/**
|
||||||
* @todo Check that REP node actually has received API_REG_REQ
|
* @todo Check that REP node actually has received API_REG_REQ
|
||||||
|
|
Loading…
Reference in a new issue