From ea16e525b57c1b8b9d9d53ca0b291b42567beba6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Apr 2006 02:10:08 +1000 Subject: [PATCH 01/14] BUG#18966 Change in stop/shutdown behaviour fix behaviour of ALL STOP and SHUTDOWN in relation to MGM nodes ndb/src/mgmclient/CommandInterpreter.cpp: Shutdown management servers properly (one we're connected to last). Fix potential problems if disconnect from one mgmd and connect to another (that's a different cluster) ndb/src/mgmsrv/MgmtSrvr.cpp: fix regression in how nodes are stopped ALL STOP - db nodes only SHUTDOWN - db and mgm nodes fix race where mgmd could stop itself before it sends the response to stop. In ~MgmApiSession() we now do the disconnect. We have (in various places) a return stopSelf which tells the caller if they need to stop or restart this daemon. ndb/src/mgmsrv/MgmtSrvr.hpp: add stopSelf return parameter to stopNodes and restartNodes. Rename stop to shutdownDB as this name better reflects what it does Rename restart to restartDB as this name better reflects what it does ndb/src/mgmsrv/Services.cpp: Stop or restart server only on mgm session disconnect (of session that asked us to) ndb/src/mgmsrv/Services.hpp: add m_stopSelf member for tracking what we should do --- ndb/src/mgmclient/CommandInterpreter.cpp | 250 +++++++++++++---------- ndb/src/mgmsrv/MgmtSrvr.cpp | 73 ++++--- ndb/src/mgmsrv/MgmtSrvr.hpp | 20 +- ndb/src/mgmsrv/Services.cpp | 15 +- ndb/src/mgmsrv/Services.hpp | 1 + 5 files changed, 205 insertions(+), 154 deletions(-) diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 39c84fd8055..0fdb81989b3 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -162,6 +162,7 @@ private: NdbMgmHandle m_mgmsrv; NdbMgmHandle m_mgmsrv2; + const char *m_constr; bool m_connected; int m_verbose; int try_reconnect; @@ -390,22 +391,7 @@ convert(const char* s, int& val) { CommandInterpreter::CommandInterpreter(const char *_host,int verbose) : m_verbose(verbose) { - m_mgmsrv = ndb_mgm_create_handle(); - if(m_mgmsrv == NULL) { - ndbout_c("Cannot create handle to management server."); - exit(-1); - } - m_mgmsrv2 = ndb_mgm_create_handle(); - if(m_mgmsrv2 == NULL) { - ndbout_c("Cannot create 2:nd handle to management server."); - exit(-1); - } - if (ndb_mgm_set_connectstring(m_mgmsrv, _host)) - { - printError(); - exit(-1); - } - + m_constr= _host; m_connected= false; m_event_thread= 0; try_reconnect = 0; @@ -422,8 +408,6 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose) CommandInterpreter::~CommandInterpreter() { disconnect(); - ndb_mgm_destroy_handle(&m_mgmsrv); - ndb_mgm_destroy_handle(&m_mgmsrv2); } static bool @@ -447,7 +431,6 @@ CommandInterpreter::printError() { if (ndb_mgm_check_connection(m_mgmsrv)) { - m_connected= false; disconnect(); } ndbout_c("* %5d: %s", @@ -497,78 +480,97 @@ event_thread_run(void* m) } bool -CommandInterpreter::connect() +CommandInterpreter::connect() { DBUG_ENTER("CommandInterpreter::connect"); - if(!m_connected) + + if(m_connected) + DBUG_RETURN(m_connected); + + m_mgmsrv = ndb_mgm_create_handle(); + if(m_mgmsrv == NULL) { + ndbout_c("Cannot create handle to management server."); + exit(-1); + } + m_mgmsrv2 = ndb_mgm_create_handle(); + if(m_mgmsrv2 == NULL) { + ndbout_c("Cannot create 2:nd handle to management server."); + exit(-1); + } + + if (ndb_mgm_set_connectstring(m_mgmsrv, m_constr)) { - if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1)) + printError(); + exit(-1); + } + + if(ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1)) + DBUG_RETURN(m_connected); // couldn't connect, always false + + const char *host= ndb_mgm_get_connected_host(m_mgmsrv); + unsigned port= ndb_mgm_get_connected_port(m_mgmsrv); + BaseString constr; + constr.assfmt("%s:%d",host,port); + if(!ndb_mgm_set_connectstring(m_mgmsrv2, constr.c_str()) && + !ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1)) + { + DBUG_PRINT("info",("2:ndb connected to Management Server ok at: %s:%d", + host, port)); + assert(m_event_thread == 0); + assert(do_event_thread == 0); + do_event_thread= 0; + m_event_thread = NdbThread_Create(event_thread_run, + (void**)&m_mgmsrv2, + 32768, + "CommandInterpreted_event_thread", + NDB_THREAD_PRIO_LOW); + if (m_event_thread != 0) { - const char *host= ndb_mgm_get_connected_host(m_mgmsrv); - unsigned port= ndb_mgm_get_connected_port(m_mgmsrv); - BaseString constr; - constr.assfmt("%s:%d",host,port); - if(!ndb_mgm_set_connectstring(m_mgmsrv2, constr.c_str()) && - !ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1)) + DBUG_PRINT("info",("Thread created ok, waiting for started...")); + int iter= 1000; // try for 30 seconds + while(do_event_thread == 0 && + iter-- > 0) + NdbSleep_MilliSleep(30); + } + if (m_event_thread == 0 || + do_event_thread == 0 || + do_event_thread == -1) + { + DBUG_PRINT("info",("Warning, event thread startup failed, " + "degraded printouts as result, errno=%d", + errno)); + printf("Warning, event thread startup failed, " + "degraded printouts as result, errno=%d\n", errno); + do_event_thread= 0; + if (m_event_thread) { - DBUG_PRINT("info",("2:ndb connected to Management Server ok at: %s:%d", - host, port)); - assert(m_event_thread == 0); - assert(do_event_thread == 0); - do_event_thread= 0; - m_event_thread = NdbThread_Create(event_thread_run, - (void**)&m_mgmsrv2, - 32768, - "CommandInterpreted_event_thread", - NDB_THREAD_PRIO_LOW); - if (m_event_thread != 0) - { - DBUG_PRINT("info",("Thread created ok, waiting for started...")); - int iter= 1000; // try for 30 seconds - while(do_event_thread == 0 && - iter-- > 0) - NdbSleep_MilliSleep(30); - } - if (m_event_thread == 0 || - do_event_thread == 0 || - do_event_thread == -1) - { - DBUG_PRINT("info",("Warning, event thread startup failed, " - "degraded printouts as result, errno=%d", - errno)); - printf("Warning, event thread startup failed, " - "degraded printouts as result, errno=%d\n", errno); - do_event_thread= 0; - if (m_event_thread) - { - void *res; - NdbThread_WaitFor(m_event_thread, &res); - NdbThread_Destroy(&m_event_thread); - } - ndb_mgm_disconnect(m_mgmsrv2); - } - } - else - { - DBUG_PRINT("warning", - ("Could not do 2:nd connect to mgmtserver for event listening")); - DBUG_PRINT("info", ("code: %d, msg: %s", - ndb_mgm_get_latest_error(m_mgmsrv2), - ndb_mgm_get_latest_error_msg(m_mgmsrv2))); - printf("Warning, event connect failed, degraded printouts as result\n"); - printf("code: %d, msg: %s\n", - ndb_mgm_get_latest_error(m_mgmsrv2), - ndb_mgm_get_latest_error_msg(m_mgmsrv2)); - } - m_connected= true; - DBUG_PRINT("info",("Connected to Management Server at: %s:%d", host, port)); - if (m_verbose) - { - printf("Connected to Management Server at: %s:%d\n", - host, port); + void *res; + NdbThread_WaitFor(m_event_thread, &res); + NdbThread_Destroy(&m_event_thread); } + ndb_mgm_disconnect(m_mgmsrv2); } } + else + { + DBUG_PRINT("warning", + ("Could not do 2:nd connect to mgmtserver for event listening")); + DBUG_PRINT("info", ("code: %d, msg: %s", + ndb_mgm_get_latest_error(m_mgmsrv2), + ndb_mgm_get_latest_error_msg(m_mgmsrv2))); + printf("Warning, event connect failed, degraded printouts as result\n"); + printf("code: %d, msg: %s\n", + ndb_mgm_get_latest_error(m_mgmsrv2), + ndb_mgm_get_latest_error_msg(m_mgmsrv2)); + } + m_connected= true; + DBUG_PRINT("info",("Connected to Management Server at: %s:%d", host, port)); + if (m_verbose) + { + printf("Connected to Management Server at: %s:%d\n", + host, port); + } + DBUG_RETURN(m_connected); } @@ -576,20 +578,18 @@ bool CommandInterpreter::disconnect() { DBUG_ENTER("CommandInterpreter::disconnect"); + if (m_event_thread) { void *res; do_event_thread= 0; NdbThread_WaitFor(m_event_thread, &res); NdbThread_Destroy(&m_event_thread); m_event_thread= 0; - ndb_mgm_disconnect(m_mgmsrv2); + ndb_mgm_destroy_handle(&m_mgmsrv2); } if (m_connected) { - if (ndb_mgm_disconnect(m_mgmsrv) == -1) { - ndbout_c("Could not disconnect from management server"); - printError(); - } + ndb_mgm_destroy_handle(&m_mgmsrv); m_connected= false; } DBUG_RETURN(true); @@ -1066,28 +1066,39 @@ CommandInterpreter::executeShutdown(char* parameters) ndbout << result << " NDB Cluster node(s) have shutdown." << endl; - int mgm_id= 0; - mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); - if (mgm_id == 0) + int nodeId= 0; + int this_mgmd= 0; + this_mgmd= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); + while(get_next_nodeid(state, &nodeId, NDB_MGM_NODE_TYPE_MGM)) { - ndbout << "Unable to locate management server, " - << "shutdown manually with STOP" - << endl; - return 1; + 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; } - result = ndb_mgm_stop(m_mgmsrv, 1, &mgm_id); + ndbout << "Shutting down NDB Cluster management server nodeId=" + << this_mgmd << "..."; + result= ndb_mgm_stop(m_mgmsrv, 1, &this_mgmd); if (result <= 0) { - ndbout << "Shutdown of NDB Cluster management server failed." << endl; + ndbout << " failed." << endl; printError(); - if (result == 0) - return 1; - return result; } - - m_connected= false; - disconnect(); - ndbout << "NDB Cluster management server shutdown." << endl; + else + { + ndbout << "Done." << endl; + ndbout << "Disconnecting to allow management server to shutdown." + << endl; + disconnect(); + } + ndbout << "NDB Cluster management servers shutdown." << endl; return 0; } @@ -1311,12 +1322,7 @@ CommandInterpreter::executeConnect(char* parameters) { disconnect(); if (!emptyString(parameters)) { - if (ndb_mgm_set_connectstring(m_mgmsrv, - BaseString(parameters).trim().c_str())) - { - printError(); - return; - } + m_constr= BaseString(parameters).trim().c_str(); } connect(); } @@ -1507,10 +1513,25 @@ CommandInterpreter::executeStop(Vector &command_list, ndbout_c("NDB Cluster has shutdown."); else { + int mgm_id= 0; + int need_reconnect= 0; + mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); ndbout << "Node"; for (int i= 0; i < no_of_nodes; i++) - ndbout << " " << node_ids[i]; + { + if(node_ids[i] == mgm_id) + need_reconnect= 1; + else + ndbout << " " << node_ids[i]; + } ndbout_c(" has shutdown."); + if(need_reconnect) + { + ndbout << "You are connected to node " << mgm_id + << ", disconnecting to allow it to shutdown" + << endl; + disconnect(); + } } } } @@ -1640,9 +1661,16 @@ CommandInterpreter::executeRestart(Vector &command_list, ndbout_c("NDB Cluster is being restarted."); else { + int mgm_id= 0; + mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); + ndbout << "Node"; for (int i= 0; i < no_of_nodes; i++) + { + if(node_ids[i] == mgm_id) + disconnect(); ndbout << " " << node_ids[i]; + } ndbout_c(" is being restarted"); } } diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 9b518ba938b..4c3631488e6 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -60,9 +60,6 @@ #include -extern bool g_StopServer; -extern bool g_RestartServer; - //#define MGM_SRV_DEBUG #ifdef MGM_SRV_DEBUG #define DEBUG(x) do ndbout << x << endl; while(0) @@ -932,6 +929,13 @@ int MgmtSrvr::sendStopMgmd(NodeId nodeId, * client connection to that mgmd and stop it that way. * This allows us to stop mgm servers when there isn't any real * distributed communication up. + * + * node_ids.size()==0 means to stop all DB nodes. + * MGM nodes will *NOT* be stopped. + * + * If we work out we should be stopping or restarting ourselves, + * we return <0 in stopSelf for restart, >0 for stop + * and 0 for do nothing. */ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, @@ -941,7 +945,8 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, bool stop, bool restart, bool nostart, - bool initialStart) + bool initialStart, + int* stopSelf) { int error = 0; DBUG_ENTER("MgmtSrvr::sendSTOP_REQ"); @@ -990,12 +995,13 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, NodeId nodeId= 0; int use_master_node= 0; int do_send= 0; - int do_stop_self= 0; + *stopSelf= 0; NdbNodeBitmask nodes_to_stop; { for (unsigned i= 0; i < node_ids.size(); i++) { nodeId= node_ids[i]; + ndbout << "asked to stop " << nodeId << endl; if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM) nodes_to_stop.set(nodeId); else if (nodeId != getOwnNodeId()) @@ -1006,7 +1012,11 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, stoppedNodes.set(nodeId); } else - do_stop_self= 1;; + { + ndbout << "which is me" << endl; + *stopSelf= (restart)? -1 : 1; + stoppedNodes.set(nodeId); + } } } int no_of_nodes_to_stop= nodes_to_stop.count(); @@ -1039,14 +1049,6 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, nodes.set(nodeId); } } - nodeId= 0; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)) - { - if(nodeId==getOwnNodeId()) - continue; - if(sendStopMgmd(nodeId, abort, stop, restart, nostart, initialStart)==0) - stoppedNodes.set(nodeId); - } } // now wait for the replies @@ -1153,11 +1155,9 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, DBUG_RETURN(SEND_OR_RECEIVE_FAILED); } } - if (!error && do_stop_self) + if (error && *stopSelf) { - if (restart) - g_RestartServer= true; - g_StopServer= true; + *stopSelf= 0; } DBUG_RETURN(error); } @@ -1167,7 +1167,7 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids, */ int MgmtSrvr::stopNodes(const Vector &node_ids, - int *stopCount, bool abort) + int *stopCount, bool abort, int* stopSelf) { if (!abort) { @@ -1189,20 +1189,25 @@ int MgmtSrvr::stopNodes(const Vector &node_ids, false, false, false, - false); + false, + stopSelf); if (stopCount) *stopCount= nodes.count(); return ret; } /* - * Perform system shutdown + * Perform DB nodes shutdown. + * MGM servers are left in their current state */ -int MgmtSrvr::stop(int * stopCount, bool abort) +int MgmtSrvr::shutdownDB(int * stopCount, bool abort) { NodeBitmask nodes; Vector node_ids; + + int tmp; + int ret = sendSTOP_REQ(node_ids, nodes, 0, @@ -1210,7 +1215,8 @@ int MgmtSrvr::stop(int * stopCount, bool abort) true, false, false, - false); + false, + &tmp); if (stopCount) *stopCount = nodes.count(); return ret; @@ -1235,6 +1241,7 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) } NodeBitmask nodes; Vector node_ids; + int stopSelf; int ret = sendSTOP_REQ(node_ids, nodes, singleUserNodeId, @@ -1242,7 +1249,8 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) false, false, false, - false); + false, + &stopSelf); if (stopCount) *stopCount = nodes.count(); return ret; @@ -1254,7 +1262,8 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) int MgmtSrvr::restartNodes(const Vector &node_ids, int * stopCount, bool nostart, - bool initialStart, bool abort) + bool initialStart, bool abort, + int *stopSelf) { NodeBitmask nodes; int ret= sendSTOP_REQ(node_ids, @@ -1264,21 +1273,24 @@ int MgmtSrvr::restartNodes(const Vector &node_ids, false, true, nostart, - initialStart); + initialStart, + stopSelf); if (stopCount) *stopCount = nodes.count(); return ret; } /* - * Perform system restart + * Perform restart of all DB nodes */ -int MgmtSrvr::restart(bool nostart, bool initialStart, - bool abort, int * stopCount ) +int MgmtSrvr::restartDB(bool nostart, bool initialStart, + bool abort, int * stopCount) { NodeBitmask nodes; Vector node_ids; + int tmp; + int ret = sendSTOP_REQ(node_ids, nodes, 0, @@ -1286,7 +1298,8 @@ int MgmtSrvr::restart(bool nostart, bool initialStart, true, true, true, - initialStart); + initialStart, + &tmp); if (ret) return ret; diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index fe1603a1953..b47ee69fd9f 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -253,12 +253,13 @@ public: * @param processId: Id of the DB process to stop * @return 0 if succeeded, otherwise: as stated above, plus: */ - int stopNodes(const Vector &node_ids, int *stopCount, bool abort); + int stopNodes(const Vector &node_ids, int *stopCount, bool abort, + int *stopSelf); /** - * Stop the system + * shutdown the DB nodes */ - int stop(int * cnt = 0, bool abort = false); + int shutdownDB(int * cnt = 0, bool abort = false); /** * print version info about a node @@ -292,14 +293,14 @@ public: */ int restartNodes(const Vector &node_ids, int *stopCount, bool nostart, - bool initialStart, bool abort); + bool initialStart, bool abort, int *stopSelf); /** - * Restart the system + * Restart all DB nodes */ - int restart(bool nostart, bool initialStart, - bool abort = false, - int * stopCount = 0); + int restartDB(bool nostart, bool initialStart, + bool abort = false, + int * stopCount = 0); struct BackupEvent { enum Event { @@ -503,7 +504,8 @@ private: bool stop, bool restart, bool nostart, - bool initialStart); + bool initialStart, + int *stopSelf); /** * Check if it is possible to send a signal to a (DB) process diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index a80827abd8f..a6c483fcdcd 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -35,6 +35,7 @@ #include extern bool g_StopServer; +extern bool g_RestartServer; extern EventLogger g_eventLogger; static const unsigned int MAX_READ_TIMEOUT = 1000 ; @@ -267,6 +268,7 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock) m_output = new SocketOutputStream(sock); m_parser = new Parser_t(commands, *m_input, true, true, true); m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv); + m_stopSelf= 0; DBUG_VOID_RETURN; } @@ -286,6 +288,10 @@ MgmApiSession::~MgmApiSession() NDB_CLOSE_SOCKET(m_socket); m_socket= NDB_INVALID_SOCKET; } + if(m_stopSelf < 0) + g_RestartServer= true; + if(m_stopSelf) + g_StopServer= true; DBUG_VOID_RETURN; } @@ -870,7 +876,8 @@ MgmApiSession::restart(Parser::Context &, &restarted, nostart != 0, initialstart != 0, - abort != 0); + abort != 0, + &m_stopSelf); m_output->println("restart reply"); if(result != 0){ @@ -894,7 +901,7 @@ MgmApiSession::restartAll(Parser::Context &, args.get("nostart", &nostart); int count = 0; - int result = m_mgmsrv.restart(nostart, initialstart, abort, &count); + int result = m_mgmsrv.restartDB(nostart, initialstart, abort, &count); m_output->println("restart reply"); if(result != 0) @@ -1013,7 +1020,7 @@ MgmApiSession::stop(Parser::Context &, int stopped= 0; int result= 0; if (nodes.size()) - result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0); + result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0, &m_stopSelf); m_output->println("stop reply"); if(result != 0) @@ -1032,7 +1039,7 @@ MgmApiSession::stopAll(Parser::Context &, Uint32 abort; args.get("abort", &abort); - int result = m_mgmsrv.stop(&stopped, abort != 0); + int result = m_mgmsrv.shutdownDB(&stopped, abort != 0); m_output->println("stop reply"); if(result != 0) diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index f97223750a1..b8a73f5e4bc 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -40,6 +40,7 @@ private: Parser_t *m_parser; MgmtSrvr::Allocated_resources *m_allocated_resources; char m_err_str[1024]; + int m_stopSelf; // -1 is restart, 0 do nothing, 1 stop void getConfig_common(Parser_t::Context &ctx, const class Properties &args, From 564ba97b6244bd865ae82a4939e5a3badec104eb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 May 2006 21:32:24 +1000 Subject: [PATCH 02/14] BUG#18966 Change in stop/shutdown behaviour Now need this fix to prevent crash of ndb_mgm on invalid mgm protocol. ndb/src/mgmclient/CommandInterpreter.cpp: fix crash on invalid mgm protocol --- ndb/src/mgmclient/CommandInterpreter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 0fdb81989b3..9e1224ab3ef 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -429,14 +429,14 @@ emptyString(const char* s) void CommandInterpreter::printError() { - if (ndb_mgm_check_connection(m_mgmsrv)) - { - disconnect(); - } ndbout_c("* %5d: %s", ndb_mgm_get_latest_error(m_mgmsrv), ndb_mgm_get_latest_error_msg(m_mgmsrv)); ndbout_c("* %s", ndb_mgm_get_latest_error_desc(m_mgmsrv)); + if (ndb_mgm_check_connection(m_mgmsrv)) + { + disconnect(); + } } //***************************************************************************** From e94ce460dbf17817d85f38cd2ecaf8e721a75d07 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 23 May 2006 14:45:56 +1000 Subject: [PATCH 03/14] BUG#20016 error in mgm protocol parser error message incorrect fix display of mgm protocol parser error in mgmapi ndb/src/mgmapi/mgmapi.cpp: fix display of mgm protocol parser error. --- ndb/src/mgmapi/mgmapi.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 061360428af..b6c68962e4b 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -361,8 +361,9 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow *command_reply, * Print some info about why the parser returns NULL */ fprintf(handle->errstream, - "Error in mgm protocol parser. cmd: >%s< status: %d curr: %d\n", - cmd, (Uint32)ctx.m_status, ctx.m_currentToken); + "Error in mgm protocol parser. cmd: >%s< status: %d curr: %s\n", + cmd, (Uint32)ctx.m_status, + (ctx.m_currentToken)?ctx.m_currentToken:"NULL"); DBUG_PRINT("info",("ctx.status: %d, ctx.m_currentToken: %s", ctx.m_status, ctx.m_currentToken)); } From 466b548f15f28db0840cc9ad91f2c52a3b6f721f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 23 May 2006 14:51:04 +1000 Subject: [PATCH 04/14] BUG#19932 mgmapi crash if disconnect in ndb_mgm_get_status correctly detect and report errors in talking to mgm server and memory allocation ndb/src/mgmapi/mgmapi.cpp: correctly detect and return errors in ndb_mgm_get_status --- ndb/src/mgmapi/mgmapi.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 061360428af..70c492be8b1 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -678,7 +678,11 @@ ndb_mgm_get_status(NdbMgmHandle handle) out.println(""); char buf[1024]; - in.gets(buf, sizeof(buf)); + if(!in.gets(buf, sizeof(buf))) + { + SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected"); + return NULL; + } if(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; @@ -687,7 +691,11 @@ ndb_mgm_get_status(NdbMgmHandle handle) return NULL; } - in.gets(buf, sizeof(buf)); + if(!in.gets(buf, sizeof(buf))) + { + SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected"); + return NULL; + } if(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; @@ -710,6 +718,13 @@ ndb_mgm_get_status(NdbMgmHandle handle) malloc(sizeof(ndb_mgm_cluster_state)+ noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#"))); + if(!state) + { + SET_ERROR(handle, NDB_MGM_OUT_OF_MEMORY, + "Allocating ndb_mgm_cluster_state"); + return NULL; + } + state->no_of_nodes= noOfNodes; ndb_mgm_node_state * ptr = &state->node_states[0]; int nodeId = 0; @@ -719,7 +734,13 @@ ndb_mgm_get_status(NdbMgmHandle handle) } i = -1; ptr--; for(; i Date: Tue, 23 May 2006 16:24:26 +1000 Subject: [PATCH 05/14] 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 --- ndb/include/mgmapi/mgmapi.h | 57 +++++++ ndb/src/mgmapi/mgmapi.cpp | 196 ++++++++++++++++++++--- ndb/src/mgmclient/CommandInterpreter.cpp | 75 +++------ ndb/src/mgmsrv/MgmtSrvr.cpp | 21 +++ ndb/src/mgmsrv/MgmtSrvr.hpp | 2 + ndb/src/mgmsrv/Services.cpp | 81 ++++++++-- ndb/src/mgmsrv/Services.hpp | 12 +- 7 files changed, 352 insertions(+), 92 deletions(-) diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index c6c0fdebb65..798e09f0c2b 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -694,6 +694,28 @@ extern "C" { int ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, int abort); + /** + * Stops cluster nodes + * + * @param handle Management handle. + * @param no_of_nodes Number of database nodes to stop
+ * -1: All database and management nodes
+ * 0: All database nodes in cluster
+ * n: Stop the n 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 * @@ -733,6 +755,31 @@ extern "C" { const int * node_list, int initial, int nostart, int abort); + /** + * Restart nodes + * + * @param handle Management handle. + * @param no_of_nodes Number of database nodes to be restarted:
+ * 0: Restart all database nodes in the cluster
+ * n: Restart the n 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 * @@ -1023,6 +1070,16 @@ extern "C" { */ 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 */ diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index b02367a8870..3109cea7782 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -27,6 +27,7 @@ #include #include "mgmapi_configuration.hpp" #include +#include #include #include @@ -103,6 +104,9 @@ struct ndb_mgm_handle { #endif FILE *errstream; 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) @@ -168,6 +172,10 @@ ndb_mgm_create_handle() h->logfile = 0; #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_RETURN(h); } @@ -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); } - extern "C" -int +int ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, int abort) { - SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop2"); - const ParserRow stop_reply[] = { + int disconnect; + 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 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 stop_reply_v2[] = { + MGM_CMD("stop reply", NULL, ""), + MGM_ARG("stopped", Int, Optional, "No of stopped nodes"), + MGM_ARG("result", String, Mandatory, "Error message"), + MGM_ARG("disconnect", Int, Mandatory, "Need to disconnect"), + MGM_END() + }; + CHECK_HANDLE(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, "Negative number of nodes requested to stop"); return -1; } 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; args.put("abort", abort); + if(use_v2) + args.put("stop", (no_of_nodes==-1)?"mgm,db":"db"); 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); if(!reply->get("stopped", &stoppedNoOfNodes)){ @@ -865,6 +911,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, delete reply; return -1; } + if(use_v2) + reply->get("disconnect", (Uint32*)disconnect); + else + *disconnect= 0; BaseString result; reply->get("result", result); if(strcmp(result.c_str(), "Ok") != 0) { @@ -890,7 +940,11 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, args.put("abort", abort); 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); if(!reply->get("stopped", &stoppedNoOfNodes)){ SET_ERROR(handle, NDB_MGM_STOP_FAILED, @@ -898,6 +952,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, delete reply; return -1; } + if(use_v2) + reply->get("disconnect", (Uint32*)disconnect); + else + *disconnect= 0; BaseString result; reply->get("result", result); if(strcmp(result.c_str(), "Ok") != 0) { @@ -909,22 +967,65 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, 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" int ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, 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; - const ParserRow restart_reply[] = { + const ParserRow 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 restart_reply_v2[] = { + MGM_CMD("restart reply", NULL, ""), + MGM_ARG("result", String, Mandatory, "Error message"), + MGM_ARG("restarted", Int, Optional, "No of restarted nodes"), + MGM_ARG("disconnect", Int, Optional, "Disconnect to apply"), + MGM_END() + }; + CHECK_HANDLE(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){ SET_ERROR(handle, NDB_MGM_RESTART_FAILED, "Restart requested of negative number of nodes"); @@ -939,7 +1040,7 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, const Properties *reply; const int timeout = handle->read_timeout; 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; CHECK_REPLY(reply, -1); @@ -975,7 +1076,10 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, const Properties *reply; const int timeout = handle->read_timeout; 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; if(reply != NULL) { BaseString result; @@ -986,20 +1090,16 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, return -1; } reply->get("restarted", &restarted); + if(use_v2) + reply->get("disconnect", (Uint32*)disconnect); + else + *disconnect= 0; delete reply; } 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[]= { "enabled", "debug", "info", "warning", "error", "critical", "alert" }; @@ -2353,4 +2453,56 @@ int ndb_mgm_end_session(NdbMgmHandle handle) 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 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*>; diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 9e1224ab3ef..290f57a881a 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -1057,7 +1057,8 @@ CommandInterpreter::executeShutdown(char* parameters) NdbAutoPtr ap1((char*)state); 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) { ndbout << "Shutdown of NDB Cluster node(s) failed." << endl; printError(); @@ -1066,39 +1067,11 @@ CommandInterpreter::executeShutdown(char* parameters) ndbout << result << " NDB Cluster node(s) have shutdown." << endl; - int nodeId= 0; - 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; + if(need_disconnect) { ndbout << "Disconnecting to allow management server to shutdown." << endl; disconnect(); } - ndbout << "NDB Cluster management servers shutdown." << endl; return 0; } @@ -1487,6 +1460,7 @@ CommandInterpreter::executeStop(Vector &command_list, unsigned command_pos, int *node_ids, int no_of_nodes) { + int need_disconnect; int abort= 0; for (; command_pos < command_list.size(); command_pos++) { @@ -1501,7 +1475,8 @@ CommandInterpreter::executeStop(Vector &command_list, 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) { ndbout_c("Shutdown failed."); @@ -1513,27 +1488,19 @@ CommandInterpreter::executeStop(Vector &command_list, ndbout_c("NDB Cluster has shutdown."); else { - int mgm_id= 0; - int need_reconnect= 0; - mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); ndbout << "Node"; for (int i= 0; i < no_of_nodes; i++) - { - if(node_ids[i] == mgm_id) - need_reconnect= 1; - else ndbout << " " << node_ids[i]; - } 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 @@ -1624,6 +1591,7 @@ CommandInterpreter::executeRestart(Vector &command_list, int nostart= 0; int initialstart= 0; int abort= 0; + int need_disconnect= 0; for (; command_pos < command_list.size(); command_pos++) { @@ -1648,9 +1616,9 @@ CommandInterpreter::executeRestart(Vector &command_list, return; } - result= ndb_mgm_restart2(m_mgmsrv, no_of_nodes, node_ids, - initialstart, nostart, abort); - + result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids, + initialstart, nostart, abort, &need_disconnect); + if (result <= 0) { ndbout_c("Restart failed."); printError(); @@ -1661,18 +1629,13 @@ CommandInterpreter::executeRestart(Vector &command_list, ndbout_c("NDB Cluster is being restarted."); else { - int mgm_id= 0; - mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); - ndbout << "Node"; for (int i= 0; i < no_of_nodes; i++) - { - if(node_ids[i] == mgm_id) - disconnect(); ndbout << " " << node_ids[i]; - } ndbout_c(" is being restarted"); } + if(need_disconnect) + disconnect(); } } diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 4c3631488e6..8a9a33779d8 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -1196,6 +1196,27 @@ int MgmtSrvr::stopNodes(const Vector &node_ids, 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. * MGM servers are left in their current state diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index b47ee69fd9f..2102897eb61 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -256,6 +256,8 @@ public: int stopNodes(const Vector &node_ids, int *stopCount, bool abort, int *stopSelf); + int shutdownMGM(int *stopCount, bool abort, int *stopSelf); + /** * shutdown the DB nodes */ diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index a6c483fcdcd..01f11d600df 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -145,7 +145,13 @@ ParserRow commands[] = { 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("initialstart", Int, Optional, "Initial start"), MGM_ARG("nostart", Int, Optional, "No start"), @@ -186,13 +192,21 @@ ParserRow commands[] = { MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""), 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("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_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_ARG("nodeId", Int, Mandatory, "Node"), @@ -850,8 +864,19 @@ MgmApiSession::stopSignalLog(Parser::Context &, } void -MgmApiSession::restart(Parser::Context &, +MgmApiSession::restart_v1(Parser::Context &, Properties const &args) { + restart(args,1); +} + +void +MgmApiSession::restart_v2(Parser::Context &, + Properties const &args) { + restart(args,2); +} + +void +MgmApiSession::restart(Properties const &args, int version) { Uint32 nostart = 0, initialstart = 0, @@ -885,6 +910,8 @@ MgmApiSession::restart(Parser::Context &, } else m_output->println("result: Ok"); m_output->println("restarted: %d", restarted); + if(version>1) + m_output->println("disconnect: %d", (m_stopSelf)?1:0); m_output->println(""); } @@ -994,8 +1021,19 @@ MgmApiSession::getInfoClusterLog(Parser::Context &, } void -MgmApiSession::stop(Parser::Context &, - Properties const &args) { +MgmApiSession::stop_v1(Parser::Context &, + Properties const &args) { + stop(args,1); +} + +void +MgmApiSession::stop_v2(Parser::Context &, + Properties const &args) { + stop(args,2); +} + +void +MgmApiSession::stop(Properties const &args, int version) { Uint32 abort; char *nodes_str; Vector nodes; @@ -1028,25 +1066,46 @@ MgmApiSession::stop(Parser::Context &, else m_output->println("result: Ok"); m_output->println("stopped: %d", stopped); + if(version>1) + m_output->println("disconnect: %d", (m_stopSelf)?1:0); m_output->println(""); } void -MgmApiSession::stopAll(Parser::Context &, +MgmApiSession::stopAll_v1(Parser::Context &, Properties const &args) { - int stopped = 0; + stopAll(args,"db",1); +} + +void +MgmApiSession::stopAll_v2(Parser::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; 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"); if(result != 0) m_output->println("result: %s", get_error_text(result)); else 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(""); } diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index b8a73f5e4bc..0d4331b128b 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -63,7 +63,9 @@ public: void getVersion(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 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 insertError(Parser_t::Context &ctx, const class Properties &args); void setTrace(Parser_t::Context &ctx, const class Properties &args); @@ -75,8 +77,12 @@ public: void abortBackup(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 stop(Parser_t::Context &ctx, const class Properties &args); - void stopAll(Parser_t::Context &ctx, const class Properties &args); + void stop_v1(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 startAll(Parser_t::Context &ctx, const class Properties &args); void bye(Parser_t::Context &ctx, const class Properties &args); From d1b37c77ef202f4d9b276b36000cd4ac4c19626a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 7 Jun 2006 16:20:57 +1000 Subject: [PATCH 06/14] BUG#18966 CHange in stop/shutdown behaviour Fixes based on review by Tomas ndb/src/mgmapi/mgmapi.cpp: Return immediately if ndb_mgm_get_version fails. correctly use new protocol for versions > 5.1 ndb/src/mgmsrv/Services.cpp: Only have 1 version of 'stop all' with reply being dependent on if the optional stop parameter is supplied. ndb/src/mgmsrv/Services.hpp: Only 1 version of stopAll --- ndb/src/mgmapi/mgmapi.cpp | 30 +++++++++++++++++++++--------- ndb/src/mgmsrv/Services.cpp | 36 ++++++++++++++---------------------- ndb/src/mgmsrv/Services.hpp | 4 +--- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 3109cea7782..d514397f8de 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -870,18 +870,24 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list, if(handle->mgmd_version_build==-1) { char verstr[50]; - ndb_mgm_get_version(handle, + if(!ndb_mgm_get_version(handle, &(handle->mgmd_version_major), &(handle->mgmd_version_minor), &(handle->mgmd_version_build), sizeof(verstr), - verstr); + verstr)) + { + return -1; + } } - int use_v2= (handle->mgmd_version_major==5) + 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) - ); + ||(handle->mgmd_version_minor>1) + ) + ) + || (handle->mgmd_version_major>5); if(no_of_nodes < -1){ SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES, @@ -900,7 +906,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list, args.put("stop", (no_of_nodes==-1)?"mgm,db":"db"); const Properties *reply; if(use_v2) - reply = ndb_mgm_call(handle, stop_reply_v2, "stop all v2", &args); + reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args); else reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args); CHECK_REPLY(reply, -1); @@ -1013,18 +1019,24 @@ ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list, if(handle->mgmd_version_build==-1) { char verstr[50]; - ndb_mgm_get_version(handle, + if(!ndb_mgm_get_version(handle, &(handle->mgmd_version_major), &(handle->mgmd_version_minor), &(handle->mgmd_version_build), sizeof(verstr), - verstr); + verstr)) + { + return -1; + } } - int use_v2= (handle->mgmd_version_major==5) + 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) - ); + ||(handle->mgmd_version_minor>1) + ) + ) + || (handle->mgmd_version_major>5); if(no_of_nodes < 0){ SET_ERROR(handle, NDB_MGM_RESTART_FAILED, diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 01f11d600df..cdadec5cea1 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -200,12 +200,9 @@ ParserRow commands[] = { MGM_ARG("node", String, Mandatory, "Node"), MGM_ARG("abort", Int, Mandatory, "Node"), - MGM_CMD("stop all", &MgmApiSession::stopAll_v1, ""), + MGM_CMD("stop all", &MgmApiSession::stopAll, ""), 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_ARG("stop", String, Optional, "MGM/DB or both"), MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""), MGM_ARG("nodeId", Int, Mandatory, "Node"), @@ -1071,31 +1068,26 @@ MgmApiSession::stop(Properties const &args, int version) { m_output->println(""); } - void -MgmApiSession::stopAll_v1(Parser::Context &, - Properties const &args) { - stopAll(args,"db",1); -} - -void -MgmApiSession::stopAll_v2(Parser::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) { +MgmApiSession::stopAll(Parser::Context &, + Properties const &args) { int stopped[2] = {0,0}; Uint32 abort; args.get("abort", &abort); + BaseString stop; + const char* tostop= "db"; + int ver=1; + if (args.get("stop", stop)) + { + tostop= stop.c_str(); + ver= 2; + } + int result= 0; if(strstr(tostop,"db")) result= m_mgmsrv.shutdownDB(&stopped[0], abort != 0); - if(strstr(tostop,"mgm")) + if(!result && strstr(tostop,"mgm")) result= m_mgmsrv.shutdownMGM(&stopped[1], abort!=0, &m_stopSelf); m_output->println("stop reply"); diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index 0d4331b128b..6d293ced8c8 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -80,9 +80,7 @@ public: void stop_v1(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 stopAll(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 bye(Parser_t::Context &ctx, const class Properties &args); From 3f19b05bb00366df88d72f9b6507f897f2f9370b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Jun 2006 15:36:12 +0200 Subject: [PATCH 07/14] Added order by --- mysql-test/r/ndb_lock.result | 8 ++++---- mysql-test/t/ndb_lock.test | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/ndb_lock.result b/mysql-test/r/ndb_lock.result index 92a73830662..3b433023843 100644 --- a/mysql-test/r/ndb_lock.result +++ b/mysql-test/r/ndb_lock.result @@ -78,10 +78,10 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; commit; begin; -select * from t1 where y = 'one' or y = 'three' for update; +select * from t1 where y = 'one' or y = 'three' order by x for update; x y z -3 three 3 1 one 1 +3 three 3 begin; select * from t1 where x = 1 for update; ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -115,10 +115,10 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; commit; begin; -select * from t1 where y = 'one' or y = 'three' lock in share mode; +select * from t1 where y = 'one' or y = 'three' order by x lock in share mode; x y z -3 three 3 1 one 1 +3 three 3 begin; select * from t1 where y = 'one' lock in share mode; x y z diff --git a/mysql-test/t/ndb_lock.test b/mysql-test/t/ndb_lock.test index 6d3257aeb68..54214ee72ec 100644 --- a/mysql-test/t/ndb_lock.test +++ b/mysql-test/t/ndb_lock.test @@ -93,7 +93,7 @@ commit; # table scan connection con1; begin; -select * from t1 where y = 'one' or y = 'three' for update; +select * from t1 where y = 'one' or y = 'three' order by x for update; connection con2; begin; @@ -146,7 +146,7 @@ commit; # table scan connection con1; begin; -select * from t1 where y = 'one' or y = 'three' lock in share mode; +select * from t1 where y = 'one' or y = 'three' order by x lock in share mode; connection con2; begin; From e7daa497613cdd1845ec6b05d7cf3f9efaa2662c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Jun 2006 18:15:08 +0300 Subject: [PATCH 08/14] Bug #20363: Create view on just created view is now denied There was a wrong determination of the DB name (witch is not always the one in TABLE_LIST because derived tables may be calculated using temp tables that have their db name set to ""). The fix determines the database name according to the type of table reference, and calls the function check_access() with the correct db name so the correct set of grants is found. mysql-test/r/view_grant.result: testsuite for the bug mysql-test/t/view_grant.test: testsuite for the bug sql/sql_parse.cc: correct determination of the db name. --- mysql-test/r/view_grant.result | 29 +++++++++++++++++++++++++ mysql-test/t/view_grant.test | 39 ++++++++++++++++++++++++++++++++++ sql/sql_parse.cc | 9 +++++++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index f6559e6f838..a8619201810 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -618,3 +618,32 @@ ERROR HY000: There is no 'no-such-user'@'localhost' registered DROP VIEW v; DROP TABLE t1; USE test; +CREATE USER mysqltest_db1@localhost identified by 'PWD'; +GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION; +CREATE SCHEMA mysqltest_db1 ; +USE mysqltest_db1 ; +CREATE TABLE t1 (f1 INTEGER); +CREATE VIEW view1 AS +SELECT * FROM t1; +SHOW CREATE VIEW view1; +View Create View +view1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1` +CREATE VIEW view2 AS +SELECT * FROM view1; +# Here comes a suspicious warning +SHOW CREATE VIEW view2; +View Create View +view2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1` +# But the view view2 is usable +SELECT * FROM view2; +f1 +CREATE VIEW view3 AS +SELECT * FROM view2; +SELECT * from view3; +f1 +DROP VIEW mysqltest_db1.view3; +DROP VIEW mysqltest_db1.view2; +DROP VIEW mysqltest_db1.view1; +DROP TABLE mysqltest_db1.t1; +DROP SCHEMA mysqltest_db1; +DROP USER mysqltest_db1@localhost; diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index 4663a667d25..f160de2d798 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -807,3 +807,42 @@ SELECT * FROM v; DROP VIEW v; DROP TABLE t1; USE test; + +# +# Bug#20363: Create view on just created view is now denied +# +eval CREATE USER mysqltest_db1@localhost identified by 'PWD'; +eval GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION; + +# The session with the non root user is needed. +--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK +connect (session1,localhost,mysqltest_db1,PWD,test); + +CREATE SCHEMA mysqltest_db1 ; +USE mysqltest_db1 ; + +CREATE TABLE t1 (f1 INTEGER); + +CREATE VIEW view1 AS +SELECT * FROM t1; +SHOW CREATE VIEW view1; + +CREATE VIEW view2 AS +SELECT * FROM view1; +--echo # Here comes a suspicious warning +SHOW CREATE VIEW view2; +--echo # But the view view2 is usable +SELECT * FROM view2; + +CREATE VIEW view3 AS +SELECT * FROM view2; + +SELECT * from view3; + +connection default; +DROP VIEW mysqltest_db1.view3; +DROP VIEW mysqltest_db1.view2; +DROP VIEW mysqltest_db1.view1; +DROP TABLE mysqltest_db1.t1; +DROP SCHEMA mysqltest_db1; +DROP USER mysqltest_db1@localhost; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 213a7730824..ba5c2ebf484 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5004,7 +5004,14 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) if (all_tables->security_ctx) thd->security_ctx= all_tables->security_ctx; - if (check_access(thd, privilege, all_tables->db, + const char *db_name; + if ((all_tables->view || all_tables->field_translation) && + !all_tables->schema_table) + db_name= all_tables->view_db.str; + else + db_name= all_tables->db; + + if (check_access(thd, privilege, db_name, &all_tables->grant.privilege, 0, 0, test(all_tables->schema_table))) goto deny; From de5de7c3196533922169bb0538433fc9618f34f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Jun 2006 00:38:34 +0200 Subject: [PATCH 09/14] ndb - bug#20406 multi-platform testing - not FIX --- mysql-test/r/ndb_condition_pushdown.result | 24 ++++++++++++++++++++++ mysql-test/t/ndb_condition_pushdown.test | 22 ++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result index 27a510b252f..4e5597a4851 100644 --- a/mysql-test/r/ndb_condition_pushdown.result +++ b/mysql-test/r/ndb_condition_pushdown.result @@ -1842,5 +1842,29 @@ a b select * from t1 where b like 'abc' or b like 'abc'; a b 3 abc +drop table t1; +create table t1 ( fname varchar(255), lname varchar(255) ) +engine=ndbcluster; +insert into t1 values ("Young","Foo"); +set engine_condition_pushdown = 0; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); +fname lname +Young Foo +set engine_condition_pushdown = 1; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); +fname lname +Young Foo +insert into t1 values ("aaa", "aaa"); +insert into t1 values ("bbb", "bbb"); +insert into t1 values ("ccc", "ccc"); +insert into t1 values ("ddd", "ddd"); +set engine_condition_pushdown = 0; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); +fname lname +Young Foo +set engine_condition_pushdown = 1; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); +fname lname +Young Foo set engine_condition_pushdown = @old_ecpd; DROP TABLE t1,t2,t3,t4,t5; diff --git a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test index 398ca3c502c..cc138b32b7e 100644 --- a/mysql-test/t/ndb_condition_pushdown.test +++ b/mysql-test/t/ndb_condition_pushdown.test @@ -1686,5 +1686,27 @@ select * from t1 where b like 'ab' or b like 'ab'; select * from t1 where b like 'abc'; select * from t1 where b like 'abc' or b like 'abc'; +# bug#20406 (maybe same as bug#17421 -1, not seen on 32-bit x86) +drop table t1; +create table t1 ( fname varchar(255), lname varchar(255) ) +engine=ndbcluster; +insert into t1 values ("Young","Foo"); + +set engine_condition_pushdown = 0; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); +set engine_condition_pushdown = 1; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); + +# make sure optimizer does not do some crazy shortcut +insert into t1 values ("aaa", "aaa"); +insert into t1 values ("bbb", "bbb"); +insert into t1 values ("ccc", "ccc"); +insert into t1 values ("ddd", "ddd"); + +set engine_condition_pushdown = 0; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); +set engine_condition_pushdown = 1; +SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); + set engine_condition_pushdown = @old_ecpd; DROP TABLE t1,t2,t3,t4,t5; From 2a07ee7202f1ca198d60f89f3abd1cd88f87d717 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Jun 2006 21:30:49 +0200 Subject: [PATCH 10/14] Bug#19191 Repeated crashes on OpenBSD for ssl test cases - Import patch from yaSSL extra/yassl/src/handshake.cpp: Import patch yassl.diff extra/yassl/src/socket_wrapper.cpp: Import patch yassl.diff --- extra/yassl/src/handshake.cpp | 8 ++++---- extra/yassl/src/socket_wrapper.cpp | 13 +++++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 12b62f26e14..66ec64f4af8 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -880,7 +880,7 @@ int sendData(SSL& ssl, const void* buffer, int sz) ssl.SetError(no_error); ssl.verfiyHandShakeComplete(); - if (ssl.GetError()) return 0; + if (ssl.GetError()) return -1; int sent = 0; for (;;) { @@ -891,7 +891,7 @@ int sendData(SSL& ssl, const void* buffer, int sz) buildMessage(ssl, out, data); ssl.Send(out.get_buffer(), out.get_size()); - if (ssl.GetError()) return 0; + if (ssl.GetError()) return -1; sent += len; if (sent == sz) break; } @@ -918,14 +918,14 @@ int receiveData(SSL& ssl, Data& data) ssl.SetError(no_error); ssl.verfiyHandShakeComplete(); - if (ssl.GetError()) return 0; + if (ssl.GetError()) return -1; if (!ssl.bufferedData()) processReply(ssl); ssl.fillData(data); ssl.useLog().ShowData(data.get_length()); - if (ssl.GetError()) return 0; + if (ssl.GetError()) return -1; if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) { ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index 803f4b01249..06b403c999d 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -113,13 +113,22 @@ uint Socket::get_ready() const uint Socket::send(const byte* buf, unsigned int sz, int flags) const { + const byte* pos = buf; + const byte* end = pos + sz; + assert(socket_ != INVALID_SOCKET); - int sent = ::send(socket_, reinterpret_cast(buf), sz, flags); + + while (pos != end) { + int sent = ::send(socket_, reinterpret_cast(pos), + static_cast(end - pos), flags); if (sent == -1) return 0; - return sent; + pos += sent; + } + + return sz; } From 689205ae947176220ef7ba7332ffa2b765c4796a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Jun 2006 16:24:02 +0500 Subject: [PATCH 11/14] Fix for bug#19667 group by a decimal expression yields wrong result mysql-test/r/type_newdecimal.result: Fix for bug#19667 group by a decimal expression yields wrong result test case mysql-test/t/type_newdecimal.test: Fix for bug#19667 group by a decimal expression yields wrong result test case --- mysql-test/r/type_newdecimal.result | 11 +++++++++++ mysql-test/t/type_newdecimal.test | 9 +++++++++ sql/item_buff.cc | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 968c6d3ec6f..4caec152a1f 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1397,3 +1397,14 @@ c1 9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999 drop table t1; +create table t1 (i int, j int); +insert into t1 values (1,1), (1,2), (2,3), (2,4); +select i, count(distinct j) from t1 group by i; +i count(distinct j) +1 2 +2 2 +select i+0.0 as i2, count(distinct j) from t1 group by i2; +i2 count(distinct j) +1.0 2 +2.0 2 +drop table t1; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 74782a5bddb..35aff8b3c5a 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1095,3 +1095,12 @@ insert into t1 values( insert into t1 values(1e100); select * from t1; drop table t1; + +# +# Bug#19667 group by a decimal expression yields wrong result +# +create table t1 (i int, j int); +insert into t1 values (1,1), (1,2), (2,3), (2,4); +select i, count(distinct j) from t1 group by i; +select i+0.0 as i2, count(distinct j) from t1 group by i2; +drop table t1; diff --git a/sql/item_buff.cc b/sql/item_buff.cc index 9db2f465080..1661f04a4ae 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -132,7 +132,7 @@ bool Cached_item_decimal::cmp() { my_decimal tmp; my_decimal *ptmp= item->val_decimal(&tmp); - if (null_value != item->null_value || my_decimal_cmp(&value, ptmp) == 0) + if (null_value != item->null_value || my_decimal_cmp(&value, ptmp)) { null_value= item->null_value; my_decimal2decimal(ptmp, &value); From 9668198e14d575a12dd889a601233924b1f13479 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Jun 2006 22:02:26 +0200 Subject: [PATCH 12/14] BUG#19940: Add Valgrind suppression for false alarm report. --- mysql-test/valgrind.supp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 3c2ac1a7ea5..65c5a82db36 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -292,3 +292,18 @@ futex(utime) fun:__lll_mutex_unlock_wake } + +# +# BUG#19940: NDB sends uninitialized parts of field buffers across the wire. +# This is "works as designed"; the uninitialized part is not used at the +# other end (but Valgrind cannot see this). +# +{ + bug19940 + Memcheck:Param + socketcall.sendto(msg) + fun:send + fun:_ZN15TCP_Transporter6doSendEv + fun:_ZN19TransporterRegistry11performSendEv + fun:_ZN19TransporterRegistry14forceSendCheckEi +} From 59d38c15bc8c010fcff11cdf72f497fd957a1ef6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Jun 2006 22:46:52 -0400 Subject: [PATCH 13/14] Fixing false alarm errors on windows build from a clean clone. win/build-vs71.bat: Don't trigger 'could not find the file specified' errors when running from a clean clone. win/build-vs8.bat: Don't trigger 'could not find the file specified' errors when running from a clean clone. --- win/build-vs71.bat | 2 +- win/build-vs8.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/win/build-vs71.bat b/win/build-vs71.bat index 46f3bc32f6e..959067695c5 100644 --- a/win/build-vs71.bat +++ b/win/build-vs71.bat @@ -1,6 +1,6 @@ @echo off -del cmakecache.txt +if exist cmakecache.txt del cmakecache.txt copy win\vs71cache.txt cmakecache.txt cmake -G "Visual Studio 7 .NET 2003" copy cmakecache.txt win\vs71cache.txt diff --git a/win/build-vs8.bat b/win/build-vs8.bat index 349c3e78628..d9c06241a9b 100644 --- a/win/build-vs8.bat +++ b/win/build-vs8.bat @@ -1,6 +1,6 @@ @echo off -del cmakecache.txt +if exist cmakecache.txt del cmakecache.txt copy win\vs8cache.txt cmakecache.txt cmake -G "Visual Studio 8 2005" copy cmakecache.txt win\vs8cache.txt From 9224719d254ee5eba41a6b9e5e7d35c973a86853 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Jun 2006 15:04:35 -0400 Subject: [PATCH 14/14] Fix for broken compile if not compiling with partitioning --- sql/sql_table.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d379af3b3eb..bf0535567b4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5009,6 +5009,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, old_db_type= table->s->db_type; if (!create_info->db_type) { +#ifdef WITH_PARTITION_STORAGE_ENGINE if (table->part_info && create_info->used_fields & HA_CREATE_USED_ENGINE) { @@ -5022,6 +5023,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info->db_type= table->part_info->default_engine_type; } else +#endif create_info->db_type= old_db_type; }