#At file:///data0/magnus/mysql/7.0-bug12352191/ based on revid:ole.john.aske@stripped
4469 magnus.blaudd@stripped 2011-06-21
Bug#12352191 NDB_MGMD NODES DON'T SEE EACH OTHER AS CONNECTED UNTIL END OF
SYSTEM RESTART.
- Add specialized function status_mgmd() and status_api() used to
retrive version and status for API and MGM nodes.
- Make status_mgmd() aware that other MGM nodes are connected directly
to own node with transporter
- Fix missing assignment of mysql_version in Qmgr
- Return the connected adress from transporter also for MGM nodes
- Also fix bug#48301 by adding a new status CONNECTED to be used
when we know the node is connected(this stats was previously only
indicated by version != 0)
modified:
storage/ndb/include/mgmapi/mgmapi.h
storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
storage/ndb/src/mgmapi/mgmapi.cpp
storage/ndb/src/mgmsrv/MgmtSrvr.cpp
storage/ndb/src/mgmsrv/MgmtSrvr.hpp
storage/ndb/src/ndbapi/ClusterMgr.cpp
storage/ndb/test/ndbapi/testMgmd.cpp
=== modified file 'storage/ndb/include/mgmapi/mgmapi.h'
--- a/storage/ndb/include/mgmapi/mgmapi.h 2011-02-01 23:27:25 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi.h 2011-06-21 13:10:37 +0000
@@ -206,11 +206,13 @@ extern "C" {
NDB_MGM_NODE_STATUS_SINGLEUSER = 7,
/** Resume mode*/
NDB_MGM_NODE_STATUS_RESUME = 8,
+ /** Node is connected */
+ NDB_MGM_NODE_STATUS_CONNECTED = 9,
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/** Min valid value*/
NDB_MGM_NODE_STATUS_MIN = 0,
/** Max valid value*/
- NDB_MGM_NODE_STATUS_MAX = 8
+ NDB_MGM_NODE_STATUS_MAX = 9
#endif
};
=== modified file 'storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp 2011-06-13 06:14:32 +0000
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp 2011-06-21 13:10:37 +0000
@@ -3728,6 +3728,7 @@ Qmgr::execAPI_VERSION_REQ(Signal * signa
else
{
conf->version = 0;
+ conf->mysql_version = 0;
conf->inet_addr= 0;
}
conf->nodeId = nodeId;
=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp 2011-03-28 09:01:03 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp 2011-06-21 13:10:37 +0000
@@ -934,7 +934,10 @@ static struct ndb_mgm_status_atoi status
{ "STARTED", NDB_MGM_NODE_STATUS_STARTED },
{ "SHUTTING_DOWN", NDB_MGM_NODE_STATUS_SHUTTING_DOWN },
{ "RESTARTING", NDB_MGM_NODE_STATUS_RESTARTING },
- { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER }
+ { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER },
+ { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER },
+ { "RESUME", NDB_MGM_NODE_STATUS_RESUME },
+ { "CONNECTED", NDB_MGM_NODE_STATUS_CONNECTED }
};
const int no_of_status_values = (sizeof(status_values) /
=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2011-06-01 07:40:49 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2011-06-21 13:10:37 +0000
@@ -835,59 +835,34 @@ MgmtSrvr::start(int nodeId)
* Version handling
*****************************************************************************/
-int
-MgmtSrvr::versionNode(int nodeId, Uint32 &version, Uint32& mysql_version,
- const char **address)
-{
- version= 0;
- mysql_version = 0;
- if (getOwnNodeId() == nodeId)
- {
- /**
- * If we're inquiring about our own node id,
- * We know what version we are (version implies connected for mgm)
- * but would like to find out from elsewhere what address they're using
- * to connect to us. This means that secondary mgm servers
- * can list ip addresses for mgm servers.
- *
- * If we don't get an address (i.e. no db nodes),
- * we get the address from the configuration.
- */
- sendVersionReq(nodeId, version, mysql_version, address);
- version= NDB_VERSION;
- mysql_version = NDB_MYSQL_VERSION_D;
- if(!*address)
- {
- Guard g(m_local_config_mutex);
- ConfigIter iter(m_local_config, CFG_SECTION_NODE);
- unsigned tmp= 0;
- for(iter.first();iter.valid();iter.next())
- {
- if(iter.get(CFG_NODE_ID, &tmp)) require(false);
- if((unsigned)nodeId!=tmp)
- continue;
- if(iter.get(CFG_NODE_HOST, address)) require(false);
- break;
- }
- }
+void
+MgmtSrvr::status_api(int nodeId,
+ ndb_mgm_node_status& node_status,
+ Uint32& version, Uint32& mysql_version,
+ const char **address)
+{
+ assert(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API);
+ assert(version == 0 && mysql_version == 0);
+
+ if (sendVersionReq(nodeId, version, mysql_version, address) != 0)
+ {
+ // Couldn't get version from any NDB node.
+ assert(version == 0);
+ node_status = NDB_MGM_NODE_STATUS_UNKNOWN;
+ return;
}
- else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
+
+ if (version)
{
- trp_node node = getNodeInfo(nodeId);
- if(node.is_connected())
- {
- version= node.m_info.m_version;
- mysql_version = node.m_info.m_mysql_version;
- }
- *address= get_connect_address(nodeId);
+ assert(mysql_version);
+ node_status = NDB_MGM_NODE_STATUS_CONNECTED;
}
- else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
+ else
{
- return sendVersionReq(nodeId, version, mysql_version, address);
+ assert(mysql_version == 0);
+ node_status = NDB_MGM_NODE_STATUS_NO_CONTACT;
}
-
- return 0;
+ return;
}
@@ -1898,6 +1873,75 @@ MgmtSrvr::updateStatus()
theFacade->ext_forceHB();
}
+
+void
+MgmtSrvr::status_mgmd(NodeId node_id,
+ ndb_mgm_node_status& node_status,
+ Uint32& version, Uint32& mysql_version,
+ const char **address)
+{
+ assert(getNodeType(node_id) == NDB_MGM_NODE_TYPE_MGM);
+
+ if (node_id == getOwnNodeId())
+ {
+ /*
+ Special case to get version of own node
+ - version and mysql_version is hardcoded
+ - address should be the address seen from ndbd(if it's connected)
+ else use HostName from config
+ */
+ Uint32 tmp_version = 0, tmp_mysql_version = 0;
+ sendVersionReq(node_id, tmp_version, tmp_mysql_version, address);
+ // Check that the version returned is equal to compiled in version
+ assert(tmp_version == 0 ||
+ (tmp_version == NDB_VERSION &&
+ tmp_mysql_version == NDB_MYSQL_VERSION_D));
+
+ version = NDB_VERSION;
+ mysql_version = NDB_MYSQL_VERSION_D;
+ if(!*address)
+ {
+ // No address returned from ndbd -> get HostName from config
+ Guard g(m_local_config_mutex);
+ ConfigIter iter(m_local_config, CFG_SECTION_NODE);
+ require(iter.find(CFG_NODE_ID, node_id) == 0);
+ require(iter.get(CFG_NODE_HOST, address) == 0);
+
+ /*
+ Try to convert HostName to numerical ip address
+ (to get same output as if ndbd had replied)
+ */
+ struct in_addr addr;
+ if (Ndb_getInAddr(&addr, *address) == 0)
+ *address = inet_ntoa(addr);
+ }
+
+ node_status = NDB_MGM_NODE_STATUS_CONNECTED;
+ return;
+ }
+
+ /*
+ MGM nodes are connected directly to all other MGM
+ node(s), return status as seen by ClusterMgr
+ */
+ const trp_node node = getNodeInfo(node_id);
+ if(node.is_connected())
+ {
+ version = node.m_info.m_version;
+ mysql_version = node.m_info.m_mysql_version;
+ node_status = NDB_MGM_NODE_STATUS_CONNECTED;
+ *address= get_connect_address(node_id);
+ }
+ else
+ {
+ version = 0;
+ mysql_version = 0;
+ node_status = NDB_MGM_NODE_STATUS_NO_CONTACT;
+ }
+
+ return;
+}
+
int
MgmtSrvr::status(int nodeId,
ndb_mgm_node_status * _status,
@@ -1910,24 +1954,38 @@ MgmtSrvr::status(int nodeId,
Uint32 * connectCount,
const char **address)
{
- if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
- versionNode(nodeId, *version, *mysql_version, address);
- } else {
- *address= get_connect_address(nodeId);
+ switch(getNodeType(nodeId)){
+ case NDB_MGM_NODE_TYPE_API:
+ status_api(nodeId, *_status, *version, *mysql_version, address);
+ return 0;
+ break;
+
+ case NDB_MGM_NODE_TYPE_MGM:
+ status_mgmd(nodeId, *_status, *version, *mysql_version, address);
+ return 0;
+ break;
+
+ case NDB_MGM_NODE_TYPE_NDB:
+ break;
+
+ default:
+ abort();
+ break;
}
const trp_node node = getNodeInfo(nodeId);
+ assert(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB &&
+ node.m_info.getType() == NodeInfo::DB);
if(!node.is_connected()){
* _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
return 0;
}
-
- if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
- * version = node.m_info.m_version;
- * mysql_version = node.m_info.m_mysql_version;
- }
+
+ * version = node.m_info.m_version;
+ * mysql_version = node.m_info.m_mysql_version;
+
+ *address= get_connect_address(nodeId);
* dynamic = node.m_state.dynamicId;
* nodegroup = node.m_state.nodeGroup;
@@ -2792,9 +2850,10 @@ MgmtSrvr::getNodeType(NodeId nodeId) con
const char *MgmtSrvr::get_connect_address(Uint32 node_id)
{
- if (m_connect_address[node_id].s_addr == 0 &&
- theFacade &&
- getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB)
+ if (theFacade &&
+ m_connect_address[node_id].s_addr == 0 &&
+ (getNodeType(node_id) == NDB_MGM_NODE_TYPE_MGM ||
+ getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB))
{
const trp_node &node= getNodeInfo(node_id);
if (node.is_connected())
=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp 2011-06-01 07:40:49 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp 2011-06-21 13:10:37 +0000
@@ -364,8 +364,14 @@ public:
private:
int guess_master_node(SignalSender&);
- int versionNode(int nodeId, Uint32 &version,
- Uint32 &mysql_version, const char **address);
+ void status_api(int nodeId,
+ ndb_mgm_node_status& node_status,
+ Uint32& version, Uint32& mysql_version,
+ const char **address);
+ void status_mgmd(NodeId node_id,
+ ndb_mgm_node_status& node_status,
+ Uint32& version, Uint32& mysql_version,
+ const char **address);
int sendVersionReq(int processId, Uint32 &version,
Uint32& mysql_version, const char **address);
=== modified file 'storage/ndb/src/ndbapi/ClusterMgr.cpp'
--- a/storage/ndb/src/ndbapi/ClusterMgr.cpp 2011-02-03 14:20:36 +0000
+++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp 2011-06-21 13:10:37 +0000
@@ -651,6 +651,9 @@ ClusterMgr::execAPI_REGREQ(const Uint32
if(node.m_info.m_version != apiRegReq->version){
node.m_info.m_version = apiRegReq->version;
+ node.m_info.m_mysql_version = apiRegReq->mysql_version;
+ if (node.m_info.m_version < NDBD_SPLIT_VERSION)
+ node.m_info.m_mysql_version = 0;
if (getMajor(node.m_info.m_version) < getMajor(NDB_VERSION) ||
getMinor(node.m_info.m_version) < getMinor(NDB_VERSION)) {
=== modified file 'storage/ndb/test/ndbapi/testMgmd.cpp'
--- a/storage/ndb/test/ndbapi/testMgmd.cpp 2011-02-03 14:20:36 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp 2011-06-21 13:10:37 +0000
@@ -934,6 +934,171 @@ runBug56844(NDBT_Context* ctx, NDBT_Step
return NDBT_OK;
}
+static bool
+get_status(const char* connectstring,
+ Properties& status)
+{
+ NdbMgmd ndbmgmd;
+ if (!ndbmgmd.connect(connectstring))
+ return false;
+
+ Properties args;
+ if (!ndbmgmd.call("get status", args,
+ "node status", status, NULL, true))
+ {
+ g_err << "fetch_mgmd_status: mgmd.call failed" << endl;
+ return false;
+ }
+ return true;
+}
+
+static bool
+value_equal(Properties& status,
+ int nodeid, const char* name,
+ const char* expected_value)
+{
+ const char* value;
+ BaseString key;
+ key.assfmt("node.%d.%s", nodeid, name);
+ if (!status.get(key.c_str(), &value))
+ {
+ g_err << "value_equal: no value found for '" << name
+ << "." << nodeid << "'" << endl;
+ return false;
+ }
+
+ if (strcmp(value, expected_value))
+ {
+ g_err << "value_equal: found unexpected value: '" << value
+ << "', expected: '" << expected_value << "'" <<endl;
+ return false;
+ }
+ g_info << "'" << value << "'=='" << expected_value << "'" << endl;
+ return true;
+}
+
+#include <ndb_version.h>
+
+int runTestBug12352191(NDBT_Context* ctx, NDBT_Step* step)
+{
+ BaseString version;
+ version.assfmt("%u", NDB_VERSION_D);
+ BaseString mysql_version;
+ mysql_version.assfmt("%u", NDB_MYSQL_VERSION_D);
+ BaseString address("127.0.0.1");
+
+ NDBT_Workingdir wd("test_mgmd"); // temporary working directory
+
+ g_err << "** Create config.ini" << endl;
+ Properties config = ConfigFactory::create(2);
+ CHECK(ConfigFactory::write_config_ini(config,
+ path(wd.path(),
+ "config.ini",
+ NULL).c_str()));
+
+ MgmdProcessList mgmds;
+ const int nodeid1 = 1;
+ Mgmd* mgmd1 = new Mgmd(nodeid1);
+ mgmds.push_back(mgmd1);
+
+ const int nodeid2 = 2;
+ Mgmd* mgmd2 = new Mgmd(nodeid2);
+ mgmds.push_back(mgmd2);
+
+ // Start first mgmd
+ CHECK(mgmd1->start_from_config_ini(wd.path()));
+ CHECK(mgmd1->connect(config));
+
+ Properties status1;
+ CHECK(get_status(mgmd1->connectstring(config).c_str(), status1));
+ //status1.print();
+ // Check status for own mgm node, always CONNECTED
+ CHECK(value_equal(status1, nodeid1, "type", "MGM"));
+ CHECK(value_equal(status1, nodeid1, "status", "CONNECTED"));
+ CHECK(value_equal(status1, nodeid1, "version", version.c_str()));
+ CHECK(value_equal(status1, nodeid1, "mysql_version", mysql_version.c_str()));
+ CHECK(value_equal(status1, nodeid1, "address", address.c_str()));
+ CHECK(value_equal(status1, nodeid1, "startphase", "0"));
+ CHECK(value_equal(status1, nodeid1, "dynamic_id", "0"));
+ CHECK(value_equal(status1, nodeid1, "node_group", "0"));
+ CHECK(value_equal(status1, nodeid1, "connect_count", "0"));
+
+ // Check status for other mgm node
+ // not started yet -> NO_CONTACT, no address, no versions
+ CHECK(value_equal(status1, nodeid2, "type", "MGM"));
+ CHECK(value_equal(status1, nodeid2, "status", "NO_CONTACT"));
+ CHECK(value_equal(status1, nodeid2, "version", "0"));
+ CHECK(value_equal(status1, nodeid2, "mysql_version", "0"));
+ CHECK(value_equal(status1, nodeid2, "address", ""));
+ CHECK(value_equal(status1, nodeid2, "startphase", "0"));
+ CHECK(value_equal(status1, nodeid2, "dynamic_id", "0"));
+ CHECK(value_equal(status1, nodeid2, "node_group", "0"));
+ CHECK(value_equal(status1, nodeid2, "connect_count", "0"));
+
+ // Start second mgmd
+ CHECK(mgmd2->start_from_config_ini(wd.path()));
+ CHECK(mgmd2->connect(config));
+
+ // wait for confirmed config
+ for (unsigned i = 0; i < mgmds.size(); i++)
+ CHECK(mgmds[i]->wait_confirmed_config());
+
+ Properties status2;
+ CHECK(get_status(mgmd2->connectstring(config).c_str(), status2));
+ //status2.print();
+ // Check status for own mgm node, always CONNECTED
+ CHECK(value_equal(status2, nodeid2, "type", "MGM"));
+ CHECK(value_equal(status2, nodeid2, "status", "CONNECTED"));
+ CHECK(value_equal(status2, nodeid2, "version", version.c_str()));
+ CHECK(value_equal(status2, nodeid2, "mysql_version", mysql_version.c_str()));
+ CHECK(value_equal(status2, nodeid2, "address", address.c_str()));
+ CHECK(value_equal(status2, nodeid2, "startphase", "0"));
+ CHECK(value_equal(status2, nodeid2, "dynamic_id", "0"));
+ CHECK(value_equal(status2, nodeid2, "node_group", "0"));
+ CHECK(value_equal(status2, nodeid2, "connect_count", "0"));
+
+ // Check status for other mgm node
+ // both started now -> CONNECTED, address and versions filled in
+ CHECK(value_equal(status2, nodeid1, "type", "MGM"));
+ CHECK(value_equal(status2, nodeid1, "status", "CONNECTED"));
+ CHECK(value_equal(status2, nodeid1, "version", version.c_str()));
+ CHECK(value_equal(status2, nodeid1, "mysql_version", mysql_version.c_str()));
+ CHECK(value_equal(status2, nodeid1, "address", address.c_str()));
+ CHECK(value_equal(status2, nodeid1, "startphase", "0"));
+ CHECK(value_equal(status2, nodeid1, "dynamic_id", "0"));
+ CHECK(value_equal(status2, nodeid1, "node_group", "0"));
+ CHECK(value_equal(status2, nodeid1, "connect_count", "0"));
+
+ Properties status3;
+ CHECK(get_status(mgmd1->connectstring(config).c_str(), status3));
+ //status3.print();
+ // Check status for own mgm node, always CONNECTED
+ CHECK(value_equal(status3, nodeid1, "type", "MGM"));
+ CHECK(value_equal(status3, nodeid1, "status", "CONNECTED"));
+ CHECK(value_equal(status3, nodeid1, "version", version.c_str()));
+ CHECK(value_equal(status3, nodeid1, "mysql_version", mysql_version.c_str()));
+ CHECK(value_equal(status3, nodeid1, "address", address.c_str()));
+ CHECK(value_equal(status3, nodeid1, "startphase", "0"));
+ CHECK(value_equal(status3, nodeid1, "dynamic_id", "0"));
+ CHECK(value_equal(status3, nodeid1, "node_group", "0"));
+ CHECK(value_equal(status3, nodeid1, "connect_count", "0"));
+
+ // Check status for other mgm node
+ // both started now -> CONNECTED, address and versions filled in
+ CHECK(value_equal(status3, nodeid2, "type", "MGM"));
+ CHECK(value_equal(status3, nodeid2, "status", "CONNECTED"));
+ CHECK(value_equal(status3, nodeid2, "version", version.c_str()));
+ CHECK(value_equal(status3, nodeid2, "mysql_version", mysql_version.c_str()));
+ CHECK(value_equal(status3, nodeid2, "address", address.c_str()));
+ CHECK(value_equal(status3, nodeid2, "startphase", "0"));
+ CHECK(value_equal(status3, nodeid2, "dynamic_id", "0"));
+ CHECK(value_equal(status3, nodeid2, "node_group", "0"));
+ CHECK(value_equal(status3, nodeid2, "connect_count", "0"));
+
+ return NDBT_OK;
+
+}
+
NDBT_TESTSUITE(testMgmd);
DRIVER(DummyDriver); /* turn off use of NdbApi */
@@ -981,6 +1146,11 @@ TESTCASE("Bug56844",
{
INITIALIZER(runBug56844);
}
+TESTCASE("Bug12352191",
+ "Test mgmd status for other mgmd")
+{
+ INITIALIZER(runTestBug12352191);
+}
NDBT_TESTSUITE_END(testMgmd);
Attachment: [text/bzr-bundle] bzr/magnus.blaudd@oracle.com-20110621131037-hr0vnnxhqduwsr07.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:4469) Bug#48301Bug#12352191 | magnus.blaudd | 21 Jun |