4251 magnus.blaudd@stripped 2011-06-21 [merge]
Merge 7.0 -> 7.1
added:
mysql-test/suite/ndb/r/ndb_select_count.result
mysql-test/suite/ndb/t/ndb_select_count.test
modified:
sql/ha_ndbcluster.cc
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/src/ndbapi/NdbQueryBuilder.hpp
storage/ndb/src/ndbapi/NdbQueryOperation.cpp
storage/ndb/src/ndbapi/NdbQueryOperation.hpp
storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp
storage/ndb/test/ndbapi/testMgmd.cpp
4250 Craig L Russell 2011-06-20
Modify some error conditions to print mismatches instead of failing immediately
Allow data comparison failures to continue or throw an exception
Normalize operation names (remove "_" from names except at end)
Clean rows only at the beginning (operations already delete rows during tests)
modified:
storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java
storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java
storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java
=== added file 'mysql-test/suite/ndb/r/ndb_select_count.result'
--- a/mysql-test/suite/ndb/r/ndb_select_count.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_select_count.result 2011-06-20 12:34:27 +0000
@@ -0,0 +1,19 @@
+create table t1(
+k int not null auto_increment primary key,
+i int,
+j int
+) engine=ndbcluster;
+insert into t1(i,j) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+select count(*) from t1;
+count(*)
+7
+begin;
+delete from t1 where k = 10000;
+select count(*) from t1;
+count(*)
+7
+commit;
+select count(*) from t1;
+count(*)
+7
+drop table t1;
=== added file 'mysql-test/suite/ndb/t/ndb_select_count.test'
--- a/mysql-test/suite/ndb/t/ndb_select_count.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_select_count.test 2011-06-20 12:34:27 +0000
@@ -0,0 +1,18 @@
+-- source include/have_ndb.inc
+
+create table t1(
+ k int not null auto_increment primary key,
+ i int,
+ j int
+) engine=ndbcluster;
+
+insert into t1(i,j) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+
+select count(*) from t1;
+begin;
+delete from t1 where k = 10000; # none existant, rbwr
+select count(*) from t1;
+commit;
+select count(*) from t1;
+
+drop table t1;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2011-06-20 16:22:38 +0000
+++ b/sql/ha_ndbcluster.cc 2011-06-21 13:50:33 +0000
@@ -5057,6 +5057,7 @@ int ha_ndbcluster::end_bulk_delete()
assert(m_rows_deleted >= ignore_count);
m_rows_deleted-= ignore_count;
+ no_uncommitted_rows_update(ignore_count);
DBUG_RETURN(0);
}
@@ -5249,6 +5250,7 @@ int ha_ndbcluster::ndb_delete_row(const
{
assert(m_rows_deleted >= ignore_count);
m_rows_deleted-= ignore_count;
+ no_uncommitted_rows_update(ignore_count);
}
DBUG_RETURN(0);
}
=== 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:51:41 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2011-06-21 13:50:33 +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:45:49 +0000
+++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp 2011-06-21 13:50:33 +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/src/ndbapi/NdbQueryBuilder.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.hpp 2011-06-16 09:32:43 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.hpp 2011-06-20 13:25:48 +0000
@@ -479,13 +479,8 @@ private:
* times. It is valid until it is explicitely released().
*
* The NdbQueryDef *must* be keept alive until the last thread
- * which executing a query based on this NdbQueryDef has completed execution
- * *and* result handling. Used from multiple threads this implies either:
- *
- * - Keep the NdbQueryDef until all threads terminates.
- * - Implement reference counting on the NdbQueryDef.
- * - Use the supplied copy constructor to give each thread its own copy
- * of the NdbQueryDef.
+ * which executing a query based on this NdbQueryDef has called
+ * NdbQuery::close().
*
* A NdbQueryDef is scheduled for execution by appending it to an open
* transaction - optionally together with a set of parameters specifying
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2011-06-16 09:32:43 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2011-06-20 13:25:48 +0000
@@ -1389,7 +1389,7 @@ NdbQueryImpl::NdbQueryImpl(NdbTransactio
m_state(Initial),
m_tcState(Inactive),
m_next(NULL),
- m_queryDef(queryDef),
+ m_queryDef(&queryDef),
m_error(),
m_transaction(trans),
m_scanTransaction(NULL),
@@ -1452,9 +1452,13 @@ NdbQueryImpl::NdbQueryImpl(NdbTransactio
NdbQueryImpl::~NdbQueryImpl()
{
-
- // Do this to check that m_queryDef still exists.
- assert(getNoOfOperations() == m_queryDef.getNoOfOperations());
+ /** BEWARE:
+ * Don't refer NdbQueryDef or NdbQueryOperationDefs after
+ * NdbQuery::close() as at this stage the appliaction is
+ * allowed to destruct the Def's.
+ */
+ assert(m_state==Closed);
+ assert(m_rootFrags==NULL);
// NOTE: m_operations[] was allocated as a single memory chunk with
// placement new construction of each operation.
@@ -1465,8 +1469,6 @@ NdbQueryImpl::~NdbQueryImpl()
}
m_operations = NULL;
}
- delete[] m_rootFrags;
- m_rootFrags = NULL;
m_state = Destructed;
}
@@ -1478,6 +1480,9 @@ NdbQueryImpl::postFetchRelease()
{ m_operations[i].postFetchRelease();
}
}
+ delete[] m_rootFrags;
+ m_rootFrags = NULL;
+
m_rowBufferAlloc.reset();
m_tupleSetAlloc.reset();
m_resultStreamAlloc.reset();
@@ -1957,7 +1962,7 @@ NdbQueryImpl::awaitMoreResults(bool forc
assert(m_applFrags.getCurrent() == NULL);
/* Check if there are any more completed fragments available.*/
- if (m_queryDef.isScanQuery())
+ if (getQueryDef().isScanQuery())
{
assert (m_scanTransaction);
assert (m_state==Executing);
@@ -2052,7 +2057,7 @@ NdbQueryImpl::awaitMoreResults(bool forc
assert(m_pendingFrags == 0);
assert(m_finalBatchFrags == getRootFragCount());
return FetchResult_noMoreData;
- } // if(m_queryDef.isScanQuery())
+ } // if(getQueryDef().isScanQuery())
} //NdbQueryImpl::awaitMoreResults
@@ -2131,32 +2136,41 @@ NdbQueryImpl::close(bool forceSend)
int res = 0;
assert (m_state >= Initial && m_state < Destructed);
- Ndb* const ndb = m_transaction.getNdb();
-
- if (m_tcState != Inactive)
+ if (m_state != Closed)
{
- /* We have started a scan, but we have not yet received the last batch
- * for all root fragments. We must therefore close the scan to release
- * the scan context at TC.*/
- res = closeTcCursor(forceSend);
- }
+ if (m_tcState != Inactive)
+ {
+ /* We have started a scan, but we have not yet received the last batch
+ * for all root fragments. We must therefore close the scan to release
+ * the scan context at TC.*/
+ res = closeTcCursor(forceSend);
+ }
- // Throw any pending results
- m_fullFrags.clear();
- m_applFrags.clear();
+ // Throw any pending results
+ m_fullFrags.clear();
+ m_applFrags.clear();
- if (m_scanTransaction != NULL)
- {
- assert (m_state != Closed);
- assert (m_scanTransaction->m_scanningQuery == this);
- m_scanTransaction->m_scanningQuery = NULL;
- ndb->closeTransaction(m_scanTransaction);
- ndb->theRemainingStartTransactions--; // Compensate; m_scanTransaction was not a real Txn
- m_scanTransaction = NULL;
+ Ndb* const ndb = m_transaction.getNdb();
+ if (m_scanTransaction != NULL)
+ {
+ assert (m_state != Closed);
+ assert (m_scanTransaction->m_scanningQuery == this);
+ m_scanTransaction->m_scanningQuery = NULL;
+ ndb->closeTransaction(m_scanTransaction);
+ ndb->theRemainingStartTransactions--; // Compensate; m_scanTransaction was not a real Txn
+ m_scanTransaction = NULL;
+ }
+
+ postFetchRelease();
+ m_state = Closed; // Even if it was previously 'Failed' it is closed now!
}
- postFetchRelease();
- m_state = Closed; // Even if it was previously 'Failed' it is closed now!
+ /** BEWARE:
+ * Don't refer NdbQueryDef or its NdbQueryOperationDefs after ::close()
+ * as the application is allowed to destruct the Def's after this point.
+ */
+ m_queryDef= NULL;
+
return res;
} //NdbQueryImpl::close
@@ -2819,7 +2833,7 @@ NdbQueryImpl::sendFetchMore(NdbRootFragm
{
assert(getRoot().m_resultStreams!=NULL);
assert(!emptyFrag.finalBatchReceived());
- assert(m_queryDef.isScanQuery());
+ assert(getQueryDef().isScanQuery());
const Uint32 fragNo = emptyFrag.getFragNo();
emptyFrag.reset();
@@ -2892,7 +2906,7 @@ NdbQueryImpl::sendFetchMore(NdbRootFragm
int
NdbQueryImpl::closeTcCursor(bool forceSend)
{
- assert (m_queryDef.isScanQuery());
+ assert (getQueryDef().isScanQuery());
NdbImpl* const ndb = m_transaction.getNdb()->theImpl;
const Uint32 timeout = ndb->get_waitfor_timeout();
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.hpp 2011-04-06 14:16:13 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.hpp 2011-06-20 13:25:48 +0000
@@ -180,7 +180,15 @@ public:
NdbTransaction* getNdbTransaction() const;
/**
- * Close query
+ * Close query.
+ *
+ * Will release most of the internally allocated objects owned
+ * by this NdbQuery and detach itself from the NdbQueryDef
+ * used to instantiate it.
+ *
+ * The application may destruct the NdbQueryDef after
+ * ::close() has been called on *all* NdbQuery objects
+ * instantiated from it.
*/
void close(bool forceSend = false);
=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp 2011-04-06 14:16:13 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp 2011-06-20 13:25:48 +0000
@@ -142,7 +142,8 @@ public:
/** Close query:
* - Release datanode resources,
* - Discard pending result sets,
- * - optionaly dealloc NdbQuery structures
+ * - Delete internal buffer and structures for receiving results.
+ * - Disconnect with NdbQueryDef - it might now be destructed .
*/
int close(bool forceSend);
@@ -191,7 +192,10 @@ public:
/** Get the (transaction independent) definition of this query. */
const NdbQueryDefImpl& getQueryDef() const
- { return m_queryDef; }
+ {
+ assert(m_queryDef);
+ return *m_queryDef;
+ }
/** Process TCKEYCONF message. Return true if query is complete. */
bool execTCKEYCONF();
@@ -213,7 +217,7 @@ public:
*/
void setStartIndicator()
{
- assert(!m_queryDef.isScanQuery());
+ assert(!getQueryDef().isScanQuery());
m_startIndicator = true;
}
@@ -224,7 +228,7 @@ public:
*/
void setCommitIndicator()
{
- assert(!m_queryDef.isScanQuery());
+ assert(!getQueryDef().isScanQuery());
m_commitIndicator = true;
}
@@ -415,7 +419,7 @@ private:
/** Next query in same transaction.*/
NdbQueryImpl* m_next;
/** Definition of this query.*/
- const NdbQueryDefImpl& m_queryDef;
+ const NdbQueryDefImpl* m_queryDef;
/** Possible error status of this query.*/
NdbError m_error;
=== modified file 'storage/ndb/test/ndbapi/testMgmd.cpp'
--- a/storage/ndb/test/ndbapi/testMgmd.cpp 2011-02-03 14:45:49 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp 2011-06-21 13:50:33 +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);
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.1-telco-7.1 branch (magnus.blaudd:4250 to 4251) | magnus.blaudd | 21 Jun |