Commit 878ce564 authored by jonas@perch.ndb.mysql.com's avatar jonas@perch.ndb.mysql.com

Merge perch.ndb.mysql.com:/home/jonas/src/50-jonas

into  perch.ndb.mysql.com:/home/jonas/src/51-work
parents 327adcf4 2d284fe0
......@@ -1380,35 +1380,6 @@ mysql_get_server_info(MYSQL *mysql)
}
/*
Get version number for server in a form easy to test on
SYNOPSIS
mysql_get_server_version()
mysql Connection
EXAMPLE
4.1.0-alfa -> 40100
NOTES
We will ensure that a newer server always has a bigger number.
RETURN
Signed number > 323000
*/
ulong STDCALL
mysql_get_server_version(MYSQL *mysql)
{
uint major, minor, version;
char *pos= mysql->server_version, *end_pos;
major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
version= (uint) strtoul(pos, &end_pos, 10);
return (ulong) major*10000L+(ulong) (minor*100+version);
}
const char * STDCALL
mysql_get_host_info(MYSQL *mysql)
{
......
......@@ -2817,6 +2817,36 @@ const char * STDCALL mysql_error(MYSQL *mysql)
return mysql->net.last_error;
}
/*
Get version number for server in a form easy to test on
SYNOPSIS
mysql_get_server_version()
mysql Connection
EXAMPLE
4.1.0-alfa -> 40100
NOTES
We will ensure that a newer server always has a bigger number.
RETURN
Signed number > 323000
*/
ulong STDCALL
mysql_get_server_version(MYSQL *mysql)
{
uint major, minor, version;
char *pos= mysql->server_version, *end_pos;
major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
version= (uint) strtoul(pos, &end_pos, 10);
return (ulong) major*10000L+(ulong) (minor*100+version);
}
/*
mysql_set_character_set function sends SET NAMES cs_name to
the server (which changes character_set_client, character_set_result
......@@ -2836,6 +2866,9 @@ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
{
char buff[MY_CS_NAME_SIZE + 10];
charsets_dir= save_csdir;
/* Skip execution of "SET NAMES" for pre-4.1 servers */
if (mysql_get_server_version(mysql) < 40100)
return 0;
sprintf(buff, "SET NAMES %s", cs_name);
if (!mysql_real_query(mysql, buff, strlen(buff)))
{
......
......@@ -92,7 +92,7 @@ class StopRef
friend class Ndbcntr;
public:
STATIC_CONST( SignalLength = 2 );
STATIC_CONST( SignalLength = 3 );
enum ErrorCode {
OK = 0,
......@@ -107,6 +107,7 @@ public:
public:
Uint32 senderData;
Uint32 errorCode;
Uint32 masterNodeId;
};
inline
......
......@@ -2165,6 +2165,7 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
else
ref->errorCode = StopRef::NodeShutdownInProgress;
ref->senderData = senderData;
ref->masterNodeId = cmasterNodeId;
if (senderRef != RNIL)
sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
......@@ -2176,6 +2177,7 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
jam();
ref->errorCode = StopRef::UnsupportedNodeShutdown;
ref->senderData = senderData;
ref->masterNodeId = cmasterNodeId;
if (senderRef != RNIL)
sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
return;
......@@ -2186,6 +2188,7 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
jam();
ref->errorCode = StopRef::MultiNodeShutdownNotMaster;
ref->senderData = senderData;
ref->masterNodeId = cmasterNodeId;
if (senderRef != RNIL)
sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
return;
......@@ -2329,6 +2332,7 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
ref->senderData = stopReq.senderData;
ref->errorCode = StopRef::NodeShutdownWouldCauseSystemCrash;
ref->masterNodeId = cntr.cmasterNodeId;
const BlockReference bref = stopReq.senderRef;
if (bref != RNIL)
......@@ -2477,6 +2481,7 @@ void Ndbcntr::execABORT_ALL_REF(Signal* signal){
StopRef * const stopRef = (StopRef *)&signal->theData[0];
stopRef->senderData = c_stopRec.stopReq.senderData;
stopRef->errorCode = StopRef::TransactionAbortFailed;
stopRef->masterNodeId = cmasterNodeId;
sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
}
......
......@@ -653,7 +653,6 @@ void Qmgr::execCM_REGREQ(Signal* signal)
jam();
c_start.m_president_candidate = addNodePtr.i;
c_start.m_president_candidate_gci = gci;
ndbout_c("assign candidate: %u %u", addNodePtr.i, gci);
}
sendCmRegrefLab(signal, Tblockref, CmRegRef::ZELECTION);
return;
......@@ -1106,7 +1105,6 @@ void Qmgr::execCM_REGREF(Signal* signal)
signal->theData[3] = 2;
c_start.m_president_candidate = candidate;
c_start.m_president_candidate_gci = candidate_gci;
ndbout_c("assign candidate: %u %u", candidate, candidate_gci);
} else {
signal->theData[3] = 4;
}//if
......@@ -1216,6 +1214,7 @@ Qmgr::check_startup(Signal* signal)
goto start_report;
}
}
{
const bool all = c_start.m_starting_nodes.equal(c_definedNodes);
CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
......@@ -1324,7 +1323,7 @@ Qmgr::check_startup(Signal* signal)
retVal = 1;
goto start_report;
}
}
ndbrequire(false);
start_report:
......@@ -1409,7 +1408,6 @@ void Qmgr::regreqTimeLimitLab(Signal* signal)
{
jam();
c_start.m_president_candidate = getOwnNodeId();
ndbout_c("Assigning candidate to self: %d", getOwnNodeId());
}
cmInfoconf010Lab(signal);
......
......@@ -18,6 +18,7 @@
#include <my_sys.h>
#include <Vector.hpp>
#include <mgmapi.h>
#include <util/BaseString.hpp>
class MgmtSrvr;
......@@ -63,6 +64,9 @@ private:
*/
void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr);
void executeCommand(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes);
/**
* Parse the block specification part of the LOG* commands,
* things after LOG*: [BLOCK = {ALL|<blockName>+}]
......@@ -97,10 +101,14 @@ private:
public:
void executeStop(int processId, const char* parameters, bool all);
void executeStop(Vector<BaseString> &command_list, unsigned command_pos,
int *node_ids, int no_of_nodes);
void executeEnterSingleUser(char* parameters);
void executeExitSingleUser(char* parameters);
void executeStart(int processId, const char* parameters, bool all);
void executeRestart(int processId, const char* parameters, bool all);
void executeRestart(Vector<BaseString> &command_list, unsigned command_pos,
int *node_ids, int no_of_nodes);
void executeLogLevel(int processId, const char* parameters, bool all);
void executeError(int processId, const char* parameters, bool all);
void executeLog(int processId, const char* parameters, bool all);
......@@ -583,6 +591,13 @@ CommandInterpreter::execute_impl(const char *_line)
}
} while (do_continue);
// if there is anything in the line proceed
Vector<BaseString> command_list;
{
BaseString tmp(line);
tmp.split(command_list);
for (unsigned i= 0; i < command_list.size();)
command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
}
char* firstToken = strtok(line, " ");
char* allAfterFirstToken = strtok(NULL, "");
......@@ -656,22 +671,45 @@ CommandInterpreter::execute_impl(const char *_line)
analyseAfterFirstToken(-1, allAfterFirstToken);
} else {
/**
* First token should be a digit, node ID
* First tokens should be digits, node ID's
*/
int nodeId;
if (! convert(firstToken, nodeId)) {
int node_ids[MAX_NODES];
unsigned pos;
for (pos= 0; pos < command_list.size(); pos++)
{
int node_id;
if (convert(command_list[pos].c_str(), node_id))
{
if (node_id <= 0) {
ndbout << "Invalid node ID: " << command_list[pos].c_str()
<< "." << endl;
DBUG_RETURN(true);
}
node_ids[pos]= node_id;
continue;
}
break;
}
int no_of_nodes= pos;
if (no_of_nodes == 0)
{
/* No digit found */
invalid_command(_line);
DBUG_RETURN(true);
}
if (nodeId <= 0) {
ndbout << "Invalid node ID: " << firstToken << "." << endl;
if (pos == command_list.size())
{
/* No command found */
invalid_command(_line);
DBUG_RETURN(true);
}
analyseAfterFirstToken(nodeId, allAfterFirstToken);
if (no_of_nodes == 1)
{
analyseAfterFirstToken(node_ids[0], allAfterFirstToken);
DBUG_RETURN(true);
}
executeCommand(command_list, pos, node_ids, no_of_nodes);
DBUG_RETURN(true);
}
DBUG_RETURN(true);
}
......@@ -741,6 +779,27 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
ndbout << endl;
}
void
CommandInterpreter::executeCommand(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes)
{
const char *cmd= command_list[command_pos].c_str();
if (strcasecmp("STOP", cmd) == 0)
{
executeStop(command_list, command_pos+1, node_ids, no_of_nodes);
return;
}
if (strcasecmp("RESTART", cmd) == 0)
{
executeRestart(command_list, command_pos+1, node_ids, no_of_nodes);
return;
}
ndbout_c("Invalid command: '%s' after multi node id list. "
"Expected STOP or RESTART.", cmd);
return;
}
/**
* Get next nodeid larger than the give node_id. node_id will be
* set to the next node_id in the list. node_id should be set
......@@ -1326,23 +1385,59 @@ CommandInterpreter::executeClusterLog(char* parameters)
//*****************************************************************************
void
CommandInterpreter::executeStop(int processId, const char *, bool all)
CommandInterpreter::executeStop(int processId, const char *parameters,
bool all)
{
int result = 0;
if(all) {
result = ndb_mgm_stop(m_mgmsrv, 0, 0);
} else {
result = ndb_mgm_stop(m_mgmsrv, 1, &processId);
Vector<BaseString> command_list;
if (parameters)
{
BaseString tmp(parameters);
tmp.split(command_list);
for (unsigned i= 0; i < command_list.size();)
command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
}
if (result < 0) {
ndbout << "Shutdown failed." << endl;
if (all)
executeStop(command_list, 0, 0, 0);
else
executeStop(command_list, 0, &processId, 1);
}
void
CommandInterpreter::executeStop(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes)
{
int abort= 0;
for (; command_pos < command_list.size(); command_pos++)
{
const char *item= command_list[command_pos].c_str();
if (strcasecmp(item, "-A") == 0)
{
abort= 1;
continue;
}
ndbout_c("Invalid option: %s. Expecting -A after STOP",
item);
return;
}
int result= ndb_mgm_stop2(m_mgmsrv, no_of_nodes, node_ids, abort);
if (result < 0)
{
ndbout_c("Shutdown failed.");
printError();
} else
}
else
{
if(all)
ndbout << "NDB Cluster has shutdown." << endl;
if (node_ids == 0)
ndbout_c("NDB Cluster has shutdown.");
else
ndbout << "Node " << processId << " has shutdown." << endl;
{
ndbout << "Node";
for (int i= 0; i < no_of_nodes; i++)
ndbout << " " << node_ids[i];
ndbout_c(" has shutdown.");
}
}
}
......@@ -1410,45 +1505,72 @@ CommandInterpreter::executeStart(int processId, const char* parameters,
void
CommandInterpreter::executeRestart(int processId, const char* parameters,
bool all)
{
Vector<BaseString> command_list;
if (parameters)
{
BaseString tmp(parameters);
tmp.split(command_list);
for (unsigned i= 0; i < command_list.size();)
command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
}
if (all)
executeRestart(command_list, 0, 0, 0);
else
executeRestart(command_list, 0, &processId, 1);
}
void
CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
unsigned command_pos,
int *node_ids, int no_of_nodes)
{
int result;
int nostart = 0;
int initialstart = 0;
int abort = 0;
int nostart= 0;
int initialstart= 0;
int abort= 0;
if(parameters != 0 && strlen(parameters) != 0){
char * tmpString = my_strdup(parameters,MYF(MY_WME));
My_auto_ptr<char> ap1(tmpString);
char * tmpPtr = 0;
char * item = strtok_r(tmpString, " ", &tmpPtr);
while(item != NULL){
if(strcasecmp(item, "-N") == 0)
nostart = 1;
if(strcasecmp(item, "-I") == 0)
initialstart = 1;
if(strcasecmp(item, "-A") == 0)
abort = 1;
item = strtok_r(NULL, " ", &tmpPtr);
for (; command_pos < command_list.size(); command_pos++)
{
const char *item= command_list[command_pos].c_str();
if (strcasecmp(item, "-N") == 0)
{
nostart= 1;
continue;
}
if (strcasecmp(item, "-I") == 0)
{
initialstart= 1;
continue;
}
if(all) {
result = ndb_mgm_restart2(m_mgmsrv, 0, NULL, initialstart, nostart, abort);
} else {
int v[1];
v[0] = processId;
result = ndb_mgm_restart2(m_mgmsrv, 1, v, initialstart, nostart, abort);
if (strcasecmp(item, "-A") == 0)
{
abort= 1;
continue;
}
ndbout_c("Invalid option: %s. Expecting -A,-N or -I after RESTART",
item);
return;
}
result= ndb_mgm_restart2(m_mgmsrv, no_of_nodes, node_ids,
initialstart, nostart, abort);
if (result <= 0) {
ndbout.println("Restart failed.", result);
ndbout_c("Restart failed.");
printError();
} else
}
else
{
if(all)
ndbout << "NDB Cluster is being restarted." << endl;
if (node_ids == 0)
ndbout_c("NDB Cluster is being restarted.");
else
ndbout_c("Node %d is being restarted.", processId);
{
ndbout << "Node";
for (int i= 0; i < no_of_nodes; i++)
ndbout << " " << node_ids[i];
ndbout_c(" is being restarted");
}
}
}
......
This diff is collapsed.
......@@ -176,6 +176,7 @@ public:
STATIC_CONST( NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH = 5028 );
STATIC_CONST( NO_CONTACT_WITH_DB_NODES = 5030 );
STATIC_CONST( UNSUPPORTED_NODE_SHUTDOWN = 5031 );
STATIC_CONST( NODE_NOT_API_NODE = 5062 );
STATIC_CONST( OPERATION_NOT_ALLOWED_START_STOP = 5063 );
......@@ -252,7 +253,7 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
int stopNode(int nodeId, bool abort = false);
int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort);
/**
* Stop the system
......@@ -286,11 +287,12 @@ public:
int start(int processId);
/**
* Restart a node
* Restart nodes
* @param processId: Id of the DB process to start
*/
int restartNode(int processId, bool nostart, bool initialStart,
bool abort = false);
int restartNodes(const Vector<NodeId> &node_ids,
int *stopCount, bool nostart,
bool initialStart, bool abort);
/**
* Restart the system
......@@ -489,7 +491,7 @@ private:
bool nostart,
bool initialStart);
int sendSTOP_REQ(NodeId nodeId,
int sendSTOP_REQ(const Vector<NodeId> &node_ids,
NodeBitmask &stoppedNodes,
Uint32 singleUserNodeId,
bool abort,
......@@ -649,6 +651,8 @@ private:
friend class Ndb_mgmd_event_service;
Ndb_mgmd_event_service m_event_listner;
NodeId m_master_node;
/**
* Handles the thread wich upon a 'Node is started' event will
* set the node's previous loglevel settings.
......
......@@ -866,14 +866,11 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &,
}
int restarted = 0;
int result = 0;
for(size_t i = 0; i < nodes.size(); i++)
if((result = m_mgmsrv.restartNode(nodes[i],
int result= m_mgmsrv.restartNodes(nodes,
&restarted,
nostart != 0,
initialstart != 0,
abort != 0)) == 0)
restarted++;
abort != 0);
m_output->println("restart reply");
if(result != 0){
......@@ -998,7 +995,12 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
args.get("node", (const char **)&nodes_str);
if(nodes_str == NULL)
{
m_output->println("stop reply");
m_output->println("result: empty node list");
m_output->println("");
return;
}
args.get("abort", &abort);
char *p, *last;
......@@ -1008,29 +1010,10 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
nodes.push_back(atoi(p));
}
int stop_self= 0;
size_t i;
for(i=0; i < nodes.size(); i++) {
if (nodes[i] == m_mgmsrv.getOwnNodeId()) {
stop_self= 1;
if (i != nodes.size()-1) {
m_output->println("stop reply");
m_output->println("result: server must be stopped last");
m_output->println("");
return;
}
}
}
int stopped = 0, result = 0;
for(i=0; i < nodes.size(); i++)
if (nodes[i] != m_mgmsrv.getOwnNodeId()) {
if((result = m_mgmsrv.stopNode(nodes[i], abort != 0)) == 0)
stopped++;
} else
stopped++;
int stopped= 0;
int result= 0;
if (nodes.size())
result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0);
m_output->println("stop reply");
if(result != 0)
......@@ -1039,9 +1022,6 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
m_output->println("result: Ok");
m_output->println("stopped: %d", stopped);
m_output->println("");
if (stop_self)
g_StopServer= true;
}
......
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