Commit e1c9dd5f authored by unknown's avatar unknown

BUG#18966 Change in stop/shutdown behaviour

Improvements that were discussed with Tomas.

Maintain protocol backwards/forwards compatibilty for client and server and support
the commands from ndb_mgm 'as expected'


ndb/include/mgmapi/mgmapi.h:
  Add ndb_mgm_stop3 mgmapi function.
   - This supports stopping all DB nodes, or all DB and MGM nodes.
   - It also returns to mgmapi program if it needs to disconnect to apply changes.
  
  Add ndb_mgm_restart3 mgmapi function.
   - Tells mgmapi program if it needs to disconnect to apply changes
  
  Add (internal) ndb_mgm_get_version
   - designed to be used to find out what protocol version we need to speak to the server.
ndb/src/mgmapi/mgmapi.cpp:
  Add cache of mgmd version to ndb_mgm_handle. Only filled out in functions that
  need to know the version of the mgmd we're talking to.
  Initialize these members in create handle.
  added ndb_mgm_get_version which asks the mgm server what version it is. This call
  has been supported since the dawn of time, no compatibility issues here.
  
  Add implementation of ndb_mgm_stop3
  Check what version of the protocol the server speaks, and speak it.
  Add compatibility for ndb_mgm_stop2
  
  Same for ndb_mgm_restart3.
ndb/src/mgmclient/CommandInterpreter.cpp:
  Simplify stop and restart code.
  
  Use the new ndb_mgm_(stop|restart)3 calls to find out if we need to disconnect.
ndb/src/mgmsrv/MgmtSrvr.cpp:
  Add nice call for shutting down MGM servers (like shutdownDB)
ndb/src/mgmsrv/MgmtSrvr.hpp:
  add prototype for shutdownMGM
ndb/src/mgmsrv/Services.cpp:
  Add restart node v2, stop v2, stop all v2 while maintaining protocol backwards
  compatibility.
  
  Unfortunately we can't add result lines due to protocol errors in clients :(
  Neither can we add extra things to the 'result: Ok' line due to the use of
  strcmp instead of strncmp.
ndb/src/mgmsrv/Services.hpp:
  Add prototypes for restart, stop and stopall v1 and v2
parent 564ba97b
...@@ -694,6 +694,28 @@ extern "C" { ...@@ -694,6 +694,28 @@ extern "C" {
int ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, int ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes,
const int * node_list, int abort); const int * node_list, int abort);
/**
* Stops cluster nodes
*
* @param handle Management handle.
* @param no_of_nodes Number of database nodes to stop<br>
* -1: All database and management nodes<br>
* 0: All database nodes in cluster<br>
* n: Stop the <var>n</var> node(s) specified in
* the array node_list
* @param node_list List of node IDs of database nodes to be stopped
* @param abort Don't perform graceful stop,
* but rather stop immediately
* @param disconnect Returns true if you need to disconnect to apply
* the stop command (e.g. stopping the mgm server
* that handle is connected to)
*
* @return Number of nodes stopped (-1 on error).
*/
int ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes,
const int * node_list, int abort, int *disconnect);
/** /**
* Restart database nodes * Restart database nodes
* *
...@@ -733,6 +755,31 @@ extern "C" { ...@@ -733,6 +755,31 @@ extern "C" {
const int * node_list, int initial, const int * node_list, int initial,
int nostart, int abort); int nostart, int abort);
/**
* Restart nodes
*
* @param handle Management handle.
* @param no_of_nodes Number of database nodes to be restarted:<br>
* 0: Restart all database nodes in the cluster<br>
* n: Restart the <var>n</var> node(s) specified in the
* array node_list
* @param node_list List of node IDs of database nodes to be restarted
* @param initial Remove filesystem from restarting node(s)
* @param nostart Don't actually start node(s) but leave them
* waiting for start command
* @param abort Don't perform graceful restart,
* but rather restart immediately
* @param disconnect Returns true if mgmapi client must disconnect from
* server to apply the requested operation. (e.g.
* restart the management server)
*
*
* @return Number of nodes stopped (-1 on error).
*/
int ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes,
const int * node_list, int initial,
int nostart, int abort, int *disconnect);
/** /**
* Start database nodes * Start database nodes
* *
...@@ -1023,6 +1070,16 @@ extern "C" { ...@@ -1023,6 +1070,16 @@ extern "C" {
*/ */
Uint32 ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle); Uint32 ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle);
/**
* Get the version of the mgm server we're talking to.
* Designed to allow switching of protocol depending on version
* so that new clients can speak to old servers in a compat mode
*/
int ndb_mgm_get_version(NdbMgmHandle handle,
int *major, int *minor, int* build,
int len, char* str);
/** /**
* Config iterator * Config iterator
*/ */
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <mgmapi_debug.h> #include <mgmapi_debug.h>
#include "mgmapi_configuration.hpp" #include "mgmapi_configuration.hpp"
#include <socket_io.h> #include <socket_io.h>
#include <version.h>
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <SocketServer.hpp> #include <SocketServer.hpp>
...@@ -103,6 +104,9 @@ struct ndb_mgm_handle { ...@@ -103,6 +104,9 @@ struct ndb_mgm_handle {
#endif #endif
FILE *errstream; FILE *errstream;
char *m_name; char *m_name;
int mgmd_version_major;
int mgmd_version_minor;
int mgmd_version_build;
}; };
#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s) #define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)
...@@ -168,6 +172,10 @@ ndb_mgm_create_handle() ...@@ -168,6 +172,10 @@ ndb_mgm_create_handle()
h->logfile = 0; h->logfile = 0;
#endif #endif
h->mgmd_version_major= -1;
h->mgmd_version_minor= -1;
h->mgmd_version_build= -1;
DBUG_PRINT("info", ("handle=0x%x", (UintPtr)h)); DBUG_PRINT("info", ("handle=0x%x", (UintPtr)h));
DBUG_RETURN(h); DBUG_RETURN(h);
} }
...@@ -826,37 +834,75 @@ ndb_mgm_stop(NdbMgmHandle handle, int no_of_nodes, const int * node_list) ...@@ -826,37 +834,75 @@ ndb_mgm_stop(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
return ndb_mgm_stop2(handle, no_of_nodes, node_list, 0); return ndb_mgm_stop2(handle, no_of_nodes, node_list, 0);
} }
extern "C" extern "C"
int int
ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int abort) int abort)
{ {
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop2"); int disconnect;
const ParserRow<ParserDummy> stop_reply[] = { return ndb_mgm_stop3(handle, no_of_nodes, node_list, abort, &disconnect);
}
extern "C"
int
ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int abort, int *disconnect)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop3");
const ParserRow<ParserDummy> stop_reply_v1[] = {
MGM_CMD("stop reply", NULL, ""),
MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
MGM_ARG("result", String, Mandatory, "Error message"),
MGM_END()
};
const ParserRow<ParserDummy> stop_reply_v2[] = {
MGM_CMD("stop reply", NULL, ""), MGM_CMD("stop reply", NULL, ""),
MGM_ARG("stopped", Int, Optional, "No of stopped nodes"), MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
MGM_ARG("result", String, Mandatory, "Error message"), MGM_ARG("result", String, Mandatory, "Error message"),
MGM_ARG("disconnect", Int, Mandatory, "Need to disconnect"),
MGM_END() MGM_END()
}; };
CHECK_HANDLE(handle, -1); CHECK_HANDLE(handle, -1);
CHECK_CONNECTED(handle, -1); CHECK_CONNECTED(handle, -1);
if(no_of_nodes < 0){ if(handle->mgmd_version_build==-1)
{
char verstr[50];
ndb_mgm_get_version(handle,
&(handle->mgmd_version_major),
&(handle->mgmd_version_minor),
&(handle->mgmd_version_build),
sizeof(verstr),
verstr);
}
int use_v2= (handle->mgmd_version_major==5)
&& (
(handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
);
if(no_of_nodes < -1){
SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES, SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES,
"Negative number of nodes requested to stop"); "Negative number of nodes requested to stop");
return -1; return -1;
} }
Uint32 stoppedNoOfNodes = 0; Uint32 stoppedNoOfNodes = 0;
if(no_of_nodes == 0){ if(no_of_nodes <= 0){
/** /**
* All database nodes should be stopped * All nodes should be stopped (all or just db)
*/ */
Properties args; Properties args;
args.put("abort", abort); args.put("abort", abort);
if(use_v2)
args.put("stop", (no_of_nodes==-1)?"mgm,db":"db");
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, stop_reply, "stop all", &args); if(use_v2)
reply = ndb_mgm_call(handle, stop_reply_v2, "stop all v2", &args);
else
reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(reply, -1);
if(!reply->get("stopped", &stoppedNoOfNodes)){ if(!reply->get("stopped", &stoppedNoOfNodes)){
...@@ -865,6 +911,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -865,6 +911,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
delete reply; delete reply;
return -1; return -1;
} }
if(use_v2)
reply->get("disconnect", (Uint32*)disconnect);
else
*disconnect= 0;
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
if(strcmp(result.c_str(), "Ok") != 0) { if(strcmp(result.c_str(), "Ok") != 0) {
...@@ -890,7 +940,11 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -890,7 +940,11 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
args.put("abort", abort); args.put("abort", abort);
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, stop_reply, "stop", &args); if(use_v2)
reply = ndb_mgm_call(handle, stop_reply_v2, "stop v2", &args);
else
reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args);
CHECK_REPLY(reply, stoppedNoOfNodes); CHECK_REPLY(reply, stoppedNoOfNodes);
if(!reply->get("stopped", &stoppedNoOfNodes)){ if(!reply->get("stopped", &stoppedNoOfNodes)){
SET_ERROR(handle, NDB_MGM_STOP_FAILED, SET_ERROR(handle, NDB_MGM_STOP_FAILED,
...@@ -898,6 +952,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -898,6 +952,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
delete reply; delete reply;
return -1; return -1;
} }
if(use_v2)
reply->get("disconnect", (Uint32*)disconnect);
else
*disconnect= 0;
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
if(strcmp(result.c_str(), "Ok") != 0) { if(strcmp(result.c_str(), "Ok") != 0) {
...@@ -909,22 +967,65 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -909,22 +967,65 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
return stoppedNoOfNodes; return stoppedNoOfNodes;
} }
extern "C"
int
ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart");
return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0);
}
extern "C" extern "C"
int int
ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int initial, int nostart, int abort) int initial, int nostart, int abort)
{ {
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart2"); int disconnect;
return ndb_mgm_restart3(handle, no_of_nodes, node_list, initial, nostart,
abort, &disconnect);
}
extern "C"
int
ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int initial, int nostart, int abort, int *disconnect)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart3");
Uint32 restarted = 0; Uint32 restarted = 0;
const ParserRow<ParserDummy> restart_reply[] = { const ParserRow<ParserDummy> restart_reply_v1[] = {
MGM_CMD("restart reply", NULL, ""),
MGM_ARG("result", String, Mandatory, "Error message"),
MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
MGM_END()
};
const ParserRow<ParserDummy> restart_reply_v2[] = {
MGM_CMD("restart reply", NULL, ""), MGM_CMD("restart reply", NULL, ""),
MGM_ARG("result", String, Mandatory, "Error message"), MGM_ARG("result", String, Mandatory, "Error message"),
MGM_ARG("restarted", Int, Optional, "No of restarted nodes"), MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
MGM_ARG("disconnect", Int, Optional, "Disconnect to apply"),
MGM_END() MGM_END()
}; };
CHECK_HANDLE(handle, -1); CHECK_HANDLE(handle, -1);
CHECK_CONNECTED(handle, -1); CHECK_CONNECTED(handle, -1);
if(handle->mgmd_version_build==-1)
{
char verstr[50];
ndb_mgm_get_version(handle,
&(handle->mgmd_version_major),
&(handle->mgmd_version_minor),
&(handle->mgmd_version_build),
sizeof(verstr),
verstr);
}
int use_v2= (handle->mgmd_version_major==5)
&& (
(handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
);
if(no_of_nodes < 0){ if(no_of_nodes < 0){
SET_ERROR(handle, NDB_MGM_RESTART_FAILED, SET_ERROR(handle, NDB_MGM_RESTART_FAILED,
"Restart requested of negative number of nodes"); "Restart requested of negative number of nodes");
...@@ -939,7 +1040,7 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -939,7 +1040,7 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
const Properties *reply; const Properties *reply;
const int timeout = handle->read_timeout; const int timeout = handle->read_timeout;
handle->read_timeout= 5*60*1000; // 5 minutes handle->read_timeout= 5*60*1000; // 5 minutes
reply = ndb_mgm_call(handle, restart_reply, "restart all", &args); reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args);
handle->read_timeout= timeout; handle->read_timeout= timeout;
CHECK_REPLY(reply, -1); CHECK_REPLY(reply, -1);
...@@ -975,7 +1076,10 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -975,7 +1076,10 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
const Properties *reply; const Properties *reply;
const int timeout = handle->read_timeout; const int timeout = handle->read_timeout;
handle->read_timeout= 5*60*1000; // 5 minutes handle->read_timeout= 5*60*1000; // 5 minutes
reply = ndb_mgm_call(handle, restart_reply, "restart node", &args); if(use_v2)
reply = ndb_mgm_call(handle, restart_reply_v2, "restart node v2", &args);
else
reply = ndb_mgm_call(handle, restart_reply_v1, "restart node", &args);
handle->read_timeout= timeout; handle->read_timeout= timeout;
if(reply != NULL) { if(reply != NULL) {
BaseString result; BaseString result;
...@@ -986,20 +1090,16 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -986,20 +1090,16 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
return -1; return -1;
} }
reply->get("restarted", &restarted); reply->get("restarted", &restarted);
if(use_v2)
reply->get("disconnect", (Uint32*)disconnect);
else
*disconnect= 0;
delete reply; delete reply;
} }
return restarted; return restarted;
} }
extern "C"
int
ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart");
return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0);
}
static const char *clusterlog_severity_names[]= static const char *clusterlog_severity_names[]=
{ "enabled", "debug", "info", "warning", "error", "critical", "alert" }; { "enabled", "debug", "info", "warning", "error", "critical", "alert" };
...@@ -2353,4 +2453,56 @@ int ndb_mgm_end_session(NdbMgmHandle handle) ...@@ -2353,4 +2453,56 @@ int ndb_mgm_end_session(NdbMgmHandle handle)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
extern "C"
int ndb_mgm_get_version(NdbMgmHandle handle,
int *major, int *minor, int *build, int len, char* str)
{
DBUG_ENTER("ndb_mgm_get_version");
CHECK_HANDLE(handle, 0);
CHECK_CONNECTED(handle, 0);
Properties args;
const ParserRow<ParserDummy> reply[]= {
MGM_CMD("version", NULL, ""),
MGM_ARG("id", Int, Mandatory, "ID"),
MGM_ARG("major", Int, Mandatory, "Major"),
MGM_ARG("minor", Int, Mandatory, "Minor"),
MGM_ARG("string", String, Mandatory, "String"),
MGM_END()
};
const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get version", &args);
CHECK_REPLY(prop, 0);
Uint32 id;
if(!prop->get("id",&id)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
*build= getBuild(id);
if(!prop->get("major",(Uint32*)major)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
if(!prop->get("minor",(Uint32*)minor)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
BaseString result;
if(!prop->get("string", result)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
strncpy(str, result.c_str(), len);
delete prop;
DBUG_RETURN(1);
}
template class Vector<const ParserRow<ParserDummy>*>; template class Vector<const ParserRow<ParserDummy>*>;
...@@ -1057,7 +1057,8 @@ CommandInterpreter::executeShutdown(char* parameters) ...@@ -1057,7 +1057,8 @@ CommandInterpreter::executeShutdown(char* parameters)
NdbAutoPtr<char> ap1((char*)state); NdbAutoPtr<char> ap1((char*)state);
int result = 0; int result = 0;
result = ndb_mgm_stop(m_mgmsrv, 0, 0); int need_disconnect;
result = ndb_mgm_stop3(m_mgmsrv, -1, 0, 0, &need_disconnect);
if (result < 0) { if (result < 0) {
ndbout << "Shutdown of NDB Cluster node(s) failed." << endl; ndbout << "Shutdown of NDB Cluster node(s) failed." << endl;
printError(); printError();
...@@ -1066,39 +1067,11 @@ CommandInterpreter::executeShutdown(char* parameters) ...@@ -1066,39 +1067,11 @@ CommandInterpreter::executeShutdown(char* parameters)
ndbout << result << " NDB Cluster node(s) have shutdown." << endl; ndbout << result << " NDB Cluster node(s) have shutdown." << endl;
int nodeId= 0; if(need_disconnect) {
int this_mgmd= 0;
this_mgmd= ndb_mgm_get_mgmd_nodeid(m_mgmsrv);
while(get_next_nodeid(state, &nodeId, NDB_MGM_NODE_TYPE_MGM))
{
if(nodeId==this_mgmd)
continue;
ndbout << "Shutting down NDB Cluster management server nodeId="
<< nodeId << "...";
result = ndb_mgm_stop(m_mgmsrv, 1, &nodeId);
if (result <= 0) {
ndbout << " failed." << endl;
printError();
}
else
ndbout << "Done." << endl;
}
ndbout << "Shutting down NDB Cluster management server nodeId="
<< this_mgmd << "...";
result= ndb_mgm_stop(m_mgmsrv, 1, &this_mgmd);
if (result <= 0) {
ndbout << " failed." << endl;
printError();
}
else
{
ndbout << "Done." << endl;
ndbout << "Disconnecting to allow management server to shutdown." ndbout << "Disconnecting to allow management server to shutdown."
<< endl; << endl;
disconnect(); disconnect();
} }
ndbout << "NDB Cluster management servers shutdown." << endl;
return 0; return 0;
} }
...@@ -1487,6 +1460,7 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list, ...@@ -1487,6 +1460,7 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
unsigned command_pos, unsigned command_pos,
int *node_ids, int no_of_nodes) int *node_ids, int no_of_nodes)
{ {
int need_disconnect;
int abort= 0; int abort= 0;
for (; command_pos < command_list.size(); command_pos++) for (; command_pos < command_list.size(); command_pos++)
{ {
...@@ -1501,7 +1475,8 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list, ...@@ -1501,7 +1475,8 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
return; return;
} }
int result= ndb_mgm_stop2(m_mgmsrv, no_of_nodes, node_ids, abort); int result= ndb_mgm_stop3(m_mgmsrv, no_of_nodes, node_ids, abort,
&need_disconnect);
if (result < 0) if (result < 0)
{ {
ndbout_c("Shutdown failed."); ndbout_c("Shutdown failed.");
...@@ -1513,27 +1488,19 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list, ...@@ -1513,27 +1488,19 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
ndbout_c("NDB Cluster has shutdown."); ndbout_c("NDB Cluster has shutdown.");
else else
{ {
int mgm_id= 0;
int need_reconnect= 0;
mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv);
ndbout << "Node"; ndbout << "Node";
for (int i= 0; i < no_of_nodes; i++) for (int i= 0; i < no_of_nodes; i++)
{
if(node_ids[i] == mgm_id)
need_reconnect= 1;
else
ndbout << " " << node_ids[i]; ndbout << " " << node_ids[i];
}
ndbout_c(" has shutdown."); ndbout_c(" has shutdown.");
if(need_reconnect)
{
ndbout << "You are connected to node " << mgm_id
<< ", disconnecting to allow it to shutdown"
<< endl;
disconnect();
}
} }
} }
if(need_disconnect)
{
ndbout << "Disconnecting to allow Management Server to shutdown" << endl;
disconnect();
}
} }
void void
...@@ -1624,6 +1591,7 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, ...@@ -1624,6 +1591,7 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
int nostart= 0; int nostart= 0;
int initialstart= 0; int initialstart= 0;
int abort= 0; int abort= 0;
int need_disconnect= 0;
for (; command_pos < command_list.size(); command_pos++) for (; command_pos < command_list.size(); command_pos++)
{ {
...@@ -1648,9 +1616,9 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, ...@@ -1648,9 +1616,9 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
return; return;
} }
result= ndb_mgm_restart2(m_mgmsrv, no_of_nodes, node_ids, result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids,
initialstart, nostart, abort); initialstart, nostart, abort, &need_disconnect);
if (result <= 0) { if (result <= 0) {
ndbout_c("Restart failed."); ndbout_c("Restart failed.");
printError(); printError();
...@@ -1661,18 +1629,13 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, ...@@ -1661,18 +1629,13 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
ndbout_c("NDB Cluster is being restarted."); ndbout_c("NDB Cluster is being restarted.");
else else
{ {
int mgm_id= 0;
mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv);
ndbout << "Node"; ndbout << "Node";
for (int i= 0; i < no_of_nodes; i++) for (int i= 0; i < no_of_nodes; i++)
{
if(node_ids[i] == mgm_id)
disconnect();
ndbout << " " << node_ids[i]; ndbout << " " << node_ids[i];
}
ndbout_c(" is being restarted"); ndbout_c(" is being restarted");
} }
if(need_disconnect)
disconnect();
} }
} }
......
...@@ -1196,6 +1196,27 @@ int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids, ...@@ -1196,6 +1196,27 @@ int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids,
return ret; return ret;
} }
int MgmtSrvr::shutdownMGM(int *stopCount, bool abort, int *stopSelf)
{
NodeId nodeId = 0;
int error;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM))
{
if(nodeId==getOwnNodeId())
continue;
error= sendStopMgmd(nodeId, abort, true, false,
false, false);
if (error == 0)
*stopCount++;
}
*stopSelf= 1;
*stopCount++;
return 0;
}
/* /*
* Perform DB nodes shutdown. * Perform DB nodes shutdown.
* MGM servers are left in their current state * MGM servers are left in their current state
......
...@@ -256,6 +256,8 @@ public: ...@@ -256,6 +256,8 @@ public:
int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort, int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort,
int *stopSelf); int *stopSelf);
int shutdownMGM(int *stopCount, bool abort, int *stopSelf);
/** /**
* shutdown the DB nodes * shutdown the DB nodes
*/ */
......
...@@ -145,7 +145,13 @@ ParserRow<MgmApiSession> commands[] = { ...@@ -145,7 +145,13 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""), MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""),
MGM_CMD("restart node", &MgmApiSession::restart, ""), MGM_CMD("restart node", &MgmApiSession::restart_v1, ""),
MGM_ARG("node", String, Mandatory, "Nodes to restart"),
MGM_ARG("initialstart", Int, Optional, "Initial start"),
MGM_ARG("nostart", Int, Optional, "No start"),
MGM_ARG("abort", Int, Optional, "Abort"),
MGM_CMD("restart node v2", &MgmApiSession::restart_v2, ""),
MGM_ARG("node", String, Mandatory, "Nodes to restart"), MGM_ARG("node", String, Mandatory, "Nodes to restart"),
MGM_ARG("initialstart", Int, Optional, "Initial start"), MGM_ARG("initialstart", Int, Optional, "Initial start"),
MGM_ARG("nostart", Int, Optional, "No start"), MGM_ARG("nostart", Int, Optional, "No start"),
...@@ -186,13 +192,21 @@ ParserRow<MgmApiSession> commands[] = { ...@@ -186,13 +192,21 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""), MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""),
MGM_ARG("id", Int, Mandatory, "Backup id"), MGM_ARG("id", Int, Mandatory, "Backup id"),
MGM_CMD("stop", &MgmApiSession::stop, ""), MGM_CMD("stop", &MgmApiSession::stop_v1, ""),
MGM_ARG("node", String, Mandatory, "Node"), MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("abort", Int, Mandatory, "Node"), MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_CMD("stop all", &MgmApiSession::stopAll, ""), MGM_CMD("stop v2", &MgmApiSession::stop_v2, ""),
MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("abort", Int, Mandatory, "Node"), MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_CMD("stop all", &MgmApiSession::stopAll_v1, ""),
MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_CMD("stop all v2", &MgmApiSession::stopAll_v2, ""),
MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_ARG("stop", String, Mandatory, "MGM/DB or both"),
MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""), MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""),
MGM_ARG("nodeId", Int, Mandatory, "Node"), MGM_ARG("nodeId", Int, Mandatory, "Node"),
...@@ -850,8 +864,19 @@ MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &, ...@@ -850,8 +864,19 @@ MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &,
} }
void void
MgmApiSession::restart(Parser<MgmApiSession>::Context &, MgmApiSession::restart_v1(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
restart(args,1);
}
void
MgmApiSession::restart_v2(Parser<MgmApiSession>::Context &,
Properties const &args) {
restart(args,2);
}
void
MgmApiSession::restart(Properties const &args, int version) {
Uint32 Uint32
nostart = 0, nostart = 0,
initialstart = 0, initialstart = 0,
...@@ -885,6 +910,8 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &, ...@@ -885,6 +910,8 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &,
} else } else
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("restarted: %d", restarted); m_output->println("restarted: %d", restarted);
if(version>1)
m_output->println("disconnect: %d", (m_stopSelf)?1:0);
m_output->println(""); m_output->println("");
} }
...@@ -994,8 +1021,19 @@ MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &, ...@@ -994,8 +1021,19 @@ MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &,
} }
void void
MgmApiSession::stop(Parser<MgmApiSession>::Context &, MgmApiSession::stop_v1(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
stop(args,1);
}
void
MgmApiSession::stop_v2(Parser<MgmApiSession>::Context &,
Properties const &args) {
stop(args,2);
}
void
MgmApiSession::stop(Properties const &args, int version) {
Uint32 abort; Uint32 abort;
char *nodes_str; char *nodes_str;
Vector<NodeId> nodes; Vector<NodeId> nodes;
...@@ -1028,25 +1066,46 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &, ...@@ -1028,25 +1066,46 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
else else
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("stopped: %d", stopped); m_output->println("stopped: %d", stopped);
if(version>1)
m_output->println("disconnect: %d", (m_stopSelf)?1:0);
m_output->println(""); m_output->println("");
} }
void void
MgmApiSession::stopAll(Parser<MgmApiSession>::Context &, MgmApiSession::stopAll_v1(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
int stopped = 0; stopAll(args,"db",1);
}
void
MgmApiSession::stopAll_v2(Parser<MgmApiSession>::Context &,
Properties const &args) {
BaseString tostop;
args.get("stop", tostop);
stopAll(args, tostop.c_str(), 2);
}
void
MgmApiSession::stopAll(Properties const &args, const char* tostop, int ver) {
int stopped[2] = {0,0};
Uint32 abort; Uint32 abort;
args.get("abort", &abort); args.get("abort", &abort);
int result = m_mgmsrv.shutdownDB(&stopped, abort != 0); int result= 0;
if(strstr(tostop,"db"))
result= m_mgmsrv.shutdownDB(&stopped[0], abort != 0);
if(strstr(tostop,"mgm"))
result= m_mgmsrv.shutdownMGM(&stopped[1], abort!=0, &m_stopSelf);
m_output->println("stop reply"); m_output->println("stop reply");
if(result != 0) if(result != 0)
m_output->println("result: %s", get_error_text(result)); m_output->println("result: %s", get_error_text(result));
else else
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("stopped: %d", stopped); m_output->println("stopped: %d", stopped[0]+stopped[1]);
if(ver >1)
m_output->println("disconnect: %d", (m_stopSelf)?1:0);
m_output->println(""); m_output->println("");
} }
......
...@@ -63,7 +63,9 @@ public: ...@@ -63,7 +63,9 @@ public:
void getVersion(Parser_t::Context &ctx, const class Properties &args); void getVersion(Parser_t::Context &ctx, const class Properties &args);
void getStatus(Parser_t::Context &ctx, const class Properties &args); void getStatus(Parser_t::Context &ctx, const class Properties &args);
void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args); void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args);
void restart(Parser_t::Context &ctx, const class Properties &args); void restart(const class Properties &args, int version);
void restart_v1(Parser_t::Context &ctx, const class Properties &args);
void restart_v2(Parser_t::Context &ctx, const class Properties &args);
void restartAll(Parser_t::Context &ctx, const class Properties &args); void restartAll(Parser_t::Context &ctx, const class Properties &args);
void insertError(Parser_t::Context &ctx, const class Properties &args); void insertError(Parser_t::Context &ctx, const class Properties &args);
void setTrace(Parser_t::Context &ctx, const class Properties &args); void setTrace(Parser_t::Context &ctx, const class Properties &args);
...@@ -75,8 +77,12 @@ public: ...@@ -75,8 +77,12 @@ public:
void abortBackup(Parser_t::Context &ctx, const class Properties &args); void abortBackup(Parser_t::Context &ctx, const class Properties &args);
void enterSingleUser(Parser_t::Context &ctx, const class Properties &args); void enterSingleUser(Parser_t::Context &ctx, const class Properties &args);
void exitSingleUser(Parser_t::Context &ctx, const class Properties &args); void exitSingleUser(Parser_t::Context &ctx, const class Properties &args);
void stop(Parser_t::Context &ctx, const class Properties &args); void stop_v1(Parser_t::Context &ctx, const class Properties &args);
void stopAll(Parser_t::Context &ctx, const class Properties &args); void stop_v2(Parser_t::Context &ctx, const class Properties &args);
void stop(const class Properties &args, int version);
void stopAll_v1(Parser_t::Context &ctx, const class Properties &args);
void stopAll_v2(Parser_t::Context &ctx, const class Properties &args);
void stopAll(Properties const &args, const char* tostop, int ver);
void start(Parser_t::Context &ctx, const class Properties &args); void start(Parser_t::Context &ctx, const class Properties &args);
void startAll(Parser_t::Context &ctx, const class Properties &args); void startAll(Parser_t::Context &ctx, const class Properties &args);
void bye(Parser_t::Context &ctx, const class Properties &args); void bye(Parser_t::Context &ctx, const class Properties &args);
......
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