From 582221604e8e567e154ce499bd09e0204b965e39 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Mar 2007 15:37:10 +0700 Subject: [PATCH 1/2] Bug #25275 SINGLE USER MODE prevents ALTER on non-ndb tables for other mysqld nodes - correction of part 1 add ndb_waiter option to wait for single user mode ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Bug #25275 SINGLE USER MODE prevents ALTER on non-ndb tables for other mysqld nodes - correction of part 1 ndb/src/kernel/blocks/dbdict/Dbdict.hpp: Bug #25275 SINGLE USER MODE prevents ALTER on non-ndb tables for other mysqld nodes - correction of part 1 ndb/tools/waiter.cpp: add ndb_waiter option to wait for single user mode --- ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 36 ++++++++++++++----------- ndb/src/kernel/blocks/dbdict/Dbdict.hpp | 2 ++ ndb/tools/waiter.cpp | 12 ++++++++- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 16964ec443f..b125f8d988d 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -2910,9 +2910,7 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){ break; } - if(getNodeState().getSingleUserMode() && - (refToNode(signal->getSendersBlockRef()) != - getNodeState().getSingleUserApi())) + if (checkSingleUserMode(signal->getSendersBlockRef())) { jam(); parseRecord.errorCode = CreateTableRef::SingleUser; @@ -3081,9 +3079,7 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) return; } - if(getNodeState().getSingleUserMode() && - (refToNode(signal->getSendersBlockRef()) != - getNodeState().getSingleUserApi())) + if (checkSingleUserMode(signal->getSendersBlockRef())) { jam(); alterTableRef(signal, req, AlterTableRef::SingleUser); @@ -5419,9 +5415,7 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){ return; } - if(getNodeState().getSingleUserMode() && - (refToNode(signal->getSendersBlockRef()) != - getNodeState().getSingleUserApi())) + if (checkSingleUserMode(signal->getSendersBlockRef())) { jam(); dropTableRef(signal, req, DropTableRef::SingleUser); @@ -6558,9 +6552,7 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) jam(); tmperr = CreateIndxRef::Busy; } - else if(getNodeState().getSingleUserMode() && - (refToNode(senderRef) != - getNodeState().getSingleUserApi())) + else if (checkSingleUserMode(senderRef)) { jam(); tmperr = CreateIndxRef::SingleUser; @@ -7135,9 +7127,7 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) jam(); tmperr = DropIndxRef::Busy; } - else if(getNodeState().getSingleUserMode() && - (refToNode(senderRef) != - getNodeState().getSingleUserApi())) + else if (checkSingleUserMode(senderRef)) { jam(); tmperr = DropIndxRef::SingleUser; @@ -10579,4 +10569,20 @@ Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table return 0; } +/* + return 1 if all of the below is true + a) node in single user mode + b) senderRef is not a db node + c) senderRef nodeid is not the singleUserApi +*/ + +int Dbdict::checkSingleUserMode(Uint32 senderRef) +{ + Uint32 nodeId = refToNode(senderRef); + return + getNodeState().getSingleUserMode() && + (getNodeInfo(nodeId).m_type != NodeInfo::DB) && + (nodeId != getNodeState().getSingleUserApi()); +} + CArray g_key_descriptor_pool; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index 49b85affdcd..6fda440f753 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -1997,6 +1997,8 @@ private: int getMetaTable(MetaData::Table& table, const char* tableName); int getMetaAttribute(MetaData::Attribute& attribute, const MetaData::Table& table, Uint32 attributeId); int getMetaAttribute(MetaData::Attribute& attribute, const MetaData::Table& table, const char* attributeName); + + int checkSingleUserMode(Uint32 senderRef); }; #endif diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index a3a986b2929..e221a26182e 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -30,12 +30,14 @@ waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout); enum ndb_waiter_options { - OPT_WAIT_STATUS_NOT_STARTED = NDB_STD_OPTIONS_LAST + OPT_WAIT_STATUS_NOT_STARTED = NDB_STD_OPTIONS_LAST, + OPT_WAIT_STATUS_SINGLE_USER }; NDB_STD_OPTS_VARS; static int _no_contact = 0; static int _not_started = 0; +static int _single_user = 0; static int _timeout = 120; const char *load_default_groups[]= { "mysql_cluster",0 }; @@ -49,6 +51,10 @@ static struct my_option my_long_options[] = { "not-started", OPT_WAIT_STATUS_NOT_STARTED, "Wait for cluster not started", (gptr*) &_not_started, (gptr*) &_not_started, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "single-user", OPT_WAIT_STATUS_SINGLE_USER, + "Wait for cluster to enter single user mode", + (gptr*) &_single_user, (gptr*) &_single_user, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { "timeout", 't', "Timeout to wait", (gptr*) &_timeout, (gptr*) &_timeout, 0, GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 }, @@ -90,6 +96,10 @@ int main(int argc, char** argv){ { wait_status= NDB_MGM_NODE_STATUS_NOT_STARTED; } + else if (_single_user) + { + wait_status= NDB_MGM_NODE_STATUS_SINGLEUSER; + } else { wait_status= NDB_MGM_NODE_STATUS_STARTED; From 3dbfc95c334e9acbaa0185e387fc2af2e986d3ff Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Mar 2007 16:39:13 +0700 Subject: [PATCH 2/2] ndb single user basic test --- mysql-test/r/ndb_single_user.result | 46 ++++++++++++++++ mysql-test/t/ndb_single_user.test | 84 +++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 mysql-test/r/ndb_single_user.result create mode 100644 mysql-test/t/ndb_single_user.test diff --git a/mysql-test/r/ndb_single_user.result b/mysql-test/r/ndb_single_user.result new file mode 100644 index 00000000000..711d343fffb --- /dev/null +++ b/mysql-test/r/ndb_single_user.result @@ -0,0 +1,46 @@ +use test; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +create table t1 (a int key, b int unique, c int) engine ndb; +ERROR HY000: Can't create table './test/t1.frm' (errno: 155) +create table t1 (a int key, b int unique, c int) engine ndb; +insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0); +create table t2 as select * from t1; +select * from t1 where a = 1; +a b c +1 1 0 +select * from t1 where b = 4; +a b c +4 4 0 +select * from t1 where a > 4 order by a; +a b c +5 5 0 +6 6 0 +7 7 0 +8 8 0 +9 9 0 +10 10 0 +update t1 set b=102 where a = 2; +update t1 set b=103 where b = 3; +update t1 set b=b+100; +update t1 set b=b+100 where a > 7; +delete from t1; +insert into t1 select * from t2; +drop table t1; +ERROR 42S02: Unknown table 't1' +create index new_index on t1 (c); +ERROR 42S02: Table 'test.t1' doesn't exist +insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0); +ERROR 42S02: Table 'test.t1' doesn't exist +select * from t1 where a = 1; +ERROR 42S02: Table 'test.t1' doesn't exist +select * from t1 where b = 4; +ERROR 42S02: Table 'test.t1' doesn't exist +update t1 set b=102 where a = 2; +ERROR 42S02: Table 'test.t1' doesn't exist +update t1 set b=103 where b = 3; +ERROR 42S02: Table 'test.t1' doesn't exist +update t1 set b=b+100; +ERROR 42S02: Table 'test.t1' doesn't exist +update t1 set b=b+100 where a > 7; +ERROR 42S02: Table 'test.t1' doesn't exist +drop table t1; diff --git a/mysql-test/t/ndb_single_user.test b/mysql-test/t/ndb_single_user.test new file mode 100644 index 00000000000..c655124f79f --- /dev/null +++ b/mysql-test/t/ndb_single_user.test @@ -0,0 +1,84 @@ +-- source include/have_ndb.inc +-- source include/have_multi_ndb.inc +-- source include/ndb_default_cluster.inc +-- source include/not_embedded.inc + +--disable_warnings +use test; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +--enable_warnings + +# operations allowed while cluster is in single user mode + +--connection server1 +--let $node_id= `SHOW STATUS LIKE 'Ndb_cluster_node_id'` +--disable_query_log +--eval set @node_id= SUBSTRING('$node_id', 20)+0 +--enable_query_log +--let $node_id= `SELECT @node_id` +--exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "enter single user mode $node_id" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" --single-user >> $NDB_TOOLS_OUTPUT + +# verify that we are indeed in single user mode +--connection server2 +--error 1005 +create table t1 (a int key, b int unique, c int) engine ndb; + +# test some sql on first mysqld +--connection server1 +create table t1 (a int key, b int unique, c int) engine ndb; +insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0); +create table t2 as select * from t1; +# read with pk +select * from t1 where a = 1; +# read with unique index +select * from t1 where b = 4; +# read with ordered index +select * from t1 where a > 4 order by a; +# update with pk +update t1 set b=102 where a = 2; +# update with unique index +update t1 set b=103 where b = 3; +# update with full table scan +update t1 set b=b+100; +# update with ordered insex scan +update t1 set b=b+100 where a > 7; +# delete with full table scan +delete from t1; +insert into t1 select * from t2; + +# test some sql on other mysqld +--connection server2 +--error 1051 +drop table t1; +--error 1146 +#--error 1296 +create index new_index on t1 (c); +--error 1146 +#--error 1296 +insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0); +--error 1146 +#--error 1296 +select * from t1 where a = 1; +--error 1146 +#--error 1296 +select * from t1 where b = 4; +--error 1146 +#--error 1296 +update t1 set b=102 where a = 2; +--error 1146 +#--error 1296 +update t1 set b=103 where b = 3; +--error 1146 +#--error 1296 +update t1 set b=b+100; +--error 1146 +#--error 1296 +update t1 set b=b+100 where a > 7; + +--exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "exit single user mode" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +# cleanup +--connection server1 +drop table t1;