Commit aaeb2b38 authored by unknown's avatar unknown

Merge mysql.com:/home/stewart/Documents/MySQL/4.1/main

into  mysql.com:/home/stewart/Documents/MySQL/5.0/main


ndb/src/kernel/blocks/qmgr/QmgrMain.cpp:
  Auto merged
ndb/src/mgmclient/CommandInterpreter.cpp:
  Auto merged
ndb/src/mgmsrv/MgmtSrvr.hpp:
  Auto merged
ndb/src/mgmsrv/Services.cpp:
  Auto merged
ndb/src/mgmsrv/Services.hpp:
  Auto merged
ndb/include/kernel/signaldata/EventReport.hpp:
  merge
ndb/src/common/debugger/EventLogger.cpp:
  merge
ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
  merge
ndb/src/mgmsrv/MgmtSrvr.cpp:
  merge
parents d5c647f2 80b98425
...@@ -553,7 +553,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; ...@@ -553,7 +553,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_STATISTICS_CONF 454 #define GSN_STATISTICS_CONF 454
#define GSN_START_ORD 455 #define GSN_START_ORD 455
/* 456 unused */
/* 457 unused */ /* 457 unused */
#define GSN_EVENT_SUBSCRIBE_REQ 458 #define GSN_EVENT_SUBSCRIBE_REQ 458
...@@ -835,14 +834,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; ...@@ -835,14 +834,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
/* Start Global Replication */ /* Start Global Replication */
#define GSN_GREP_REQ 656 #define GSN_GREP_REQ 656
/**
* Management server
*/
#define GSN_MGM_LOCK_CONFIG_REQ 657
#define GSN_MGM_LOCK_CONFIG_REP 658
#define GSN_MGM_UNLOCK_CONFIG_REQ 659
#define GSN_MGM_UNLOCK_CONFIG_REP 660
#define GSN_UTIL_CREATE_LOCK_REQ 132 #define GSN_UTIL_CREATE_LOCK_REQ 132
#define GSN_UTIL_CREATE_LOCK_REF 133 #define GSN_UTIL_CREATE_LOCK_REF 133
#define GSN_UTIL_CREATE_LOCK_CONF 188 #define GSN_UTIL_CREATE_LOCK_CONF 188
...@@ -900,6 +891,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; ...@@ -900,6 +891,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_RESUME_REQ 682 #define GSN_RESUME_REQ 682
#define GSN_STOP_REQ 443 #define GSN_STOP_REQ 443
#define GSN_STOP_REF 444 #define GSN_STOP_REF 444
#define GSN_STOP_CONF 456
#define GSN_API_VERSION_REQ 697 #define GSN_API_VERSION_REQ 697
#define GSN_API_VERSION_CONF 698 #define GSN_API_VERSION_CONF 698
......
...@@ -49,12 +49,11 @@ class ApiVersionConf { ...@@ -49,12 +49,11 @@ class ApiVersionConf {
*/ */
friend class MgmtSrv; friend class MgmtSrv;
public: public:
STATIC_CONST( SignalLength = 3 ); STATIC_CONST( SignalLength = 4 );
Uint32 senderRef; Uint32 senderRef;
Uint32 nodeId; //api node id Uint32 nodeId; //api node id
Uint32 version; // Version of API node Uint32 version; // Version of API node
Uint32 inet_addr;
}; };
#endif #endif
...@@ -67,6 +67,13 @@ public: ...@@ -67,6 +67,13 @@ public:
static bool getStopAbort(const Uint32 & requestInfo); static bool getStopAbort(const Uint32 & requestInfo);
}; };
struct StopConf
{
STATIC_CONST( SignalLength = 2 );
Uint32 senderData;
Uint32 nodeState;
};
class StopRef class StopRef
{ {
/** /**
...@@ -86,7 +93,8 @@ public: ...@@ -86,7 +93,8 @@ public:
OK = 0, OK = 0,
NodeShutdownInProgress = 1, NodeShutdownInProgress = 1,
SystemShutdownInProgress = 2, SystemShutdownInProgress = 2,
NodeShutdownWouldCauseSystemCrash = 3 NodeShutdownWouldCauseSystemCrash = 3,
TransactionAbortFailed = 4
}; };
public: public:
......
...@@ -1962,6 +1962,11 @@ Ndbcntr::execRESUME_REQ(Signal* signal){ ...@@ -1962,6 +1962,11 @@ Ndbcntr::execRESUME_REQ(Signal* signal){
//ResumeRef * const ref = (ResumeRef *)&signal->theData[0]; //ResumeRef * const ref = (ResumeRef *)&signal->theData[0];
jamEntry(); jamEntry();
signal->theData[0] = EventReport::SingleUser;
signal->theData[1] = 2;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
//Uint32 senderData = req->senderData; //Uint32 senderData = req->senderData;
//BlockReference senderRef = req->senderRef; //BlockReference senderRef = req->senderRef;
NodeState newState(NodeState::SL_STARTED); NodeState newState(NodeState::SL_STARTED);
...@@ -2000,12 +2005,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ ...@@ -2000,12 +2005,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
return; return;
} }
if(c_stopRec.stopReq.senderRef != 0 && !singleuser){ if(c_stopRec.stopReq.senderRef != 0){
jam();
/** /**
* Requested a system shutdown * Requested a system shutdown
*/ */
if(StopReq::getSystemStop(req->requestInfo)){ if(!singleuser && StopReq::getSystemStop(req->requestInfo)){
jam(); jam();
sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100, sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100,
StopReq::SignalLength); StopReq::SignalLength);
...@@ -2027,22 +2031,27 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ ...@@ -2027,22 +2031,27 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
c_stopRec.stopReq = * req; c_stopRec.stopReq = * req;
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond(); c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) && !singleuser) { if(!singleuser) {
if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)) {
jam(); jam();
if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){ if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
((Configuration&)theConfiguration).stopOnError(false); ((Configuration&)theConfiguration).stopOnError(false);
} }
} }
if(!singleuser) {
if(!c_stopRec.checkNodeFail(signal)){ if(!c_stopRec.checkNodeFail(signal)){
jam(); jam();
return; return;
} }
}
signal->theData[0] = NDB_LE_NDBStopStarted; signal->theData[0] = NDB_LE_NDBStopStarted;
signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0; signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
else
{
signal->theData[0] = NDB_LE_SingleUser;
signal->theData[1] = 0;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
NodeState newState(NodeState::SL_STOPPING_1, NodeState newState(NodeState::SL_STOPPING_1,
StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)); StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
...@@ -2125,9 +2134,11 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){ ...@@ -2125,9 +2134,11 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
stopReq.senderRef = 0; stopReq.senderRef = 0;
if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER)
{
NodeState newState(NodeState::SL_STARTED); NodeState newState(NodeState::SL_STARTED);
cntr.updateNodeState(signal, newState); cntr.updateNodeState(signal, newState);
}
signal->theData[0] = NDB_LE_NDBStopAborted; signal->theData[0] = NDB_LE_NDBStopAborted;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB); cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
...@@ -2223,12 +2234,24 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){ ...@@ -2223,12 +2234,24 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
jamEntry(); jamEntry();
if(c_stopRec.stopReq.singleuser) { if(c_stopRec.stopReq.singleuser) {
jam(); jam();
NodeState newState(NodeState::SL_SINGLEUSER); NodeState newState(NodeState::SL_SINGLEUSER);
newState.setSingleUser(true); newState.setSingleUser(true);
newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi); newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
updateNodeState(signal, newState); updateNodeState(signal, newState);
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond(); c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
StopConf * const stopConf = (StopConf *)&signal->theData[0];
stopConf->senderData = c_stopRec.stopReq.senderData;
stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
c_stopRec.stopReq.senderRef = 0; // the command is done
signal->theData[0] = EventReport::SingleUser;
signal->theData[1] = 1;
signal->theData[2] = c_stopRec.stopReq.singleUserApi;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
} }
else else
{ {
...@@ -2246,7 +2269,13 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){ ...@@ -2246,7 +2269,13 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
void Ndbcntr::execABORT_ALL_REF(Signal* signal){ void Ndbcntr::execABORT_ALL_REF(Signal* signal){
jamEntry(); jamEntry();
ndbrequire(false); AbortAllRef *abortAllRef = (AbortAllRef *)&signal->theData[0];
AbortAllRef::ErrorCode errorCode = (AbortAllRef::ErrorCode) abortAllRef->errorCode;
StopRef * const stopRef = (StopRef *)&signal->theData[0];
stopRef->senderData = c_stopRec.stopReq.senderData;
stopRef->errorCode = StopRef::TransactionAbortFailed;
sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
} }
void void
......
...@@ -2013,6 +2013,8 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) { ...@@ -2013,6 +2013,8 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) {
else else
conf->version = 0; conf->version = 0;
conf->nodeId = nodeId; conf->nodeId = nodeId;
struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
conf->inet_addr= in.s_addr;
sendSignal(senderRef, sendSignal(senderRef,
GSN_API_VERSION_CONF, GSN_API_VERSION_CONF,
......
...@@ -1443,9 +1443,8 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) ...@@ -1443,9 +1443,8 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
ndbout_c("Entering single user mode for node %d failed", nodeId); ndbout_c("Entering single user mode for node %d failed", nodeId);
printError(); printError();
} else { } else {
ndbout_c("Entering single user mode"); ndbout_c("Single user mode entered");
ndbout_c("Access will be granted for API node %d only.", nodeId); ndbout_c("Access is granted for API node %d only.", nodeId);
ndbout_c("Use ALL STATUS to see when single user mode has been entered.");
} }
} }
...@@ -1458,7 +1457,7 @@ CommandInterpreter::executeExitSingleUser(char* parameters) ...@@ -1458,7 +1457,7 @@ CommandInterpreter::executeExitSingleUser(char* parameters)
printError(); printError();
} else { } else {
ndbout_c("Exiting single user mode in progress."); ndbout_c("Exiting single user mode in progress.");
ndbout_c("Use ALL STATUS to see when single user mode has been exited."); ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited.");
} }
} }
......
...@@ -179,90 +179,3 @@ void Config::printConfigFile(NdbOut &out) const { ...@@ -179,90 +179,3 @@ void Config::printConfigFile(NdbOut &out) const {
} }
#endif #endif
} }
Uint32
Config::getGenerationNumber() const {
#if 0
Uint32 ret;
const Properties *prop = NULL;
get("SYSTEM", &prop);
if(prop != NULL)
if(prop->get("ConfigGenerationNumber", &ret))
return ret;
return 0;
#else
return 0;
#endif
}
int
Config::setGenerationNumber(Uint32 gen) {
#if 0
Properties *prop = NULL;
getCopy("SYSTEM", &prop);
if(prop != NULL) {
MGM_REQUIRE(prop->put("ConfigGenerationNumber", gen, true));
MGM_REQUIRE(put("SYSTEM", prop, true));
return 0;
}
return -1;
#else
return -1;
#endif
}
bool
Config::change(const BaseString &section,
const BaseString &param,
const BaseString &value) {
#if 0
const char *name;
Properties::Iterator it(this);
for(name = it.first(); name != NULL; name = it.next()) {
Properties *prop = NULL;
if(strcasecmp(section.c_str(), name) == 0) {
getCopy(name, &prop);
if(prop == NULL) /* doesn't exist */
return false;
if(value == "") {
prop->remove(param.c_str());
put(section.c_str(), prop, true);
} else {
PropertiesType t;
if(!prop->getTypeOf(param.c_str(), &t)) /* doesn't exist */
return false;
switch(t) {
case PropertiesType_Uint32:
long val;
char *ep;
errno = 0;
val = strtol(value.c_str(), &ep, 0);
if(value.length() == 0 || *ep != '\0') /* not a number */
return false;
if(errno == ERANGE)
return false;
prop->put(param.c_str(), (unsigned int)val, true);
put(section.c_str(), prop, true);
break;
case PropertiesType_char:
prop->put(param.c_str(), value.c_str(), true);
put(section.c_str(), prop, true);
break;
default:
return false;
}
}
break;
}
}
return true;
#else
return false;
#endif
}
...@@ -60,16 +60,6 @@ public: ...@@ -60,16 +60,6 @@ public:
printConfigFile(ndb); printConfigFile(ndb);
} }
Uint32 getGenerationNumber() const;
int setGenerationNumber(Uint32);
/** Change configuration
*/
bool change(const BaseString &section,
const BaseString &param,
const BaseString &value);
/** /**
* Info * Info
*/ */
......
...@@ -67,6 +67,16 @@ ...@@ -67,6 +67,16 @@
#define DEBUG(x) #define DEBUG(x)
#endif #endif
#define INIT_SIGNAL_SENDER(ss,nodeId) \
SignalSender ss(theFacade); \
ss.lock(); /* lock will be released on exit */ \
{\
int result = okToSendTo(nodeId, true);\
if (result != 0) {\
return result;\
}\
}
extern int global_flag_send_heartbeat_now; extern int global_flag_send_heartbeat_now;
extern int g_no_nodeid_checks; extern int g_no_nodeid_checks;
extern my_bool opt_core; extern my_bool opt_core;
...@@ -90,55 +100,6 @@ MgmtSrvr::logLevelThread_C(void* m) ...@@ -90,55 +100,6 @@ MgmtSrvr::logLevelThread_C(void* m)
return 0; return 0;
} }
void *
MgmtSrvr::signalRecvThread_C(void *m)
{
MgmtSrvr *mgm = (MgmtSrvr*)m;
mgm->signalRecvThreadRun();
return 0;
}
class SigMatch
{
public:
int gsn;
void (MgmtSrvr::* function)(NdbApiSignal *signal);
SigMatch() { gsn = 0; function = NULL; };
SigMatch(int _gsn,
void (MgmtSrvr::* _function)(NdbApiSignal *signal)) {
gsn = _gsn;
function = _function;
};
bool check(NdbApiSignal *signal) {
if(signal->readSignalNumber() == gsn)
return true;
return false;
};
};
void
MgmtSrvr::signalRecvThreadRun()
{
Vector<SigMatch> siglist;
siglist.push_back(SigMatch(GSN_MGM_LOCK_CONFIG_REQ,
&MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ));
siglist.push_back(SigMatch(GSN_MGM_UNLOCK_CONFIG_REQ,
&MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ));
while(!_isStopThread) {
SigMatch *handler = NULL;
NdbApiSignal *signal = NULL;
if(m_signalRecvQueue.waitFor(siglist, &handler, &signal, DEFAULT_TIMEOUT)) {
if(handler->function != 0)
(this->*handler->function)(signal);
}
}
}
extern EventLogger g_eventLogger; extern EventLogger g_eventLogger;
static NdbOut& static NdbOut&
...@@ -426,7 +387,6 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, ...@@ -426,7 +387,6 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_isStopThread = false; _isStopThread = false;
_logLevelThread = NULL; _logLevelThread = NULL;
_logLevelThreadSleep = 500; _logLevelThreadSleep = 500;
m_signalRecvThread = NULL;
theFacade = 0; theFacade = 0;
...@@ -654,12 +614,6 @@ MgmtSrvr::start(BaseString &error_string) ...@@ -654,12 +614,6 @@ MgmtSrvr::start(BaseString &error_string)
"MgmtSrvr_Loglevel", "MgmtSrvr_Loglevel",
NDB_THREAD_PRIO_LOW); NDB_THREAD_PRIO_LOW);
m_signalRecvThread = NdbThread_Create(signalRecvThread_C,
(void **)this,
32768,
"MgmtSrvr_Service",
NDB_THREAD_PRIO_LOW);
DBUG_RETURN(true); DBUG_RETURN(true);
} }
...@@ -668,10 +622,6 @@ MgmtSrvr::start(BaseString &error_string) ...@@ -668,10 +622,6 @@ MgmtSrvr::start(BaseString &error_string)
//**************************************************************************** //****************************************************************************
MgmtSrvr::~MgmtSrvr() MgmtSrvr::~MgmtSrvr()
{ {
while (theSignalIdleList != NULL) {
freeSignal();
}
if(theFacade != 0){ if(theFacade != 0){
theFacade->stop_instance(); theFacade->stop_instance();
delete theFacade; delete theFacade;
...@@ -699,10 +649,6 @@ MgmtSrvr::~MgmtSrvr() ...@@ -699,10 +649,6 @@ MgmtSrvr::~MgmtSrvr()
NdbThread_Destroy(&_logLevelThread); NdbThread_Destroy(&_logLevelThread);
} }
if (m_signalRecvThread != NULL) {
NdbThread_WaitFor(m_signalRecvThread, &res);
NdbThread_Destroy(&m_signalRecvThread);
}
if (m_config_retriever) if (m_config_retriever)
delete m_config_retriever; delete m_config_retriever;
} }
...@@ -710,21 +656,21 @@ MgmtSrvr::~MgmtSrvr() ...@@ -710,21 +656,21 @@ MgmtSrvr::~MgmtSrvr()
//**************************************************************************** //****************************************************************************
//**************************************************************************** //****************************************************************************
int MgmtSrvr::okToSendTo(NodeId processId, bool unCond) int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
{ {
if(processId == 0) if(nodeId == 0)
return 0; return 0;
if (getNodeType(processId) != NDB_MGM_NODE_TYPE_NDB) if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
return WRONG_PROCESS_TYPE; return WRONG_PROCESS_TYPE;
// Check if we have contact with it // Check if we have contact with it
if(unCond){ if(unCond){
if(theFacade->theClusterMgr->getNodeInfo(processId).connected) if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected)
return 0; return 0;
return NO_CONTACT_WITH_PROCESS; return NO_CONTACT_WITH_PROCESS;
} }
if (theFacade->get_node_alive(processId) == 0) { if (theFacade->get_node_alive(nodeId) == 0) {
return NO_CONTACT_WITH_PROCESS; return NO_CONTACT_WITH_PROCESS;
} else { } else {
return 0; return 0;
...@@ -745,259 +691,16 @@ void report_unknown_signal(SimpleSignal *signal) ...@@ -745,259 +691,16 @@ void report_unknown_signal(SimpleSignal *signal)
****************************************************************************/ ****************************************************************************/
int int
MgmtSrvr::start(int processId) MgmtSrvr::start(int nodeId)
{ {
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
StartOrd* const startOrd = CAST_PTR(StartOrd, signal->getDataPtrSend());
signal->set(TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
SimpleSignal ssig;
StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
startOrd->restartInfo = 0; startOrd->restartInfo = 0;
result = sendSignal(processId, NO_WAIT, signal, true); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
}
/**
* Restart one database node
*/
int
MgmtSrvr::restartNode(int processId, bool nostart,
bool initalStart, bool abort,
StopCallback callback, void * anyData)
{
int result;
if(m_stopRec.singleUserMode)
return 5060;
if(m_stopRec.inUse){
return 5029;
}
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
stopReq->requestInfo = 0;
StopReq::setSystemStop(stopReq->requestInfo, false);
StopReq::setPerformRestart(stopReq->requestInfo, true);
StopReq::setNoStart(stopReq->requestInfo, nostart);
StopReq::setInitialStart(stopReq->requestInfo, initalStart);
StopReq::setStopAbort(stopReq->requestInfo, abort);
stopReq->singleuser = 0;
stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000;
stopReq->senderData = 12;
stopReq->senderRef = _ownReference;
m_stopRec.singleUserMode = false;
m_stopRec.sentCount = 1;
m_stopRec.reply = 0;
m_stopRec.nodeId = processId;
m_stopRec.anyData = anyData;
m_stopRec.callback = callback;
m_stopRec.inUse = true;
if(callback == NULL){
Uint32 timeOut = 0;
timeOut += stopReq->apiTimeout;
timeOut += stopReq->transactionTimeout;
timeOut += stopReq->readOperationTimeout;
timeOut += stopReq->operationTimeout;
timeOut *= 3;
result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
} else {
result = sendSignal(processId, NO_WAIT, signal, true);
}
if (result == -1 && theWaitState != WAIT_NODEFAILURE) {
m_stopRec.inUse = false;
return SEND_OR_RECEIVE_FAILED;
}
if(callback == 0){
m_stopRec.inUse = false;
return m_stopRec.reply;
} else {
return 0;
}
}
/**
* Restart all database nodes
*/
int
MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
int * stopCount, StopCallback callback, void * anyData)
{
if(m_stopRec.singleUserMode)
return 5060;
if(m_stopRec.inUse){
return 5029;
}
m_stopRec.singleUserMode = false;
m_stopRec.sentCount = 0;
m_stopRec.reply = 0;
m_stopRec.nodeId = 0;
m_stopRec.anyData = anyData;
m_stopRec.callback = callback;
m_stopRec.inUse = true;
/**
* Restart all database nodes into idle ("no-started") state
*/
Uint32 timeOut = 0;
NodeId nodeId = 0;
NodeBitmask nodes;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(okToSendTo(nodeId, true) == 0){
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
StopReq::SignalLength);
stopReq->requestInfo = 0;
stopReq->singleuser = 0;
StopReq::setSystemStop(stopReq->requestInfo, true);
StopReq::setPerformRestart(stopReq->requestInfo, true);
if (callback == 0) {
// Start node in idle ("no-started") state
StopReq::setNoStart(stopReq->requestInfo, 1);
} else {
StopReq::setNoStart(stopReq->requestInfo, nostart);
}
StopReq::setInitialStart(stopReq->requestInfo, initalStart);
StopReq::setStopAbort(stopReq->requestInfo, abort);
stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000;
stopReq->senderData = 12;
stopReq->senderRef = _ownReference;
timeOut += stopReq->apiTimeout;
timeOut += stopReq->transactionTimeout;
timeOut += stopReq->readOperationTimeout;
timeOut += stopReq->operationTimeout;
timeOut *= 3;
m_stopRec.sentCount++;
int res;
if(callback == 0){
res = sendSignal(nodeId, WAIT_STOP, signal, true);
} else {
res = sendSignal(nodeId, NO_WAIT, signal, true);
}
if(res != -1){
nodes.set(nodeId);
}
}
}
if(stopCount != 0){
* stopCount = m_stopRec.sentCount;
}
if(m_stopRec.sentCount == 0){
m_stopRec.inUse = false;
return 0;
}
if(callback != 0){
return 0;
}
theFacade->lock_mutex();
int waitTime = timeOut/m_stopRec.sentCount;
if (receiveOptimisedResponse(waitTime) != 0) {
m_stopRec.inUse = false;
return -1;
}
/**
* Here all nodes were correctly stopped,
* so we wait for all nodes to be contactable
*/
nodeId = 0;
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
enum ndb_mgm_node_status s;
s = NDB_MGM_NODE_STATUS_NO_CONTACT;
while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
Uint32 connectCount = 0;
bool system;
status(nodeId, &s, &version, &startPhase,
&system, &dynamicId, &nodeGroup, &connectCount);
NdbSleep_MilliSleep(100);
waitTime = (maxTime - NdbTick_CurrentMillisecond());
}
}
if(nostart){
m_stopRec.inUse = false;
return 0;
}
/**
* Now we start all database nodes (i.e. we make them non-idle)
* We ignore the result we get from the start command.
*/
nodeId = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
int result;
result = start(nodeId);
DEBUG("Starting node " << nodeId << " with result " << result);
/**
* Errors from this call are deliberately ignored.
* Maybe the user only wanted to restart a subset of the nodes.
* It is also easy for the user to check which nodes have
* started and which nodes have not.
*
* if (result != 0) {
* m_stopRec.inUse = false;
* return result;
* }
*/
}
m_stopRec.inUse = false;
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -1005,438 +708,482 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort, ...@@ -1005,438 +708,482 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
*****************************************************************************/ *****************************************************************************/
int int
MgmtSrvr::versionNode(int processId, bool abort, MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
VersionCallback callback, void * anyData)
{ {
int version; version= 0;
if (getOwnNodeId() == nodeId)
if(m_versionRec.inUse)
return OPERATION_IN_PROGRESS;
m_versionRec.callback = callback;
m_versionRec.inUse = true ;
if (getOwnNodeId() == processId)
{ {
/**
* If we're inquiring about our own node id,
* We know what version we are (version implies connected for mgm)
* but would like to find out from elsewhere what address they're using
* to connect to us. This means that secondary mgm servers
* can list ip addresses for mgm servers.
*
* If we don't get an address (i.e. no db nodes),
* we get the address from the configuration.
*/
sendVersionReq(nodeId, version, address);
version= NDB_VERSION; version= NDB_VERSION;
if(!*address)
{
ndb_mgm_configuration_iterator
iter(*_config->m_configValues, CFG_SECTION_NODE);
unsigned tmp= 0;
for(iter.first();iter.valid();iter.next())
{
if(iter.get(CFG_NODE_ID, &tmp)) require(false);
if((unsigned)nodeId!=tmp)
continue;
if(iter.get(CFG_NODE_HOST, address)) require(false);
break;
}
}
} }
else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
{ {
ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(processId); ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
if(node.connected) if(node.connected)
version= node.m_info.m_version; version= node.m_info.m_version;
else *address= get_connect_address(nodeId);
version= 0;
} }
else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API || else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
{ {
return sendVersionReq(processId); return sendVersionReq(nodeId, version, address);
} }
else
version= 0;
if(m_versionRec.callback != 0)
m_versionRec.callback(processId, version, this,0);
m_versionRec.inUse = false ;
m_versionRec.version[processId]= version;
return 0; return 0;
} }
int int
MgmtSrvr::sendVersionReq(int processId) MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
{ {
Uint32 ndbnode=0; SignalSender ss(theFacade);
int result; ss.lock();
for(Uint32 i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
if(okToSendTo(i, true) == 0)
{
ndbnode = i;
break;
}
}
}
if (ndbnode == 0) {
m_versionRec.inUse = false;
if(m_versionRec.callback != 0)
m_versionRec.callback(processId, 0, this,0);
return NO_CONTACT_WITH_CLUSTER;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
m_versionRec.inUse = false;
if(m_versionRec.callback != 0)
m_versionRec.callback(processId, 0, this,0);
return COULD_NOT_ALLOCATE_MEMORY;
}
ApiVersionReq* req = CAST_PTR(ApiVersionReq, signal->getDataPtrSend());
req->senderRef = _ownReference;
req->nodeId = processId;
signal->set(TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ, SimpleSignal ssig;
ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
req->senderRef = ss.getOwnRef();
req->nodeId = v_nodeId;
ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
ApiVersionReq::SignalLength); ApiVersionReq::SignalLength);
int do_send = 1;
NodeId nodeId;
// if(m_versionRec.callback == 0){ while (1)
Uint32 timeOut = 0; {
timeOut = 10000; if (do_send)
result = sendRecSignal(ndbnode, WAIT_VERSION, signal, true, timeOut); {
//} else { bool next;
//result = sendSignal(processId, NO_WAIT, signal, true); nodeId = 0;
// }
if (result == -1) {
m_versionRec.inUse = false;
if(m_versionRec.callback != 0)
m_versionRec.callback(processId, 0, this,0);
m_versionRec.version[processId] = 0;
return SEND_OR_RECEIVE_FAILED;
}
m_versionRec.inUse = false; while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
return 0; okToSendTo(nodeId, true) != 0);
}
int const ClusterMgr::Node &node=
MgmtSrvr::version(int * stopCount, bool abort, theFacade->theClusterMgr->getNodeInfo(nodeId);
VersionCallback callback, void * anyData) if(next && node.m_state.startLevel != NodeState::SL_STARTED)
{ {
ClusterMgr::Node node; NodeId tmp=nodeId;
int version; while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
okToSendTo(nodeId, true) != 0);
if(!next)
nodeId= tmp;
}
if(m_versionRec.inUse) if(!next) return NO_CONTACT_WITH_DB_NODES;
return 1;
m_versionRec.callback = callback; if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
m_versionRec.inUse = true ; return SEND_OR_RECEIVE_FAILED;
Uint32 i;
for(i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) {
m_versionRec.callback(i, NDB_VERSION, this,0);
} }
do_send = 0;
} }
for(i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
node = theFacade->theClusterMgr->getNodeInfo(i);
version = node.m_info.m_version;
if(theFacade->theClusterMgr->getNodeInfo(i).connected)
m_versionRec.callback(i, version, this,0);
else
m_versionRec.callback(i, 0, this,0);
SimpleSignal *signal = ss.waitFor();
int gsn = signal->readSignalNumber();
switch (gsn) {
case GSN_API_VERSION_CONF: {
const ApiVersionConf * const conf =
CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
assert(conf->nodeId == v_nodeId);
version = conf->version;
struct in_addr in;
in.s_addr= conf->inet_addr;
*address= inet_ntoa(in);
return 0;
} }
case GSN_NF_COMPLETEREP:{
const NFCompleteRep * const rep =
CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
if (rep->failedNodeId == nodeId)
do_send = 1; // retry with other node
continue;
} }
for(i = 0; i<MAX_NODES; i++) { case GSN_NODE_FAILREP:{
if (getNodeType(i) == NDB_MGM_NODE_TYPE_API) { const NodeFailRep * const rep =
return sendVersionReq(i); CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
if (NodeBitmask::get(rep->theNodes,nodeId))
do_send = 1; // retry with other node
continue;
} }
default:
report_unknown_signal(signal);
return SEND_OR_RECEIVE_FAILED;
} }
break;
} // while(1)
return 0; return 0;
} }
int /*
MgmtSrvr::stopNode(int processId, bool abort, StopCallback callback, * Common method for handeling all STOP_REQ signalling that
void * anyData) * is used by Stopping, Restarting and Single user commands
*/
int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
NodeBitmask &stoppedNodes,
Uint32 singleUserNodeId,
bool abort,
bool stop,
bool restart,
bool nostart,
bool initialStart)
{ {
if(m_stopRec.singleUserMode) stoppedNodes.clear();
return 5060;
if(m_stopRec.inUse)
return 5029;
int result;
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal(); SignalSender ss(theFacade);
if (signal == NULL) { ss.lock(); // lock will be released on exit
return COULD_NOT_ALLOCATE_MEMORY;
}
StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); SimpleSignal ssig;
signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength); StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
stopReq->requestInfo = 0; stopReq->requestInfo = 0;
stopReq->singleuser = 0;
StopReq::setPerformRestart(stopReq->requestInfo, false);
StopReq::setSystemStop(stopReq->requestInfo, false);
StopReq::setStopAbort(stopReq->requestInfo, abort);
stopReq->apiTimeout = 5000; stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000; stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000; stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000; stopReq->operationTimeout = 1000;
stopReq->senderData = 12; stopReq->senderData = 12;
stopReq->senderRef = _ownReference; stopReq->senderRef = ss.getOwnRef();
if (singleUserNodeId)
m_stopRec.sentCount = 1; {
m_stopRec.reply = 0; stopReq->singleuser = 1;
m_stopRec.nodeId = processId; stopReq->singleUserApi = singleUserNodeId;
m_stopRec.anyData = anyData; StopReq::setSystemStop(stopReq->requestInfo, false);
m_stopRec.callback = callback; StopReq::setPerformRestart(stopReq->requestInfo, false);
m_stopRec.inUse = true; StopReq::setStopAbort(stopReq->requestInfo, false);
if(callback == NULL){
Uint32 timeOut = 0;
timeOut += stopReq->apiTimeout;
timeOut += stopReq->transactionTimeout;
timeOut += stopReq->readOperationTimeout;
timeOut += stopReq->operationTimeout;
timeOut *= 3;
result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
} else {
result = sendSignal(processId, NO_WAIT, signal, true);
} }
else
if (result == -1) { {
m_stopRec.inUse = false; stopReq->singleuser = 0;
return SEND_OR_RECEIVE_FAILED; StopReq::setSystemStop(stopReq->requestInfo, stop);
StopReq::setPerformRestart(stopReq->requestInfo, restart);
StopReq::setStopAbort(stopReq->requestInfo, abort);
StopReq::setNoStart(stopReq->requestInfo, nostart);
StopReq::setInitialStart(stopReq->requestInfo, initialStart);
} }
if(callback == 0){ // send the signals
m_stopRec.inUse = false; NodeBitmask nodes;
return m_stopRec.reply; if (nodeId)
} else { {
return 0; {
int r;
if((r = okToSendTo(nodeId, true)) != 0)
return r;
} }
} {
if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
int return SEND_OR_RECEIVE_FAILED;
MgmtSrvr::stop(int * stopCount, bool abort, StopCallback callback,
void * anyData)
{
if(m_stopRec.singleUserMode)
return 5060;
if(m_stopRec.inUse){
return 5029;
} }
nodes.set(nodeId);
m_stopRec.singleUserMode = false;
m_stopRec.sentCount = 0;
m_stopRec.reply = 0;
m_stopRec.nodeId = 0;
m_stopRec.anyData = anyData;
m_stopRec.callback = callback;
m_stopRec.inUse = true;
NodeId nodeId = 0;
Uint32 timeOut = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(okToSendTo(nodeId, true) == 0){
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
} }
StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
StopReq::SignalLength);
stopReq->requestInfo = 0;
stopReq->singleuser = 0;
StopReq::setSystemStop(stopReq->requestInfo, true);
StopReq::setPerformRestart(stopReq->requestInfo, false);
StopReq::setStopAbort(stopReq->requestInfo, abort);
stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000;
stopReq->senderData = 12;
stopReq->senderRef = _ownReference;
timeOut += stopReq->apiTimeout;
timeOut += stopReq->transactionTimeout;
timeOut += stopReq->readOperationTimeout;
timeOut += stopReq->operationTimeout;
timeOut *= 3;
m_stopRec.sentCount++;
if(callback == 0)
sendSignal(nodeId, WAIT_STOP, signal, true);
else else
sendSignal(nodeId, NO_WAIT, signal, true); while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
{
if(okToSendTo(nodeId, true) == 0)
{
SendStatus result = ss.sendSignal(nodeId, &ssig);
if (result == SEND_OK)
nodes.set(nodeId);
} }
} }
if(stopCount != 0) // now wait for the replies
* stopCount = m_stopRec.sentCount; int error = 0;
while (!nodes.isclear())
if(m_stopRec.sentCount > 0){ {
if(callback == 0){ SimpleSignal *signal = ss.waitFor();
theFacade->lock_mutex(); int gsn = signal->readSignalNumber();
receiveOptimisedResponse(timeOut / m_stopRec.sentCount); switch (gsn) {
} else { case GSN_STOP_REF:{
return 0; const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
#ifdef VM_TRACE
ndbout_c("Node %d refused stop", nodeId);
#endif
assert(nodes.get(nodeId));
nodes.clear(nodeId);
error = translateStopRef(ref->errorCode);
break;
} }
case GSN_STOP_CONF:{
const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
#ifdef VM_TRACE
ndbout_c("Node %d single user mode", nodeId);
#endif
assert(nodes.get(nodeId));
assert(singleUserNodeId != 0);
nodes.clear(nodeId);
stoppedNodes.set(nodeId);
break;
} }
case GSN_NF_COMPLETEREP:{
m_stopRec.inUse = false; const NFCompleteRep * const rep =
return m_stopRec.reply; CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
#ifdef VM_TRACE
ndbout_c("Node %d fail completed", rep->failedNodeId);
#endif
break;
}
case GSN_NODE_FAILREP:{
const NodeFailRep * const rep =
CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
NodeBitmask failedNodes;
failedNodes.assign(NodeBitmask::Size, rep->theNodes);
#ifdef VM_TRACE
{
ndbout << "Failed nodes:";
for (unsigned i = 0; i < 32*NodeBitmask::Size; i++)
if(failedNodes.get(i))
ndbout << " " << i;
ndbout << endl;
}
#endif
failedNodes.bitAND(nodes);
if (!failedNodes.isclear())
{
nodes.bitANDC(failedNodes); // clear the failed nodes
if (singleUserNodeId == 0)
stoppedNodes.bitOR(failedNodes);
}
break;
}
default:
report_unknown_signal(signal);
#ifdef VM_TRACE
ndbout_c("Unknown signal %d", gsn);
#endif
return SEND_OR_RECEIVE_FAILED;
}
}
return error;
} }
/***************************************************************************** /*
* Single user mode * Stop one node
****************************************************************************/ */
int int MgmtSrvr::stopNode(int nodeId, bool abort)
MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId,
EnterSingleCallback callback, void * anyData)
{ {
if(m_stopRec.singleUserMode) { NodeBitmask nodes;
return 5060; return sendSTOP_REQ(nodeId,
} nodes,
0,
abort,
false,
false,
false,
false);
}
/*
* Perform system shutdown
*/
int MgmtSrvr::stop(int * stopCount, bool abort)
{
NodeBitmask nodes;
int ret = sendSTOP_REQ(0,
nodes,
0,
abort,
true,
false,
false,
false);
if (stopCount)
*stopCount = nodes.count();
return ret;
}
/*
* Enter single user mode on all live nodes
*/
if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) { int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
{
if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API)
return 5062; return 5062;
} NodeId nodeId = 0;
ClusterMgr::Node node; ClusterMgr::Node node;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
for(Uint32 i = 0; i<MAX_NODES; i++) { {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { node = theFacade->theClusterMgr->getNodeInfo(nodeId);
node = theFacade->theClusterMgr->getNodeInfo(i);
if((node.m_state.startLevel != NodeState::SL_STARTED) && if((node.m_state.startLevel != NodeState::SL_STARTED) &&
(node.m_state.startLevel != NodeState::SL_NOTHING)) { (node.m_state.startLevel != NodeState::SL_NOTHING))
return 5063; return 5063;
} }
} NodeBitmask nodes;
} int ret = sendSTOP_REQ(0,
nodes,
singleUserNodeId,
false,
false,
false,
false,
false);
if (stopCount)
*stopCount = nodes.count();
return ret;
}
/*
* Perform node restart
*/
if(m_stopRec.inUse){ int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart,
return 5029; bool abort)
} {
NodeBitmask nodes;
return sendSTOP_REQ(nodeId,
nodes,
0,
abort,
false,
true,
nostart,
initialStart);
}
/*
* Perform system restart
*/
if(singleUserNodeId == 0) int MgmtSrvr::restart(bool nostart, bool initialStart,
return 1; bool abort, int * stopCount )
m_stopRec.singleUserMode = true; {
m_stopRec.sentCount = 0; NodeBitmask nodes;
m_stopRec.reply = 0; int ret = sendSTOP_REQ(0,
m_stopRec.nodeId = 0; nodes,
m_stopRec.anyData = anyData; 0,
m_stopRec.callback = callback; abort,
m_stopRec.inUse = true; true,
true,
true,
initialStart);
NodeId nodeId = 0; if (ret)
Uint32 timeOut = 0; return ret;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(okToSendTo(nodeId, true) == 0){
NdbApiSignal* signal = getSignal(); if (stopCount)
if (signal == NULL) { *stopCount = nodes.count();
return COULD_NOT_ALLOCATE_MEMORY;
}
StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); #ifdef VM_TRACE
signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, ndbout_c("Stopped %d nodes", nodes.count());
StopReq::SignalLength); #endif
/**
* Here all nodes were correctly stopped,
* so we wait for all nodes to be contactable
*/
int waitTime = 12000;
NodeId nodeId = 0;
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
stopReq->requestInfo = 0; ndbout_c(" %d", nodes.get(1));
stopReq->singleuser = 1; ndbout_c(" %d", nodes.get(2));
stopReq->singleUserApi = singleUserNodeId;
StopReq::setSystemStop(stopReq->requestInfo, false);
StopReq::setPerformRestart(stopReq->requestInfo, false);
StopReq::setStopAbort(stopReq->requestInfo, false);
stopReq->apiTimeout = 5000; while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
stopReq->transactionTimeout = 1000; if (!nodes.get(nodeId))
stopReq->readOperationTimeout = 1000; continue;
stopReq->operationTimeout = 1000; enum ndb_mgm_node_status s;
stopReq->senderData = 12; s = NDB_MGM_NODE_STATUS_NO_CONTACT;
stopReq->senderRef = _ownReference; #ifdef VM_TRACE
timeOut += stopReq->apiTimeout; ndbout_c("Waiting for %d not started", nodeId);
timeOut += stopReq->transactionTimeout; #endif
timeOut += stopReq->readOperationTimeout; while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
timeOut += stopReq->operationTimeout; Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
timeOut *= 3; Uint32 connectCount = 0;
bool system;
m_stopRec.sentCount++; const char *address;
if(callback == 0) status(nodeId, &s, &version, &startPhase,
sendSignal(nodeId, WAIT_STOP, signal, true); &system, &dynamicId, &nodeGroup, &connectCount, &address);
else NdbSleep_MilliSleep(100);
sendSignal(nodeId, NO_WAIT, signal, true); waitTime = (maxTime - NdbTick_CurrentMillisecond());
} }
} }
if(stopCount != 0) if(nostart)
* stopCount = m_stopRec.sentCount;
if(callback == 0){
m_stopRec.inUse = false;
return 0;
// return m_stopRec.reply;
} else {
return 0; return 0;
/**
* Now we start all database nodes (i.e. we make them non-idle)
* We ignore the result we get from the start command.
*/
nodeId = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
if (!nodes.get(nodeId))
continue;
int result;
result = start(nodeId);
DEBUG("Starting node " << nodeId << " with result " << result);
/**
* Errors from this call are deliberately ignored.
* Maybe the user only wanted to restart a subset of the nodes.
* It is also easy for the user to check which nodes have
* started and which nodes have not.
*/
} }
m_stopRec.inUse = false; return 0;
return m_stopRec.reply;
} }
int int
MgmtSrvr::exitSingleUser(int * stopCount, bool abort, MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
ExitSingleCallback callback, void * anyData)
{ {
m_stopRec.sentCount = 0;
m_stopRec.reply = 0;
m_stopRec.nodeId = 0;
m_stopRec.anyData = anyData;
m_stopRec.callback = callback;
m_stopRec.inUse = true;
NodeId nodeId = 0; NodeId nodeId = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ int count = 0;
if(okToSendTo(nodeId, true) == 0){
NdbApiSignal* signal = getSignal(); SignalSender ss(theFacade);
if (signal == NULL) { ss.lock(); // lock will be released on exit
return COULD_NOT_ALLOCATE_MEMORY;
}
SimpleSignal ssig;
ResumeReq* const resumeReq = ResumeReq* const resumeReq =
CAST_PTR(ResumeReq, signal->getDataPtrSend()); CAST_PTR(ResumeReq, ssig.getDataPtrSend());
signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ, ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
StopReq::SignalLength); ResumeReq::SignalLength);
resumeReq->senderData = 12; resumeReq->senderData = 12;
resumeReq->senderRef = _ownReference; resumeReq->senderRef = ss.getOwnRef();
m_stopRec.sentCount++; while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(callback == 0) if(okToSendTo(nodeId, true) == 0){
sendSignal(nodeId, WAIT_STOP, signal, true); SendStatus result = ss.sendSignal(nodeId, &ssig);
else if (result == SEND_OK)
sendSignal(nodeId, NO_WAIT, signal, true); count++;
} }
} }
m_stopRec.singleUserMode = false;
if(stopCount != 0) if(stopCount != 0)
* stopCount = m_stopRec.sentCount; * stopCount = count;
if(callback == 0){
m_stopRec.inUse = false;
return m_stopRec.reply;
} else {
return 0; return 0;
}
m_stopRec.inUse = false;
return m_stopRec.reply;
} }
/***************************************************************************** /*****************************************************************************
* Status * Status
****************************************************************************/ ****************************************************************************/
...@@ -1444,32 +1191,32 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort, ...@@ -1444,32 +1191,32 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
#include <ClusterMgr.hpp> #include <ClusterMgr.hpp>
int int
MgmtSrvr::status(int processId, MgmtSrvr::status(int nodeId,
ndb_mgm_node_status * _status, ndb_mgm_node_status * _status,
Uint32 * version, Uint32 * version,
Uint32 * _phase, Uint32 * _phase,
bool * _system, bool * _system,
Uint32 * dynamic, Uint32 * dynamic,
Uint32 * nodegroup, Uint32 * nodegroup,
Uint32 * connectCount) Uint32 * connectCount,
const char **address)
{ {
if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API || if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) { getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
if(versionNode(processId, false,0,0) ==0) versionNode(nodeId, *version, address);
* version = m_versionRec.version[processId]; } else {
else *address= get_connect_address(nodeId);
* version = 0;
} }
const ClusterMgr::Node node = const ClusterMgr::Node node =
theFacade->theClusterMgr->getNodeInfo(processId); theFacade->theClusterMgr->getNodeInfo(nodeId);
if(!node.connected){ if(!node.connected){
* _status = NDB_MGM_NODE_STATUS_NO_CONTACT; * _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
return 0; return 0;
} }
if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) { if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
* version = node.m_info.m_version; * version = node.m_info.m_version;
} }
...@@ -1532,67 +1279,81 @@ MgmtSrvr::status(int processId, ...@@ -1532,67 +1279,81 @@ MgmtSrvr::status(int processId,
} }
int int
MgmtSrvr::setEventReportingLevelImpl(int processId, MgmtSrvr::setEventReportingLevelImpl(int nodeId,
const EventSubscribeReq& ll) const EventSubscribeReq& ll)
{ {
INIT_SIGNAL_SENDER(ss,nodeId);
int result = okToSendTo(processId, true); SimpleSignal ssig;
if (result != 0) {
return result;
}
NdbApiSignal signal(_ownReference);
EventSubscribeReq * dst = EventSubscribeReq * dst =
CAST_PTR(EventSubscribeReq, signal.getDataPtrSend()); CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
* dst = ll;
signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
EventSubscribeReq::SignalLength); EventSubscribeReq::SignalLength);
*dst = ll;
theFacade->lock_mutex(); send(ss,ssig,nodeId,NODE_TYPE_DB);
send(&signal, processId, NODE_TYPE_DB);
theFacade->unlock_mutex(); #if 0
while (1)
{
SimpleSignal *signal = ss.waitFor();
int gsn = signal->readSignalNumber();
switch (gsn) {
case GSN_EVENT_SUBSCRIBE_CONF:{
break;
}
case GSN_EVENT_SUBSCRIBE_REF:{
return SEND_OR_RECEIVE_FAILED;
}
case GSN_NF_COMPLETEREP:{
const NFCompleteRep * const rep =
CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
if (rep->failedNodeId == nodeId)
return SEND_OR_RECEIVE_FAILED;
break;
}
case GSN_NODE_FAILREP:{
const NodeFailRep * const rep =
CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
if (NodeBitmask::get(rep->theNodes,nodeId))
return SEND_OR_RECEIVE_FAILED;
break;
}
default:
report_unknown_signal(signal);
return SEND_OR_RECEIVE_FAILED;
}
}
#endif
return 0; return 0;
} }
//**************************************************************************** //****************************************************************************
//**************************************************************************** //****************************************************************************
int int
MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll) MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
{ {
int result = okToSendTo(processId, true); INIT_SIGNAL_SENDER(ss,nodeId);
if (result != 0) {
return result;
}
NdbApiSignal signal(_ownReference);
SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend()); SimpleSignal ssig;
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
* dst = ll;
signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
SetLogLevelOrd::SignalLength); SetLogLevelOrd::SignalLength);
SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
*dst = ll;
theFacade->lock_mutex(); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
theFacade->sendSignalUnCond(&signal, processId);
theFacade->unlock_mutex();
return 0;
} }
int int
MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){ MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){
Uint32 max = (node == 0) ? MAX_NODES : node + 1; Uint32 max = (node == 0) ? MAX_NODES : node + 1;
for(; node < max; node++){ for(; node < max; node++){
while(nodeTypes[node] != (int)node_type && node < max) node++; while(nodeTypes[node] != (int)node_type && node < max) node++;
if(nodeTypes[node] != (int)node_type) if(nodeTypes[node] != (int)node_type)
break; break;
theFacade->sendSignalUnCond(signal, node); ss.sendSignal(node, &ssig);
} }
return 0; return 0;
} }
...@@ -1601,34 +1362,21 @@ MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){ ...@@ -1601,34 +1362,21 @@ MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
//**************************************************************************** //****************************************************************************
int int
MgmtSrvr::insertError(int processId, int errorNo) MgmtSrvr::insertError(int nodeId, int errorNo)
{ {
if (errorNo < 0) { if (errorNo < 0) {
return INVALID_ERROR_NUMBER; return INVALID_ERROR_NUMBER;
} }
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, signal->getDataPtrSend()); SimpleSignal ssig;
tamperOrd->errorNo = errorNo; ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
signal->set(TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
TamperOrd::SignalLength); TamperOrd::SignalLength);
TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
tamperOrd->errorNo = errorNo;
result = sendSignal(processId, NO_WAIT, signal, true); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
} }
...@@ -1637,37 +1385,23 @@ MgmtSrvr::insertError(int processId, int errorNo) ...@@ -1637,37 +1385,23 @@ MgmtSrvr::insertError(int processId, int errorNo)
//**************************************************************************** //****************************************************************************
int int
MgmtSrvr::setTraceNo(int processId, int traceNo) MgmtSrvr::setTraceNo(int nodeId, int traceNo)
{ {
if (traceNo < 0) { if (traceNo < 0) {
return INVALID_TRACE_NUMBER; return INVALID_TRACE_NUMBER;
} }
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); SimpleSignal ssig;
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear(); testOrd->clear();
// Assume TRACE command causes toggling. Not really defined... ? TODO // Assume TRACE command causes toggling. Not really defined... ? TODO
testOrd->setTraceCommand(TestOrd::Toggle, testOrd->setTraceCommand(TestOrd::Toggle,
(TestOrd::TraceSpecification)traceNo); (TestOrd::TraceSpecification)traceNo);
signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
result = sendSignal(processId, NO_WAIT, signal, true);
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0; return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
} }
//**************************************************************************** //****************************************************************************
...@@ -1686,14 +1420,10 @@ MgmtSrvr::getBlockNumber(const BaseString &blockName) ...@@ -1686,14 +1420,10 @@ MgmtSrvr::getBlockNumber(const BaseString &blockName)
//**************************************************************************** //****************************************************************************
int int
MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode, MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode,
const Vector<BaseString>& blocks) const Vector<BaseString>& blocks)
{ {
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
// Convert from MgmtSrvr format... // Convert from MgmtSrvr format...
...@@ -1728,12 +1458,10 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode, ...@@ -1728,12 +1458,10 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
return -1; return -1;
} }
NdbApiSignal* signal = getSignal(); SimpleSignal ssig;
if (signal == NULL) { ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
return COULD_NOT_ALLOCATE_MEMORY;
}
TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear(); testOrd->clear();
if (blocks.size() == 0 || blocks[0] == "ALL") { if (blocks.size() == 0 || blocks[0] == "ALL") {
...@@ -1743,78 +1471,44 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode, ...@@ -1743,78 +1471,44 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
for(unsigned i = 0; i < blocks.size(); i++){ for(unsigned i = 0; i < blocks.size(); i++){
int blockNumber = getBlockNumber(blocks[i]); int blockNumber = getBlockNumber(blocks[i]);
if (blockNumber == -1) { if (blockNumber == -1) {
releaseSignal(signal);
return INVALID_BLOCK_NAME; return INVALID_BLOCK_NAME;
} }
testOrd->addSignalLoggerCommand(blockNumber, command, logSpec); testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
} // for } // for
} // else } // else
signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
result = sendSignal(processId, NO_WAIT, signal, true);
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
} }
/***************************************************************************** /*****************************************************************************
* Signal tracing * Signal tracing
*****************************************************************************/ *****************************************************************************/
int MgmtSrvr::startSignalTracing(int processId) int MgmtSrvr::startSignalTracing(int nodeId)
{ {
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
SimpleSignal ssig;
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear(); testOrd->clear();
testOrd->setTestCommand(TestOrd::On); testOrd->setTestCommand(TestOrd::On);
signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
result = sendSignal(processId, NO_WAIT, signal, true);
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
} }
int int
MgmtSrvr::stopSignalTracing(int processId) MgmtSrvr::stopSignalTracing(int nodeId)
{ {
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); SimpleSignal ssig;
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear(); testOrd->clear();
testOrd->setTestCommand(TestOrd::Off); testOrd->setTestCommand(TestOrd::Off);
signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
result = sendSignal(processId, NO_WAIT, signal, true);
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
} }
...@@ -1823,7 +1517,7 @@ MgmtSrvr::stopSignalTracing(int processId) ...@@ -1823,7 +1517,7 @@ MgmtSrvr::stopSignalTracing(int processId)
*****************************************************************************/ *****************************************************************************/
int int
MgmtSrvr::dumpState(int processId, const char* args) MgmtSrvr::dumpState(int nodeId, const char* args)
{ {
// Convert the space separeted args // Convert the space separeted args
// string to an int array // string to an int array
...@@ -1845,29 +1539,20 @@ MgmtSrvr::dumpState(int processId, const char* args) ...@@ -1845,29 +1539,20 @@ MgmtSrvr::dumpState(int processId, const char* args)
} }
} }
return dumpState(processId, args_array, numArgs); return dumpState(nodeId, args_array, numArgs);
} }
int int
MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no) MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
{ {
int result; INIT_SIGNAL_SENDER(ss,nodeId);
result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
const Uint32 len = no > 25 ? 25 : no; const Uint32 len = no > 25 ? 25 : no;
SimpleSignal ssig;
DumpStateOrd * const dumpOrd = DumpStateOrd * const dumpOrd =
CAST_PTR(DumpStateOrd, signal->getDataPtrSend()); CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
signal->set(TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len); ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
for(Uint32 i = 0; i<25; i++){ for(Uint32 i = 0; i<25; i++){
if (i < len) if (i < len)
dumpOrd->args[i] = args[i]; dumpOrd->args[i] = args[i];
...@@ -1875,12 +1560,7 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no) ...@@ -1875,12 +1560,7 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
dumpOrd->args[i] = 0; dumpOrd->args[i] = 0;
} }
result = sendSignal(processId, NO_WAIT, signal, true); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
} }
...@@ -1911,42 +1591,18 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) ...@@ -1911,42 +1591,18 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
int gsn = signal->readSignalNumber(); int gsn = signal->readSignalNumber();
switch (gsn) { switch (gsn) {
case GSN_API_VERSION_CONF: {
if (theWaitState == WAIT_VERSION) {
const ApiVersionConf * const conf =
CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
if(m_versionRec.callback != 0)
m_versionRec.callback(conf->nodeId, conf->version, this, 0);
else {
m_versionRec.version[conf->nodeId]=conf->version;
}
} else return;
theWaitState = NO_WAIT;
}
break;
case GSN_EVENT_SUBSCRIBE_CONF: case GSN_EVENT_SUBSCRIBE_CONF:
break; break;
case GSN_EVENT_SUBSCRIBE_REF:
break;
case GSN_EVENT_REP: case GSN_EVENT_REP:
eventReport(refToNode(signal->theSendersBlockRef), signal->getDataPtr()); eventReport(refToNode(signal->theSendersBlockRef), signal->getDataPtr());
break; break;
case GSN_STOP_REF:{ case GSN_NF_COMPLETEREP:
const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
const NodeId nodeId = refToNode(signal->theSendersBlockRef);
handleStopReply(nodeId, ref->errorCode);
return;
}
break; break;
case GSN_NODE_FAILREP:
case GSN_MGM_LOCK_CONFIG_REP:
case GSN_MGM_LOCK_CONFIG_REQ:
case GSN_MGM_UNLOCK_CONFIG_REP:
case GSN_MGM_UNLOCK_CONFIG_REQ: {
m_signalRecvQueue.receive(new NdbApiSignal(*signal));
break; break;
}
default: default:
g_eventLogger.error("Unknown signal received. SignalNumber: " g_eventLogger.error("Unknown signal received. SignalNumber: "
...@@ -1961,75 +1617,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) ...@@ -1961,75 +1617,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
} }
} }
/**
* A database node was either stopped or there was some error
*/
void
MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
{
/**
* If we are in single user mode and get a stop reply from a
* DB node, then we have had a node crash.
* If all DB nodes are gone, and we are still in single user mode,
* the set m_stopRec.singleUserMode = false;
*/
if(m_stopRec.singleUserMode) {
ClusterMgr::Node node;
bool failure = true;
for(Uint32 i = 0; i<MAX_NODES; i++) {
if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
node = theFacade->theClusterMgr->getNodeInfo(i);
if((node.m_state.startLevel == NodeState::SL_NOTHING))
failure = true;
else
failure = false;
}
}
if(failure) {
m_stopRec.singleUserMode = false;
}
}
if(m_stopRec.inUse == false)
return;
if(!(m_stopRec.nodeId == 0 || m_stopRec.nodeId == nodeId))
goto error;
if(m_stopRec.sentCount <= 0)
goto error;
if(!(theWaitState == WAIT_STOP || m_stopRec.callback != 0))
goto error;
if(errCode != 0)
m_stopRec.reply = translateStopRef(errCode);
m_stopRec.sentCount --;
if(m_stopRec.sentCount == 0){
if(theWaitState == WAIT_STOP){
theWaitState = NO_WAIT;
NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
return;
}
if(m_stopRec.callback != 0){
m_stopRec.inUse = false;
StopCallback callback = m_stopRec.callback;
m_stopRec.callback = NULL;
(* callback)(m_stopRec.nodeId,
m_stopRec.anyData,
m_stopRec.reply);
return;
}
}
return;
error:
if(errCode != 0){
g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
GSN_STOP_REF, nodeId);
}
}
void void
MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
{ {
...@@ -2043,16 +1630,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) ...@@ -2043,16 +1630,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
theData[0] = NDB_LE_Disconnected; theData[0] = NDB_LE_Disconnected;
if(nfComplete) if(nfComplete)
{ {
handleStopReply(nodeId, 0);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
if(theWaitNode == nodeId &&
theWaitState != NO_WAIT && theWaitState != WAIT_STOP)
{
theWaitState = WAIT_NODEFAILURE;
NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
}
} }
eventReport(_ownNodeId, theData); eventReport(_ownNodeId, theData);
...@@ -2401,6 +1980,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData) ...@@ -2401,6 +1980,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
/*************************************************************************** /***************************************************************************
* Backup * Backup
***************************************************************************/ ***************************************************************************/
int int
MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
{ {
...@@ -2415,7 +1995,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) ...@@ -2415,7 +1995,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
if(!next) return NO_CONTACT_WITH_DB_NODES; if(!next) return NO_CONTACT_WITH_DB_NODES;
SimpleSignal ssig; SimpleSignal ssig;
BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend()); BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ, ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ,
BackupReq::SignalLength); BackupReq::SignalLength);
...@@ -2430,8 +2009,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) ...@@ -2430,8 +2009,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
while (1) { while (1) {
if (do_send) if (do_send)
{ {
SendStatus result = ss.sendSignal(nodeId, &ssig); if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
if (result != SEND_OK) {
return SEND_OR_RECEIVE_FAILED; return SEND_OR_RECEIVE_FAILED;
} }
if (waitCompleted == 0) if (waitCompleted == 0)
...@@ -2533,13 +2111,13 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) ...@@ -2533,13 +2111,13 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
return SEND_OR_RECEIVE_FAILED; return SEND_OR_RECEIVE_FAILED;
} }
} }
return 0;
} }
int int
MgmtSrvr::abortBackup(Uint32 backupId) MgmtSrvr::abortBackup(Uint32 backupId)
{ {
SignalSender ss(theFacade);
bool next; bool next;
NodeId nodeId = 0; NodeId nodeId = 0;
while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
...@@ -2549,25 +2127,17 @@ MgmtSrvr::abortBackup(Uint32 backupId) ...@@ -2549,25 +2127,17 @@ MgmtSrvr::abortBackup(Uint32 backupId)
return NO_CONTACT_WITH_DB_NODES; return NO_CONTACT_WITH_DB_NODES;
} }
NdbApiSignal* signal = getSignal(); SimpleSignal ssig;
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, signal->getDataPtrSend()); AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
signal->set(TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD, ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
AbortBackupOrd::SignalLength); AbortBackupOrd::SignalLength);
ord->requestType = AbortBackupOrd::ClientAbort; ord->requestType = AbortBackupOrd::ClientAbort;
ord->senderData = 19; ord->senderData = 19;
ord->backupId = backupId; ord->backupId = backupId;
int result = sendSignal(nodeId, NO_WAIT, signal, true); return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
return 0;
} }
...@@ -2582,26 +2152,6 @@ MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted) ...@@ -2582,26 +2152,6 @@ MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted)
return 0; return 0;
} }
NodeId
MgmtSrvr::getPrimaryNode() const {
#if 0
Uint32 tmp;
const Properties *prop = NULL;
getConfig()->get("SYSTEM", &prop);
if(prop == NULL)
return 0;
prop->get("PrimaryMGMNode", &tmp);
return tmp;
#else
return 0;
#endif
}
MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m) MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
: m_mgmsrv(m) : m_mgmsrv(m)
{ {
...@@ -2751,7 +2301,6 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value, ...@@ -2751,7 +2301,6 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value,
NdbMutex_Unlock(m_configMutex); NdbMutex_Unlock(m_configMutex);
return 0; return 0;
} }
int int
MgmtSrvr::setConnectionDbParameter(int node1, MgmtSrvr::setConnectionDbParameter(int node1,
int node2, int node2,
...@@ -2886,10 +2435,6 @@ int MgmtSrvr::set_connect_string(const char *str) ...@@ -2886,10 +2435,6 @@ int MgmtSrvr::set_connect_string(const char *str)
} }
template class Vector<SigMatch>;
#if __SUNPRO_CC != 0x560
template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbApiSignal**, unsigned);
#endif
template class MutexVector<unsigned short>; template class MutexVector<unsigned short>;
template class MutexVector<Ndb_mgmd_event_service::Event_listener>; template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
......
...@@ -22,15 +22,17 @@ ...@@ -22,15 +22,17 @@
#include <NdbCondition.h> #include <NdbCondition.h>
#include <mgmapi.h> #include <mgmapi.h>
#include <NdbTCP.h>
#include <ConfigRetriever.hpp>
#include <Vector.hpp> #include <Vector.hpp>
#include <NodeBitmask.hpp> #include <NodeBitmask.hpp>
#include <signaldata/ManagementServer.hpp> #include <signaldata/ManagementServer.hpp>
#include "SignalQueue.hpp"
#include <ndb_version.h> #include <ndb_version.h>
#include <EventLogger.hpp> #include <EventLogger.hpp>
#include <signaldata/EventSubscribeReq.hpp> #include <signaldata/EventSubscribeReq.hpp>
#include <SignalSender.hpp>
/** /**
* @desc Block number for Management server. * @desc Block number for Management server.
* @todo This should probably be somewhere else. I don't know where atm. * @todo This should probably be somewhere else. I don't know where atm.
...@@ -200,51 +202,26 @@ public: ...@@ -200,51 +202,26 @@ public:
~MgmtSrvr(); ~MgmtSrvr();
int status(int processId, /**
* Get status on a node.
* address may point to a common area (e.g. from inet_addr)
* There is no gaurentee that it is preserved across calls.
* Copy the string if you are not going to use it immediately.
*/
int status(int nodeId,
ndb_mgm_node_status * status, ndb_mgm_node_status * status,
Uint32 * version, Uint32 * version,
Uint32 * phase, Uint32 * phase,
bool * systemShutdown, bool * systemShutdown,
Uint32 * dynamicId, Uint32 * dynamicId,
Uint32 * nodeGroup, Uint32 * nodeGroup,
Uint32 * connectCount); Uint32 * connectCount,
const char **address);
// All the functions below may return any of this error codes: // All the functions below may return any of this error codes:
// NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE, // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE,
// COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED // COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED
typedef void (* StopCallback)(int nodeId, void * anyData, int errorCode);
typedef void (* VersionCallback)(int nodeId, int version,
void * anyData, int errorCode);
typedef void (* EnterSingleCallback)(int nodeId, void * anyData,
int errorCode);
typedef void (* ExitSingleCallback)(int nodeId, void * anyData,
int errorCode);
/**
* Lock configuration
*/
int lockConf();
/**
* Unlock configuration, and commit it if commit is true
*/
int unlockConf(bool commit);
/**
* Commit new configuration
*/
int commitConfig();
/**
* Rollback configuration
*/
int rollbackConfig();
/** /**
* Save a configuration to permanent storage * Save a configuration to permanent storage
*/ */
...@@ -273,12 +250,12 @@ public: ...@@ -273,12 +250,12 @@ public:
* @param processId: Id of the DB process to stop * @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus: * @return 0 if succeeded, otherwise: as stated above, plus:
*/ */
int stopNode(int nodeId, bool abort = false, StopCallback = 0, void *any= 0); int stopNode(int nodeId, bool abort = false);
/** /**
* Stop the system * Stop the system
*/ */
int stop(int * cnt = 0, bool abort = false, StopCallback = 0, void *any = 0); int stop(int * cnt = 0, bool abort = false);
/** /**
* print version info about a node * print version info about a node
...@@ -286,27 +263,18 @@ public: ...@@ -286,27 +263,18 @@ public:
* @param processId: Id of the DB process to stop * @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus: * @return 0 if succeeded, otherwise: as stated above, plus:
*/ */
int versionNode(int nodeId, bool abort = false, int versionNode(int nodeId, Uint32 &version, const char **address);
VersionCallback = 0, void *any= 0);
/**
* print version info about all node in the system
*/
int version(int * cnt = 0, bool abort = false,
VersionCallback = 0, void *any = 0);
/** /**
* Maintenance on the system * Maintenance on the system
*/ */
int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0, int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0);
EnterSingleCallback = 0, void *any = 0);
/** /**
* Resume from maintenance on the system * Resume from maintenance on the system
*/ */
int exitSingleUser(int * cnt = 0, bool abort = false, int exitSingleUser(int * cnt = 0, bool abort = false);
ExitSingleCallback = 0, void *any = 0);
/** /**
* Start DB process. * Start DB process.
...@@ -320,15 +288,14 @@ public: ...@@ -320,15 +288,14 @@ public:
* @param processId: Id of the DB process to start * @param processId: Id of the DB process to start
*/ */
int restartNode(int processId, bool nostart, bool initialStart, int restartNode(int processId, bool nostart, bool initialStart,
bool abort = false, bool abort = false);
StopCallback = 0, void * anyData = 0);
/** /**
* Restart the system * Restart the system
*/ */
int restart(bool nostart, bool initialStart, int restart(bool nostart, bool initialStart,
bool abort = false, bool abort = false,
int * stopCount = 0, StopCallback = 0, void * anyData = 0); int * stopCount = 0);
struct BackupEvent { struct BackupEvent {
enum Event { enum Event {
...@@ -482,13 +449,6 @@ public: ...@@ -482,13 +449,6 @@ public:
*/ */
const Config * getConfig() const; const Config * getConfig() const;
/**
* Change configuration paramter
*/
bool changeConfig(const BaseString &section,
const BaseString &param,
const BaseString &value);
/** /**
* Returns the node count for the specified node type. * Returns the node count for the specified node type.
* *
...@@ -497,11 +457,6 @@ public: ...@@ -497,11 +457,6 @@ public:
*/ */
int getNodeCount(enum ndb_mgm_node_type type) const; int getNodeCount(enum ndb_mgm_node_type type) const;
/**
* Returns the nodeId of the management master
*/
NodeId getPrimaryNode() const;
/** /**
* Returns the port number. * Returns the port number.
* @return port number. * @return port number.
...@@ -528,7 +483,16 @@ public: ...@@ -528,7 +483,16 @@ public:
private: private:
//************************************************************************** //**************************************************************************
int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32); int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
int sendSTOP_REQ(NodeId nodeId,
NodeBitmask &stoppedNodes,
Uint32 singleUserNodeId,
bool abort,
bool stop,
bool restart,
bool nostart,
bool initialStart);
/** /**
* Check if it is possible to send a signal to a (DB) process * Check if it is possible to send a signal to a (DB) process
...@@ -593,9 +557,6 @@ private: ...@@ -593,9 +557,6 @@ private:
// Returns: - // Returns: -
//************************************************************************** //**************************************************************************
void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal);
void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal);
//************************************************************************** //**************************************************************************
// Specific signal handling data // Specific signal handling data
//************************************************************************** //**************************************************************************
...@@ -619,60 +580,9 @@ private: ...@@ -619,60 +580,9 @@ private:
enum WaitSignalType { enum WaitSignalType {
NO_WAIT, // We don't expect to receive any signal NO_WAIT, // We don't expect to receive any signal
WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF
WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation
WAIT_STOP,
WAIT_BACKUP_STARTED,
WAIT_BACKUP_COMPLETED,
WAIT_VERSION,
WAIT_NODEFAILURE
}; };
/**
* Get an unused signal
* @return A signal if succeeded, NULL otherwise
*/
NdbApiSignal* getSignal();
/**
* Add a signal to the list of unused signals
* @param signal: The signal to add
*/
void releaseSignal(NdbApiSignal* signal);
/**
* Remove a signal from the list of unused signals and delete
* the memory for it.
*/
void freeSignal();
/**
* Send a signal
* @param processId: Id of the receiver process
* @param waitState: State denoting a set of signals we accept to receive
* @param signal: The signal to send
* @return 0 if succeeded, -1 otherwise
*/
int sendSignal(Uint16 processId, WaitSignalType waitState,
NdbApiSignal* signal, bool force = false);
/**
* Send a signal and wait for an answer signal
* @param processId: Id of the receiver process
* @param waitState: State denoting a set of signals we accept to receive.
* @param signal: The signal to send
* @return 0 if succeeded, -1 otherwise (for example failed to send or
* failed to receive expected signal).
*/
int sendRecSignal(Uint16 processId, WaitSignalType waitState,
NdbApiSignal* signal, bool force = false,
int waitTime = WAIT_FOR_RESPONSE_TIMEOUT);
/**
* Wait for a signal to arrive.
* @return 0 if signal arrived, -1 otherwise
*/
int receiveOptimisedResponse(int waitTime);
/** /**
* This function is called from "outside" of MgmtSrvr * This function is called from "outside" of MgmtSrvr
* when a signal is sent to MgmtSrvr. * when a signal is sent to MgmtSrvr.
...@@ -719,31 +629,7 @@ private: ...@@ -719,31 +629,7 @@ private:
class TransporterFacade * theFacade; class TransporterFacade * theFacade;
class SignalQueue m_signalRecvQueue; int sendVersionReq( int processId, Uint32 &version, const char **address);
struct StopRecord {
StopRecord(){ inUse = false; callback = 0; singleUserMode = false;}
bool inUse;
bool singleUserMode;
int sentCount;
int reply;
int nodeId;
void * anyData;
StopCallback callback;
};
StopRecord m_stopRec;
struct VersionRecord {
VersionRecord(){ inUse = false; callback = 0;}
bool inUse;
Uint32 version[MAX_NODES];
VersionCallback callback;
};
VersionRecord m_versionRec;
int sendVersionReq( int processId);
void handleStopReply(NodeId nodeId, Uint32 errCode);
int translateStopRef(Uint32 errCode); int translateStopRef(Uint32 errCode);
bool _isStopThread; bool _isStopThread;
...@@ -764,14 +650,8 @@ private: ...@@ -764,14 +650,8 @@ private:
static void *logLevelThread_C(void *); static void *logLevelThread_C(void *);
void logLevelThreadRun(); void logLevelThreadRun();
struct NdbThread *m_signalRecvThread;
static void *signalRecvThread_C(void *);
void signalRecvThreadRun();
Config *_props; Config *_props;
int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type);
ConfigRetriever *m_config_retriever; ConfigRetriever *m_config_retriever;
}; };
......
...@@ -23,228 +23,6 @@ ...@@ -23,228 +23,6 @@
#include <ConfigRetriever.hpp> #include <ConfigRetriever.hpp>
#include <ndb_version.h> #include <ndb_version.h>
void
MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal) {
NodeId sender = refToNode(signal->theSendersBlockRef);
const MgmLockConfigReq * const req = CAST_CONSTPTR(MgmLockConfigReq, signal->getDataPtr());
NdbApiSignal *reply = getSignal();
if(signal == NULL)
return; /** @todo handle allocation failure */
reply->set(TestOrd::TraceAPI,
MGMSRV,
GSN_MGM_LOCK_CONFIG_REP,
MgmLockConfigRep::SignalLength);
MgmLockConfigRep *lockRep = CAST_PTR(MgmLockConfigRep, reply->getDataPtrSend());
lockRep->errorCode = MgmLockConfigRep::UNKNOWN_ERROR;
if(req->newConfigGeneration < m_nextConfigGenerationNumber) {
lockRep->errorCode = MgmLockConfigRep::GENERATION_MISMATCH;
goto done;
}
NdbMutex_Lock(m_configMutex);
m_nextConfigGenerationNumber = req->newConfigGeneration+1;
lockRep->errorCode = MgmLockConfigRep::OK;
done:
sendSignal(sender, NO_WAIT, reply, true);
NdbMutex_Unlock(m_configMutex);
return;
}
void
MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal) {
NodeId sender = refToNode(signal->theSendersBlockRef);
const MgmUnlockConfigReq * const req = CAST_CONSTPTR(MgmUnlockConfigReq, signal->getDataPtr());
MgmUnlockConfigRep *unlockRep;
NdbApiSignal *reply = getSignal();
if(signal == NULL)
goto error; /** @todo handle allocation failure */
reply->set(TestOrd::TraceAPI,
MGMSRV,
GSN_MGM_UNLOCK_CONFIG_REP,
MgmUnlockConfigRep::SignalLength);
unlockRep = CAST_PTR(MgmUnlockConfigRep, reply->getDataPtrSend());
unlockRep->errorCode = MgmUnlockConfigRep::UNKNOWN_ERROR;
NdbMutex_Lock(m_configMutex);
if(req->commitConfig == 1) {
m_newConfig = fetchConfig();
commitConfig();
} else
rollbackConfig();
unlockRep->errorCode = MgmUnlockConfigRep::OK;
sendSignal(sender, NO_WAIT, reply, true);
error:
NdbMutex_Unlock(m_configMutex);
return;
}
/**
* Prepare all MGM nodes for configuration changes
*
* @returns 0 on success, or -1 on failure
*/
int
MgmtSrvr::lockConf() {
int result = -1;
MgmLockConfigReq* lockReq;
NodeId node = 0;
/* Check if this is the master node */
if(getPrimaryNode() != _ownNodeId)
goto done;
if(NdbMutex_Trylock(m_configMutex) != 0)
return -1;
m_newConfig = new Config(*_config); /* copy the existing config */
_config = m_newConfig;
m_newConfig = new Config(*_config);
m_nextConfigGenerationNumber++;
/* Make sure the new configuration _always_ is at least one step older */
if(m_nextConfigGenerationNumber < m_newConfig->getGenerationNumber()+1)
m_nextConfigGenerationNumber = _config->getGenerationNumber()+1;
m_newConfig->setGenerationNumber(m_nextConfigGenerationNumber);
node = 0;
while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
if(node != _ownNodeId) {
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
result = COULD_NOT_ALLOCATE_MEMORY;
goto done;
}
lockReq = CAST_PTR(MgmLockConfigReq, signal->getDataPtrSend());
signal->set(TestOrd::TraceAPI,
MGMSRV,
GSN_MGM_LOCK_CONFIG_REQ,
MgmLockConfigReq::SignalLength);
lockReq->newConfigGeneration = m_nextConfigGenerationNumber;
result = sendSignal(node, NO_WAIT, signal, true);
NdbApiSignal *reply =
m_signalRecvQueue.waitFor(GSN_MGM_LOCK_CONFIG_REP, 0);
if(reply == NULL) {
/** @todo handle timeout/error */
ndbout << __FILE__ << ":" << __LINE__ << endl;
result = -1;
goto done;
}
}
}
done:
NdbMutex_Unlock(m_configMutex);
return result;
}
/**
* Unlocks configuration
*
* @returns 0 on success, ! 0 on error
*/
int
MgmtSrvr::unlockConf(bool commit) {
int result = -1;
MgmUnlockConfigReq* unlockReq;
NodeId node = 0;
/* Check if this is the master node */
if(getPrimaryNode() != _ownNodeId)
goto done;
errno = 0;
if(NdbMutex_Lock(m_configMutex) != 0)
return -1;
if(commit)
commitConfig();
else
rollbackConfig();
node = 0;
while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
if(node != _ownNodeId) {
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
result = COULD_NOT_ALLOCATE_MEMORY;
goto done;
}
unlockReq = CAST_PTR(MgmUnlockConfigReq, signal->getDataPtrSend());
signal->set(TestOrd::TraceAPI,
MGMSRV,
GSN_MGM_UNLOCK_CONFIG_REQ,
MgmUnlockConfigReq::SignalLength);
unlockReq->commitConfig = commit;
result = sendSignal(node, NO_WAIT, signal, true);
NdbApiSignal *reply =
m_signalRecvQueue.waitFor(GSN_MGM_UNLOCK_CONFIG_REP, 0);
if(reply == NULL) {
/** @todo handle timeout/error */
result = -1;
goto done;
}
}
}
done:
NdbMutex_Unlock(m_configMutex);
return result;
}
/**
* Commit the new configuration
*/
int
MgmtSrvr::commitConfig() {
int ret = saveConfig(m_newConfig);
delete _config;
_config = m_newConfig;
m_newConfig = NULL;
ndbout << "commit " << ret << endl;
return ret;
}
/**
* Rollback to the old configuration
*/
int
MgmtSrvr::rollbackConfig() {
delete m_newConfig;
m_newConfig = NULL;
ndbout << "rollback" << endl;
return saveConfig(_config);
}
/** /**
* Save a configuration to the running configuration file * Save a configuration to the running configuration file
*/ */
...@@ -288,12 +66,3 @@ MgmtSrvr::fetchConfig() { ...@@ -288,12 +66,3 @@ MgmtSrvr::fetchConfig() {
} }
return 0; return 0;
} }
bool
MgmtSrvr::changeConfig(const BaseString &section,
const BaseString &param,
const BaseString &value) {
if(m_newConfig == NULL)
return false;
return m_newConfig->change(section, param, value);
}
...@@ -20,123 +20,3 @@ ...@@ -20,123 +20,3 @@
// Some kind of reuse should be preferred. // Some kind of reuse should be preferred.
//****************************************************************************** //******************************************************************************
#include "MgmtSrvr.hpp"
#include <NdbApiSignal.hpp>
#include <NdbTick.h>
NdbApiSignal*
MgmtSrvr::getSignal()
{
NdbApiSignal* tSignal;
tSignal = theSignalIdleList;
if (tSignal != NULL){
NdbApiSignal* tSignalNext = tSignal->next();
tSignal->next(NULL);
theSignalIdleList = tSignalNext;
return tSignal;
} else
{
tSignal = new NdbApiSignal(_ownReference);
if (tSignal != NULL)
tSignal->next(NULL);
}
return tSignal;
}
void
MgmtSrvr::releaseSignal(NdbApiSignal* aSignal)
{
aSignal->next(theSignalIdleList);
theSignalIdleList = aSignal;
}
void
MgmtSrvr::freeSignal()
{
NdbApiSignal* tSignal = theSignalIdleList;
theSignalIdleList = tSignal->next();
delete tSignal;
}
int
MgmtSrvr::sendSignal(Uint16 aNodeId,
WaitSignalType aWaitState,
NdbApiSignal* aSignal,
bool force)
{
int tReturnCode;
theFacade->lock_mutex();
if(force){
tReturnCode = theFacade->sendSignalUnCond(aSignal,
aNodeId);
} else {
tReturnCode = theFacade->sendSignal(aSignal,
aNodeId);
}
releaseSignal(aSignal);
if (tReturnCode == -1) {
theFacade->unlock_mutex();
return -1;
}
theWaitState = aWaitState;
theFacade->unlock_mutex();
return 0;
}
int
MgmtSrvr::sendRecSignal(Uint16 aNodeId,
WaitSignalType aWaitState,
NdbApiSignal* aSignal,
bool force,
int waitTime)
{
int tReturnCode;
theFacade->lock_mutex();
if(force){
tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
} else {
tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
}
releaseSignal(aSignal);
if (tReturnCode == -1) {
theFacade->unlock_mutex();
return -1;
}
theWaitState = aWaitState;
theWaitNode = aNodeId;
return receiveOptimisedResponse(waitTime);
}
int
MgmtSrvr::receiveOptimisedResponse(int waitTime)
{
int tResultCode;
theFacade->checkForceSend(_blockNumber);
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
while (theWaitState != NO_WAIT && theWaitState != WAIT_NODEFAILURE
&& waitTime > 0) {
NdbCondition_WaitTimeout(theMgmtWaitForResponseCondPtr,
theFacade->theMutexPtr,
waitTime);
if(theWaitState == NO_WAIT || theWaitState == WAIT_NODEFAILURE)
break;
waitTime = (maxTime - NdbTick_CurrentMillisecond());
}//while
if(theWaitState == NO_WAIT) {
tResultCode = 0;
} else {
tResultCode = -1;
}
theFacade->unlock_mutex();
return tResultCode;
}
...@@ -222,21 +222,6 @@ ParserRow<MgmApiSession> commands[] = { ...@@ -222,21 +222,6 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("level", Int, Mandatory, "Severety level"), MGM_ARG("level", Int, Mandatory, "Severety level"),
MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"), MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"),
MGM_CMD("config lock", &MgmApiSession::configLock, ""),
MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
MGM_ARG("commit", Int, Mandatory, "Commit changes"),
MGM_CMD("config change", &MgmApiSession::configChange, ""),
MGM_ARG("section", String, Mandatory, "Section"),
MGM_ARG("parameter", String, Mandatory, "Parameter"),
MGM_ARG("value", String, Mandatory, "Value"),
MGM_CMD("config lock", &MgmApiSession::configLock, ""),
MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
MGM_ARG("commit", Int, Mandatory, "Commit changes"),
MGM_CMD("set parameter", &MgmApiSession::setParameter, ""), MGM_CMD("set parameter", &MgmApiSession::setParameter, ""),
MGM_ARG("node", String, Mandatory, "Node"), MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("parameter", String, Mandatory, "Parameter"), MGM_ARG("parameter", String, Mandatory, "Parameter"),
...@@ -940,8 +925,10 @@ printNodeStatus(OutputStream *output, ...@@ -940,8 +925,10 @@ printNodeStatus(OutputStream *output,
nodeGroup = 0, nodeGroup = 0,
connectCount = 0; connectCount = 0;
bool system; bool system;
const char *address= NULL;
mgmsrv.status(nodeId, &status, &version, &startPhase, mgmsrv.status(nodeId, &status, &version, &startPhase,
&system, &dynamicId, &nodeGroup, &connectCount); &system, &dynamicId, &nodeGroup, &connectCount,
&address);
output->println("node.%d.type: %s", output->println("node.%d.type: %s",
nodeId, nodeId,
ndb_mgm_get_node_type_string(type)); ndb_mgm_get_node_type_string(type));
...@@ -953,7 +940,7 @@ printNodeStatus(OutputStream *output, ...@@ -953,7 +940,7 @@ printNodeStatus(OutputStream *output,
output->println("node.%d.dynamic_id: %d", nodeId, dynamicId); output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
output->println("node.%d.node_group: %d", nodeId, nodeGroup); output->println("node.%d.node_group: %d", nodeId, nodeGroup);
output->println("node.%d.connect_count: %d", nodeId, connectCount); output->println("node.%d.connect_count: %d", nodeId, connectCount);
output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId)); output->println("node.%d.address: %s", nodeId, address);
} }
} }
...@@ -1222,42 +1209,6 @@ MgmApiSession::setLogFilter(Parser_t::Context &ctx, ...@@ -1222,42 +1209,6 @@ MgmApiSession::setLogFilter(Parser_t::Context &ctx,
m_output->println(""); m_output->println("");
} }
void
MgmApiSession::configLock(Parser_t::Context &,
Properties const &) {
int ret = m_mgmsrv.lockConf();
m_output->println("config lock reply");
m_output->println("result: %d", ret);
m_output->println("");
}
void
MgmApiSession::configUnlock(Parser_t::Context &,
Properties const &args) {
Uint32 commit;
args.get("commit", &commit);
int ret = m_mgmsrv.unlockConf(commit == 1);
m_output->println("config unlock reply");
m_output->println("result: %d", ret);
m_output->println("");
}
void
MgmApiSession::configChange(Parser_t::Context &,
Properties const &args) {
BaseString section, param, value;
args.get("section", section);
args.get("parameter", param);
args.get("value", value);
int ret = m_mgmsrv.changeConfig(section.c_str(),
param.c_str(),
value.c_str());
m_output->println("config change reply");
m_output->println("result: %d", ret);
m_output->println("");
}
static NdbOut& static NdbOut&
operator<<(NdbOut& out, const LogLevel & ll) operator<<(NdbOut& out, const LogLevel & ll)
{ {
......
...@@ -83,9 +83,6 @@ public: ...@@ -83,9 +83,6 @@ public:
void setClusterLogLevel(Parser_t::Context &ctx, void setClusterLogLevel(Parser_t::Context &ctx,
const class Properties &args); const class Properties &args);
void setLogFilter(Parser_t::Context &ctx, const class Properties &args); void setLogFilter(Parser_t::Context &ctx, const class Properties &args);
void configLock(Parser_t::Context &ctx, const class Properties &args);
void configUnlock(Parser_t::Context &ctx, const class Properties &args);
void configChange(Parser_t::Context &ctx, const class Properties &args);
void setParameter(Parser_t::Context &ctx, const class Properties &args); void setParameter(Parser_t::Context &ctx, const class Properties &args);
void setConnectionParameter(Parser_t::Context &ctx, void setConnectionParameter(Parser_t::Context &ctx,
......
#!/usr/bin/perl -w
use strict;
use DBI;
use POSIX;
use HTML::Template;
# MySQL Cluster size estimator
# ----------------------------
#
# (C)2005 MySQL AB
#
#
# The purpose of this tool is to work out storage requirements
# from an existing MySQL database.
#
# This involves connecting to a mysql server and throwing a bunch
# of queries at it.
#
# We currently estimate sizes for: 4.1, 5.0 and 5.1 to various amounts
# of accurracy.
#
# There is no warranty.
#
# BUGS
# ----
# - enum/set is 0 byte storage! Woah - efficient!
# - some float stores come out weird (when there's a comma e.g. 'float(4,1)')
# - no disk data values
# - computes the storage requirements of views (and probably MERGE)
# - ignores character sets.
my $template = HTML::Template->new(filename => 'ndb_size.tmpl',
die_on_bad_params => 0);
my $dbh;
{
my $database= $ARGV[0];
my $hostname= $ARGV[1];
my $port= $ARGV[2];
my $user= $ARGV[3];
my $password= $ARGV[4];
my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
$dbh= DBI->connect($dsn, $user, $password);
$template->param(db => $database);
$template->param(dsn => $dsn);
}
my @releases = ({rel=>'4.1'},{rel=>'5.0'},{rel=>'5.1'});
$template->param(releases => \@releases);
my $tables = $dbh->selectall_arrayref("show tables");
my @table_size;
sub align {
my($to,@unaligned) = @_;
my @aligned;
foreach my $x (@unaligned) {
push @aligned, $to * POSIX::floor(($x+$to-1)/$to);
}
return @aligned;
}
foreach(@{$tables})
{
my $table= @{$_}[0];
my @columns;
my $info= $dbh->selectall_hashref("describe ".$dbh->quote($table),"Field");
my @count = $dbh->selectrow_array("select count(*) from "
.$dbh->quote($table));
my %columnsize; # used for index calculations
# We now work out the DataMemory usage
# sizes for 4.1, 5.0, 5.1
my @totalsize= (0,0,0);
foreach(keys %$info)
{
my @realsize = (0,0,0);
my $type;
my $size;
my $name= $_;
if($$info{$_}{Type} =~ /^(.*?)\((\d+)\)/)
{
$type= $1;
$size= $2;
}
else
{
$type= $$info{$_}{Type};
}
if($type =~ /tinyint/)
{@realsize=(1,1,1)}
elsif($type =~ /smallint/)
{@realsize=(2,2,2)}
elsif($type =~ /mediumint/)
{@realsize=(3,3,3)}
elsif($type =~ /bigint/)
{@realsize=(8,8,8)}
elsif($type =~ /int/)
{@realsize=(4,4,4)}
elsif($type =~ /float/)
{
if($size<=24)
{@realsize=(4,4,4)}
else
{@realsize=(8,8,8)}
}
elsif($type =~ /double/ || $type =~ /real/)
{@realsize=(8,8,8)}
elsif($type =~ /bit/)
{
my $a=($size+7)/8;
@realsize = ($a,$a,$a);
}
elsif($type =~ /datetime/)
{@realsize=(8,8,8)}
elsif($type =~ /timestamp/)
{@realsize=(4,4,4)}
elsif($type =~ /date/ || $type =~ /time/)
{@realsize=(3,3,3)}
elsif($type =~ /year/)
{@realsize=(1,1,1)}
elsif($type =~ /varchar/ || $type =~ /varbinary/)
{
my $fixed= 1+$size;
my @dynamic=$dbh->selectrow_array("select avg(length("
.$dbh->quote($name)
.")) from ".$dbh->quote($table));
$dynamic[0]=0 if !$dynamic[0];
@realsize= ($fixed,$fixed,ceil($dynamic[0]));
}
elsif($type =~ /binary/ || $type =~ /char/)
{@realsize=($size,$size,$size)}
elsif($type =~ /text/ || $type =~ /blob/)
{@realsize=(256,256,1)} # FIXME check if 5.1 is correct
@realsize= align(4,@realsize);
$totalsize[$_]+=$realsize[$_] foreach 0..$#totalsize;
my @realout;
push @realout,{val=>$_} foreach @realsize;
push @columns, {
name=>$name,
type=>$type,
size=>$size,
key=>$$info{$_}{Key},
datamemory=>\@realout,
};
$columnsize{$name}= \@realsize; # used for index calculations
}
# And now... the IndexMemory usage.
#
# Firstly, we assemble some information about the indexes.
# We use SHOW INDEX instead of using INFORMATION_SCHEMA so
# we can still connect to pre-5.0 mysqlds.
my %indexes;
{
my $sth= $dbh->prepare("show index from "$dbh->quote($table));
$sth->execute;
while(my $i = $sth->fetchrow_hashref)
{
$indexes{${%$i}{Key_name}}= {
type=>${%$i}{Index_type},
unique=>!${%$i}{Non_unique},
comment=>${%$i}{Comment},
} if !defined($indexes{${%$i}{Key_name}});
$indexes{${%$i}{Key_name}}{columns}[${%$i}{Seq_in_index}-1]=
${%$i}{Column_name};
}
}
if(!defined($indexes{PRIMARY})) {
$indexes{PRIMARY}= {
type=>'BTREE',
unique=>1,
comment=>'Hidden pkey created by NDB',
columns=>['HIDDEN_NDB_PKEY'],
};
push @columns, {
name=>'HIDDEN_NDB_PKEY',
type=>'bigint',
size=>8,
key=>'PRI',
datamemory=>[{val=>8},{val=>8},{val=>8}],
};
$columnsize{'HIDDEN_NDB_PKEY'}= [8,8,8];
}
my @IndexDataMemory= ({val=>0},{val=>0},{val=>0});
my @RowIndexMemory= ({val=>0},{val=>0},{val=>0});
my @indexes;
foreach my $index (keys %indexes) {
my $im41= 25;
$im41+=$columnsize{$_}[0] foreach @{$indexes{$index}{columns}};
my @im = ({val=>$im41},{val=>25},{val=>25});
my @dm = ({val=>10},{val=>10},{val=>10});
push @indexes, {
name=>$index,
type=>$indexes{$index}{type},
columns=>join(',',@{$indexes{$index}{columns}}),
indexmemory=>\@im,
datamemory=>\@dm,
};
$IndexDataMemory[$_]{val}+=$dm[$_]{val} foreach 0..2;
$RowIndexMemory[$_]{val}+=$im[$_]{val} foreach 0..2;
}
# total size + 16 bytes overhead
my @TotalDataMemory;
$TotalDataMemory[$_]{val}=$IndexDataMemory[$_]{val}+$totalsize[$_]+16 foreach 0..2;
my @RowDataMemory;
push @RowDataMemory,{val=>$_} foreach @totalsize;
my @RowPerPage;
push @RowPerPage,{val=>(floor((32768-128)/$TotalDataMemory[$_]{val}))} foreach 0..$#TotalDataMemory;
my @RowPerIndexPage;
push @RowPerIndexPage,{val=>(floor(8192/$RowIndexMemory[$_]{val}))} foreach 0..$#TotalDataMemory;
my @DataMemory;
push @DataMemory,{val=>ceil(($count[0]/($RowPerPage[$_]{val})))*32} foreach 0..$#RowPerPage;
my @IndexMemory;
push @IndexMemory,{val=>ceil(($count[0]/($RowPerIndexPage[$_]{val})))*8} foreach 0..$#RowPerPage;
my $count= $count[0];
my @counts;
$counts[$_]{val}= $count foreach 0..$#releases;
push @table_size, {
table=>$table,
indexes=>\@indexes,
columns=>\@columns,
count=>\@counts,
RowDataMemory=>\@RowDataMemory,
releases=>\@releases,
IndexDataMemory=>\@IndexDataMemory,
TotalDataMemory=>\@TotalDataMemory,
RowPerPage=>\@RowPerPage,
DataMemory=>\@DataMemory,
RowIndexMemory=>\@RowIndexMemory,
RowPerIndexPage=>\@RowPerIndexPage,
IndexMemory=>\@IndexMemory,
};
}
$template->param(tables => \@table_size);
print $template->output;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
<meta name="keywords" content="MySQL Cluster" />
<title>MySQL Cluster size estimate for <TMPL_VAR NAME="db" ESCAPE="HTML"></title>
<style type="text/css">
table { border-collapse: collapse }
td,th { border: 1px solid black }
</style>
</head>
<body>
<h1>MySQL Cluster analysis for <TMPL_VAR NAME="db" escape="html"></h1>
<p>This is an automated analysis of the <TMPL_VAR NAME="DSN" escape="html"> database for migration into <a href="http://www.mysql.com/">MySQL</a> Cluster. No warranty is made to the accuracy of the information.</p>
<p>This information should be valid for MySQL 4.1</p>
<ul>
<TMPL_LOOP NAME="tables">
<li><TMPL_VAR NAME="table"></li>
</TMPL_LOOP>
</ul>
<hr/>
<TMPL_LOOP NAME="tables">
<h2><TMPL_VAR NAME="table"></h2>
<table>
<tr>
<th>Column</th>
<th>Type</th>
<th>Size</th>
<th>Key</th>
<TMPL_LOOP NAME=releases>
<th><TMPL_VAR NAME=rel> NDB Size</th>
</TMPL_LOOP>
</tr>
<TMPL_LOOP NAME="columns">
<tr>
<td><TMPL_VAR NAME=name></td>
<td><TMPL_VAR NAME=type></td>
<td><TMPL_VAR NAME=size></td>
<td><TMPL_VAR NAME=key></td>
<TMPL_LOOP NAME=datamemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
</TMPL_LOOP>
</table>
<p>&nbsp;</p>
<h3>Indexes</h3>
<p>We assume that indexes are ORDERED (not created USING HASH). If order is not required, 10 bytes of data memory can be saved per row if the index is created USING HASH</p>
<table>
<tr>
<th>Index</th>
<th>Type</th>
<th>Columns</th>
<TMPL_LOOP NAME=releases>
<th><TMPL_VAR NAME=rel> IdxMem</th>
</TMPL_LOOP>
<TMPL_LOOP NAME=releases>
<th><TMPL_VAR NAME=rel> DatMem</th>
</TMPL_LOOP>
</tr>
<TMPL_LOOP NAME="indexes">
<tr>
<td><TMPL_VAR NAME=name></td>
<td><TMPL_VAR NAME=type></td>
<td><TMPL_VAR NAME=columns></td>
<TMPL_LOOP NAME=indexmemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
<TMPL_LOOP NAME=datamemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
</TMPL_LOOP>
</table>
<h3>DataMemory Usage</h3>
<table>
<tr>
<th>&nbsp;</th>
<TMPL_LOOP NAME=releases>
<th><TMPL_VAR NAME=rel></th>
</TMPL_LOOP>
</tr>
<tr>
<th>Row Overhead</th>
<TMPL_LOOP NAME=releases>
<td>16</td>
</TMPL_LOOP>
</tr>
<tr>
<th>Column DataMemory/Row</th>
<TMPL_LOOP NAME=RowDataMemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Index DataMemory/Row</th>
<TMPL_LOOP NAME=IndexDataMemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Total DataMemory/Row</th>
<TMPL_LOOP NAME=TotalDataMemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Rows per 32kb page</th>
<TMPL_LOOP NAME=RowPerPage>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Current number of rows</th>
<TMPL_LOOP NAME=count>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Total DataMemory (kb)</th>
<TMPL_LOOP NAME=DataMemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
</table>
<h3>IndexMemory Usage</h3>
<table>
<tr>
<th>&nbsp;</th>
<TMPL_LOOP NAME=releases>
<th><TMPL_VAR NAME=rel></th>
</TMPL_LOOP>
</tr>
<tr>
<th>IndexMemory/Row</th>
<TMPL_LOOP NAME=RowIndexMemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Rows per 8kb page</th>
<TMPL_LOOP NAME=RowPerIndexPage>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Current number of rows</th>
<TMPL_LOOP NAME=count>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
<th>Total IndexMemory (kb)</th>
<TMPL_LOOP NAME=IndexMemory>
<td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
</table>
<hr/>
</TMPL_LOOP>
<p>This is the output of ndb_size.pl.</p>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment