From c5f150349373697c3a137399a9ba081afb958d7a Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Wed, 9 May 2007 14:14:27 +0200 Subject: [PATCH 01/30] Bug#26342 auto_increment_increment AND auto_increment_offset REALLY REALLY anger NDB cluster, implemented support for auto_increment_offset and auto_increment_increment for Ndb --- mysql-test/r/ndb_insert.result | 169 +++++++++++++++++++++++++++++++++ mysql-test/t/ndb_insert.test | 137 ++++++++++++++++++++++++++ ndb/include/ndbapi/Ndb.hpp | 9 +- ndb/src/ndbapi/Ndb.cpp | 95 +++++++++++++----- sql/ha_ndbcluster.cc | 18 ++-- sql/handler.cc | 6 +- sql/handler.h | 3 +- 7 files changed, 401 insertions(+), 36 deletions(-) diff --git a/mysql-test/r/ndb_insert.result b/mysql-test/r/ndb_insert.result index e7275bde2b8..b5349ecb59c 100644 --- a/mysql-test/r/ndb_insert.result +++ b/mysql-test/r/ndb_insert.result @@ -657,3 +657,172 @@ a b 2 NULL 3 NULL drop table t1; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +1 1 0 +11 2 1 +21 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_offset=5; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +SELECT * FROM t1 ORDER BY pk; +pk b c +5 1 0 +15 2 1 +25 3 2 +27 4 3 +35 5 4 +99 6 5 +105 7 6 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +7 +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_increment=2; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +1 1 0 +3 2 1 +5 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +7 1 0 +8 2 1 +9 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 3; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +5 1 0 +15 2 1 +25 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +15 1 0 +25 2 1 +35 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 5; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +5 1 0 +15 2 1 +25 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 100; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +105 1 0 +115 2 1 +125 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; diff --git a/mysql-test/t/ndb_insert.test b/mysql-test/t/ndb_insert.test index f346b7dc4ab..b8f00d6f6aa 100644 --- a/mysql-test/t/ndb_insert.test +++ b/mysql-test/t/ndb_insert.test @@ -639,4 +639,141 @@ insert ignore into t1 values (1,0), (2,0), (2,null), (3,null); select * from t1 order by a; drop table t1; +# Bug#26342 auto_increment_increment AND auto_increment_offset REALLY REALLY anger NDB cluster + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM; + +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_offset=5; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_increment=2; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; + +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 3; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 5; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 100; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + # End of 4.1 tests diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index b3c9acd4e20..f83db77739e 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -1388,9 +1388,11 @@ public: * @return 0 or -1 on error, and tupleId in out parameter */ int getAutoIncrementValue(const char* aTableName, - Uint64 & tupleId, Uint32 cacheSize); + Uint64 & tupleId, Uint32 cacheSize, + Uint64 step = 1, Uint64 start = 1); int getAutoIncrementValue(const NdbDictionary::Table * aTable, - Uint64 & tupleId, Uint32 cacheSize); + Uint64 & tupleId, Uint32 cacheSize, + Uint64 step = 1, Uint64 start = 1); int readAutoIncrementValue(const char* aTableName, Uint64 & tupleId); int readAutoIncrementValue(const NdbDictionary::Table * aTable, @@ -1401,7 +1403,8 @@ public: Uint64 tupleId, bool increase); private: int getTupleIdFromNdb(Ndb_local_table_info* info, - Uint64 & tupleId, Uint32 cacheSize); + Uint64 & tupleId, Uint32 cacheSize, + Uint64 step = 1, Uint64 start = 1 ); int readTupleIdFromNdb(Ndb_local_table_info* info, Uint64 & tupleId); int setTupleIdInNdb(Ndb_local_table_info* info, diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index 449f287dc1d..941bfc88b24 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -767,17 +767,27 @@ Ndb::getNodeId() } /**************************************************************************** -Uint64 getTupleIdFromNdb( Uint32 aTableId, Uint32 cacheSize ); +Uint64 getAutoIncrementValue( const char* aTableName, + Uint64 & tupleId, + Uint32 cacheSize, + Uint64 step, + Uint64 start); -Parameters: aTableId : The TableId. - cacheSize: Prefetch this many values -Remark: Returns a new TupleId to the application. - The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId. - It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp. +Parameters: aTableName (IN) : The table name. + autoValue (OUT) : Returns new autoincrement value + cacheSize (IN) : Prefetch this many values + step (IN) : Specifies the step between the + autoincrement values. + start (IN) : Start value for first value +Remark: Returns a new autoincrement value to the application. + The autoincrement values can be increased by steps + (default 1) and a number of values can be prefetched + by specifying cacheSize (default 10). ****************************************************************************/ int Ndb::getAutoIncrementValue(const char* aTableName, - Uint64 & tupleId, Uint32 cacheSize) + Uint64 & autoValue, Uint32 cacheSize, + Uint64 step, Uint64 start) { DBUG_ENTER("Ndb::getAutoIncrementValue"); BaseString internal_tabname(internalize_table_name(aTableName)); @@ -788,15 +798,17 @@ Ndb::getAutoIncrementValue(const char* aTableName, theError.code = theDictionary->getNdbError().code; DBUG_RETURN(-1); } - if (getTupleIdFromNdb(info, tupleId, cacheSize) == -1) + DBUG_PRINT("info", ("step %lu", (ulong) step)); + if (getTupleIdFromNdb(info, autoValue, cacheSize, step, start) == -1) DBUG_RETURN(-1); - DBUG_PRINT("info", ("value %lu", (ulong) tupleId)); + DBUG_PRINT("info", ("value %lu", (ulong) autoValue)); DBUG_RETURN(0); } int Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, - Uint64 & tupleId, Uint32 cacheSize) + Uint64 & autoValue, Uint32 cacheSize, + Uint64 step, Uint64 start) { DBUG_ENTER("Ndb::getAutoIncrementValue"); assert(aTable != 0); @@ -809,36 +821,73 @@ Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, theError.code = theDictionary->getNdbError().code; DBUG_RETURN(-1); } - if (getTupleIdFromNdb(info, tupleId, cacheSize) == -1) + DBUG_PRINT("info", ("step %lu", (ulong) step)); + if (getTupleIdFromNdb(info, autoValue, cacheSize, step, start) == -1) DBUG_RETURN(-1); - DBUG_PRINT("info", ("value %lu", (ulong)tupleId)); + DBUG_PRINT("info", ("value %lu", (ulong) autoValue)); DBUG_RETURN(0); } int Ndb::getTupleIdFromNdb(Ndb_local_table_info* info, - Uint64 & tupleId, Uint32 cacheSize) + Uint64 & tupleId, Uint32 cacheSize, + Uint64 step, Uint64 start) { +/* + Returns a new TupleId to the application. + The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId. + It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp. + In most cases step= start= 1, in which case we get: + 1,2,3,4,5,... + If step=10 and start=5 and first number is 1, we get: + 5,15,25,35,... +*/ DBUG_ENTER("Ndb::getTupleIdFromNdb"); - if (info->m_first_tuple_id != info->m_last_tuple_id) + DBUG_PRINT("info", ("Step %lu (%lu,%lu)", (ulong) step, (ulong) info->m_first_tuple_id, (ulong) info->m_last_tuple_id)); + /* + Check if the next value can be taken from the pre-fetched + sequence. + */ + if (info->m_first_tuple_id != info->m_last_tuple_id && + info->m_first_tuple_id + step <= info->m_last_tuple_id) { assert(info->m_first_tuple_id < info->m_last_tuple_id); - tupleId = ++info->m_first_tuple_id; - DBUG_PRINT("info", ("next cached value %lu", (ulong)tupleId)); + info->m_first_tuple_id += step; + tupleId = info->m_first_tuple_id; + DBUG_PRINT("info", ("Next cached value %lu", (ulong) tupleId)); } else { + /* + If start value is greater than step it is ignored + */ + Uint64 offset = (start > step) ? 1 : start; + + /* + Pre-fetch a number of values depending on cacheSize + */ if (cacheSize == 0) cacheSize = 1; - DBUG_PRINT("info", ("reading %u values from database", (uint)cacheSize)); + + DBUG_PRINT("info", ("Reading %u values from database", (uint)cacheSize)); /* * reserve next cacheSize entries in db. adds cacheSize to NEXTID - * and returns first tupleId in the new range. + * and returns first tupleId in the new range. If tupleId's are + * incremented in steps then multiply the cacheSize with step size. */ - Uint64 opValue = cacheSize; + Uint64 opValue = cacheSize * step; + if (opTupleIdOnNdb(info, opValue, 0) == -1) DBUG_RETURN(-1); - tupleId = opValue; + DBUG_PRINT("info", ("Next value fetched from database %lu", (ulong) opValue)); + DBUG_PRINT("info", ("Increasing %lu by offset %lu, increment is %lu", (ulong) (ulong) opValue, (ulong) offset, (ulong) step)); + Uint64 current, next; + next = ((Uint64) (opValue + step - offset)) / step; + next = next * step + offset; + current = (next < step) ? next : next - step; + tupleId = (opValue <= current) ? current : next; + DBUG_PRINT("info", ("Returning %lu", (ulong) tupleId)); + info->m_first_tuple_id = tupleId; } DBUG_RETURN(0); } @@ -1065,9 +1114,9 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op) } else { - DBUG_PRINT("info", - ("Setting next auto increment value (db) to %lu", - (ulong)opValue)); + DBUG_PRINT("info", + ("Setting next auto increment value (db) to %lu", + (ulong)opValue)); info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1; } break; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 9b48e0d4f38..175a81e226c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2264,12 +2264,10 @@ int ha_ndbcluster::write_row(byte *record) if (has_auto_increment) { int error; - + m_skip_auto_increment= FALSE; if ((error= update_auto_increment())) DBUG_RETURN(error); - /* Ensure that handler is always called for auto_increment values */ - thd->next_insert_id= 0; m_skip_auto_increment= !auto_increment_column_changed; } } @@ -2312,8 +2310,10 @@ int ha_ndbcluster::write_row(byte *record) int ret; Uint64 auto_value; uint retries= NDB_AUTO_INCREMENT_RETRIES; + do { - ret= ndb->getAutoIncrementValue((const NDBTAB *) m_table, auto_value, 1); + ret= ndb->getAutoIncrementValue((const NDBTAB *) m_table, + auto_value, 1); } while (ret == -1 && --retries && ndb->getNdbError().status == NdbError::TemporaryError); @@ -2322,7 +2322,7 @@ int ha_ndbcluster::write_row(byte *record) if (set_hidden_key(op, table->s->fields, (const byte*)&auto_value)) ERR_RETURN(op->getNdbError()); } - else + else { if ((res= set_primary_key_from_record(op, record))) return res; @@ -4841,6 +4841,8 @@ ulonglong ha_ndbcluster::get_auto_increment() { int cache_size; Uint64 auto_value; + Uint64 step= current_thd->variables.auto_increment_increment; + Uint64 start= current_thd->variables.auto_increment_offset; DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); Ndb *ndb= get_ndb(); @@ -4861,7 +4863,8 @@ ulonglong ha_ndbcluster::get_auto_increment() ret= m_skip_auto_increment ? ndb->readAutoIncrementValue((const NDBTAB *) m_table, auto_value) : - ndb->getAutoIncrementValue((const NDBTAB *) m_table, auto_value, cache_size); + ndb->getAutoIncrementValue((const NDBTAB *) m_table, + auto_value, cache_size, step, start); } while (ret == -1 && --retries && ndb->getNdbError().status == NdbError::TemporaryError); @@ -4894,7 +4897,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): HA_NEED_READ_RANGE_BUFFER | HA_CAN_GEOMETRY | HA_CAN_BIT_FIELD | - HA_PARTIAL_COLUMN_READ), + HA_PARTIAL_COLUMN_READ | + HA_EXTERNAL_AUTO_INCREMENT), m_share(0), m_use_write(FALSE), m_ignore_dup_key(FALSE), diff --git a/sql/handler.cc b/sql/handler.cc index c6c31593a5f..31c3827dc25 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1598,6 +1598,8 @@ int handler::update_auto_increment() ulonglong nr; THD *thd= table->in_use; struct system_variables *variables= &thd->variables; + bool external_auto_increment= + table->file->table_flags() & HA_EXTERNAL_AUTO_INCREMENT; DBUG_ENTER("handler::update_auto_increment"); /* @@ -1615,12 +1617,12 @@ int handler::update_auto_increment() adjust_next_insert_id_after_explicit_value(nr); DBUG_RETURN(0); } - if (!(nr= thd->next_insert_id)) + if (external_auto_increment || !(nr= thd->next_insert_id)) { if ((nr= get_auto_increment()) == ~(ulonglong) 0) DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED); // Mark failure - if (variables->auto_increment_increment != 1) + if (!external_auto_increment && variables->auto_increment_increment != 1) nr= next_insert_id(nr-1, variables); /* Update next row based on the found value. This way we don't have to diff --git a/sql/handler.h b/sql/handler.h index 9863d541b5f..8847d0306fb 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -93,7 +93,8 @@ #define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */ #define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */ #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30) - +/* The storage engine manages auto_increment itself */ +#define HA_EXTERNAL_AUTO_INCREMENT (1 << 31) /* bits in index_flags(index_number) for what you can do with index */ #define HA_READ_NEXT 1 /* TODO really use this flag */ From 11e98f4126ab2ffa1538111ee8dedd686bfa45d3 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Wed, 9 May 2007 17:09:06 +0200 Subject: [PATCH 02/30] Ndb.hpp, Ndb.cpp, ha_ndbcluster.cc: Bug#26342 auto_increment_increment AND auto_increment_offset REALLY REALLY anger NDB cluster, implemented support for auto_increment_offset and auto_increment --- sql/ha_ndbcluster.cc | 5 +- storage/ndb/include/ndbapi/Ndb.hpp | 11 ++-- storage/ndb/src/ndbapi/Ndb.cpp | 92 ++++++++++++++++++++++-------- 3 files changed, 79 insertions(+), 29 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index be0571de02a..da63ca8361f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6056,7 +6056,7 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, ulonglong *nb_reserved_values) -{ +{ int cache_size; Uint64 auto_value; DBUG_ENTER("get_auto_increment"); @@ -6080,7 +6080,8 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, ret= m_skip_auto_increment ? ndb->readAutoIncrementValue(m_table, g.range, auto_value) : - ndb->getAutoIncrementValue(m_table, g.range, auto_value, cache_size); + ndb->getAutoIncrementValue(m_table, g.range, + auto_value, cache_size, increment, offset); } while (ret == -1 && --retries && ndb->getNdbError().status == NdbError::TemporaryError); diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp index 5f96408ea30..ae2eefff1b2 100644 --- a/storage/ndb/include/ndbapi/Ndb.hpp +++ b/storage/ndb/include/ndbapi/Ndb.hpp @@ -1488,12 +1488,15 @@ public: int initAutoIncrement(); int getAutoIncrementValue(const char* aTableName, - Uint64 & tupleId, Uint32 cacheSize); + Uint64 & tupleId, Uint32 cacheSize, + Uint64 step = 1, Uint64 start = 1); int getAutoIncrementValue(const NdbDictionary::Table * aTable, - Uint64 & tupleId, Uint32 cacheSize); + Uint64 & tupleId, Uint32 cacheSize, + Uint64 step = 1, Uint64 start = 1); int getAutoIncrementValue(const NdbDictionary::Table * aTable, TupleIdRange & range, Uint64 & tupleId, - Uint32 cacheSize); + Uint32 cacheSize, + Uint64 step = 1, Uint64 start = 1); int readAutoIncrementValue(const char* aTableName, Uint64 & tupleId); int readAutoIncrementValue(const NdbDictionary::Table * aTable, @@ -1510,7 +1513,7 @@ public: private: int getTupleIdFromNdb(const NdbTableImpl* table, TupleIdRange & range, Uint64 & tupleId, - Uint32 cacheSize); + Uint32 cacheSize, Uint64 step = 1, Uint64 start = 1); int readTupleIdFromNdb(const NdbTableImpl* table, TupleIdRange & range, Uint64 & tupleId); int setTupleIdInNdb(const NdbTableImpl* table, diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp index 78b7af5522b..84ff477b59b 100644 --- a/storage/ndb/src/ndbapi/Ndb.cpp +++ b/storage/ndb/src/ndbapi/Ndb.cpp @@ -754,17 +754,27 @@ Ndb::getNodeId() } /**************************************************************************** -Uint64 getTupleIdFromNdb( Uint32 aTableId, Uint32 cacheSize ); +Uint64 getAutoIncrementValue( const char* aTableName, + Uint64 & autoValue, + Uint32 cacheSize, + Uint64 step, + Uint64 start); -Parameters: aTableId : The TableId. - cacheSize: Prefetch this many values -Remark: Returns a new TupleId to the application. - The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId. - It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp. +Parameters: aTableName (IN) : The table name. + autoValue (OUT) : Returns new autoincrement value + cacheSize (IN) : Prefetch this many values + step (IN) : Specifies the step between the + autoincrement values. + start (IN) : Start value for first value +Remark: Returns a new autoincrement value to the application. + The autoincrement values can be increased by steps + (default 1) and a number of values can be prefetched + by specifying cacheSize (default 10). ****************************************************************************/ int Ndb::getAutoIncrementValue(const char* aTableName, - Uint64 & tupleId, Uint32 cacheSize) + Uint64 & autoValue, Uint32 cacheSize, + Uint64 step, Uint64 start) { DBUG_ENTER("Ndb::getAutoIncrementValue"); ASSERT_NOT_MYSQLD; @@ -778,15 +788,16 @@ Ndb::getAutoIncrementValue(const char* aTableName, } const NdbTableImpl* table = info->m_table_impl; TupleIdRange & range = info->m_tuple_id_range; - if (getTupleIdFromNdb(table, range, tupleId, cacheSize) == -1) + if (getTupleIdFromNdb(table, range, autoValue, cacheSize, step, start) == -1) DBUG_RETURN(-1); - DBUG_PRINT("info", ("value %lu", (ulong) tupleId)); + DBUG_PRINT("info", ("value %lu", (ulong) autoValue)); DBUG_RETURN(0); } int Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, - Uint64 & tupleId, Uint32 cacheSize) + Uint64 & autoValue, Uint32 cacheSize, + Uint64 step, Uint64 start) { DBUG_ENTER("Ndb::getAutoIncrementValue"); ASSERT_NOT_MYSQLD; @@ -801,51 +812,86 @@ Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, DBUG_RETURN(-1); } TupleIdRange & range = info->m_tuple_id_range; - if (getTupleIdFromNdb(table, range, tupleId, cacheSize) == -1) + if (getTupleIdFromNdb(table, range, autoValue, cacheSize, step, start) == -1) DBUG_RETURN(-1); - DBUG_PRINT("info", ("value %lu", (ulong)tupleId)); + DBUG_PRINT("info", ("value %lu", (ulong)autoValue)); DBUG_RETURN(0); } int Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, - TupleIdRange & range, Uint64 & tupleId, - Uint32 cacheSize) + TupleIdRange & range, Uint64 & autoValue, + Uint32 cacheSize, Uint64 step, Uint64 start) { DBUG_ENTER("Ndb::getAutoIncrementValue"); assert(aTable != 0); const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable); - if (getTupleIdFromNdb(table, range, tupleId, cacheSize) == -1) + if (getTupleIdFromNdb(table, range, autoValue, cacheSize, step, start) == -1) DBUG_RETURN(-1); - DBUG_PRINT("info", ("value %lu", (ulong)tupleId)); + DBUG_PRINT("info", ("value %lu", (ulong)autoValue)); DBUG_RETURN(0); } int Ndb::getTupleIdFromNdb(const NdbTableImpl* table, - TupleIdRange & range, Uint64 & tupleId, Uint32 cacheSize) + TupleIdRange & range, Uint64 & tupleId, + Uint32 cacheSize, Uint64 step, Uint64 start) { +/* + Returns a new TupleId to the application. + The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId. + It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp. + In most cases step= start= 1, in which case we get: + 1,2,3,4,5,... + If step=10 and start=5 and first number is 1, we get: + 5,15,25,35,... +*/ DBUG_ENTER("Ndb::getTupleIdFromNdb"); - if (range.m_first_tuple_id != range.m_last_tuple_id) + /* + Check if the next value can be taken from the pre-fetched + sequence. + */ + if (range.m_first_tuple_id != range.m_last_tuple_id && + range.m_first_tuple_id + step <= range.m_last_tuple_id) { assert(range.m_first_tuple_id < range.m_last_tuple_id); - tupleId = ++range.m_first_tuple_id; - DBUG_PRINT("info", ("next cached value %lu", (ulong)tupleId)); + range.m_first_tuple_id += step; + tupleId = range.m_first_tuple_id; + DBUG_PRINT("info", ("Next cached value %lu", (ulong) tupleId)); } else { + /* + If start value is greater than step it is ignored + */ + Uint64 offset = (start > step) ? 1 : start; + + /* + Pre-fetch a number of values depending on cacheSize + */ if (cacheSize == 0) cacheSize = 1; + DBUG_PRINT("info", ("reading %u values from database", (uint)cacheSize)); /* * reserve next cacheSize entries in db. adds cacheSize to NEXTID - * and returns first tupleId in the new range. + * and returns first tupleId in the new range. If tupleId's are + * incremented in steps then multiply the cacheSize with step size. */ - Uint64 opValue = cacheSize; + Uint64 opValue = cacheSize * step; + if (opTupleIdOnNdb(table, range, opValue, 0) == -1) DBUG_RETURN(-1); - tupleId = opValue; + DBUG_PRINT("info", ("Next value fetched from database %lu", (ulong) opValue)); + DBUG_PRINT("info", ("Increasing %lu by offset %lu, increment is %lu", (ulong) (ulong) opValue, (ulong) offset, (ulong) step)); + Uint64 current, next; + next = ((Uint64) (opValue + step - offset)) / step; + next = next * step + offset; + current = (next < step) ? next : next - step; + tupleId = (opValue <= current) ? current : next; + DBUG_PRINT("info", ("Returning %lu", (ulong) tupleId)); + range.m_first_tuple_id = tupleId; } DBUG_RETURN(0); } From 03fc4e6ca0a92f20bdb1c858f39938b1a51bfe95 Mon Sep 17 00:00:00 2001 From: "pekka@clam.ndb.mysql.com/ndb15.mysql.com" <> Date: Fri, 8 Jun 2007 12:27:52 +0200 Subject: [PATCH 03/30] ndb - bug#28724 for blobs, op flag to not set error on trans (fix, recommit) --- storage/ndb/include/ndbapi/NdbOperation.hpp | 7 +++++++ storage/ndb/src/ndbapi/NdbBlob.cpp | 3 +++ storage/ndb/src/ndbapi/NdbOperation.cpp | 8 ++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/storage/ndb/include/ndbapi/NdbOperation.hpp b/storage/ndb/include/ndbapi/NdbOperation.hpp index 0fa2cac0a32..06111941df4 100644 --- a/storage/ndb/include/ndbapi/NdbOperation.hpp +++ b/storage/ndb/include/ndbapi/NdbOperation.hpp @@ -1042,6 +1042,13 @@ protected: */ Int8 m_abortOption; + /* + * For blob impl, option to not propagate error to trans level. + * Could be AO_IgnoreError variant if we want it public. + * Ignored unless AO_IgnoreError is also set. + */ + Int8 m_noErrorPropagation; + friend struct Ndb_free_list_t; }; diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp index 25dcafdef53..24d648b0241 100644 --- a/storage/ndb/src/ndbapi/NdbBlob.cpp +++ b/storage/ndb/src/ndbapi/NdbBlob.cpp @@ -1261,6 +1261,7 @@ NdbBlob::deletePartsUnknown(Uint32 part) DBUG_RETURN(-1); } tOp->m_abortOption= NdbOperation::AO_IgnoreError; + tOp->m_noErrorPropagation = true; n++; } DBUG_PRINT("info", ("bat=%u", bat)); @@ -1597,6 +1598,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) } if (isWriteOp()) { tOp->m_abortOption = NdbOperation::AO_IgnoreError; + tOp->m_noErrorPropagation = true; } theHeadInlineReadOp = tOp; // execute immediately @@ -1643,6 +1645,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) } if (isWriteOp()) { tOp->m_abortOption = NdbOperation::AO_IgnoreError; + tOp->m_noErrorPropagation = true; } theHeadInlineReadOp = tOp; // execute immediately diff --git a/storage/ndb/src/ndbapi/NdbOperation.cpp b/storage/ndb/src/ndbapi/NdbOperation.cpp index 903372ddb9d..50531292e40 100644 --- a/storage/ndb/src/ndbapi/NdbOperation.cpp +++ b/storage/ndb/src/ndbapi/NdbOperation.cpp @@ -76,7 +76,8 @@ NdbOperation::NdbOperation(Ndb* aNdb, NdbOperation::Type aType) : m_keyInfoGSN(GSN_KEYINFO), m_attrInfoGSN(GSN_ATTRINFO), theBlobList(NULL), - m_abortOption(-1) + m_abortOption(-1), + m_noErrorPropagation(false) { theReceiver.init(NdbReceiver::NDB_OPERATION, this); theError.code = 0; @@ -101,7 +102,8 @@ NdbOperation::setErrorCode(int anErrorCode) theError.code = anErrorCode; theNdbCon->theErrorLine = theErrorLine; theNdbCon->theErrorOperation = this; - theNdbCon->setOperationErrorCode(anErrorCode); + if (!(m_abortOption == AO_IgnoreError && m_noErrorPropagation)) + theNdbCon->setOperationErrorCode(anErrorCode); } /****************************************************************************** @@ -116,6 +118,7 @@ NdbOperation::setErrorCodeAbort(int anErrorCode) theError.code = anErrorCode; theNdbCon->theErrorLine = theErrorLine; theNdbCon->theErrorOperation = this; + // ignore m_noErrorPropagation theNdbCon->setOperationErrorCodeAbort(anErrorCode); } @@ -161,6 +164,7 @@ NdbOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection){ theMagicNumber = 0xABCDEF01; theBlobList = NULL; m_abortOption = -1; + m_noErrorPropagation = false; m_no_disk_flag = 1; tSignal = theNdb->getSignal(); From 352e93df736f34ee5c2acdb66a9b38838f138a17 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Mon, 11 Jun 2007 17:19:20 +0200 Subject: [PATCH 04/30] internal interface to ndb (to be used by e.g. ndb_restore) --- storage/ndb/include/ndbapi/Ndb.hpp | 1 + .../ndb/src/ndbapi/NdbEventOperationImpl.cpp | 3 ++- storage/ndb/src/ndbapi/ndb_internal.hpp | 27 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 storage/ndb/src/ndbapi/ndb_internal.hpp diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp index 5f96408ea30..e677616f43b 100644 --- a/storage/ndb/include/ndbapi/Ndb.hpp +++ b/storage/ndb/include/ndbapi/Ndb.hpp @@ -1055,6 +1055,7 @@ class Ndb friend class NdbDictInterface; friend class NdbBlob; friend class NdbImpl; + friend class Ndb_internal; #endif public: diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp index 00acfe62ad9..bfedf30d201 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -41,6 +41,7 @@ #include #include "NdbEventOperationImpl.hpp" #include +#include "ndb_internal.hpp" #include extern EventLogger g_eventLogger; @@ -2838,7 +2839,7 @@ send_report: data[5]= apply_gci >> 32; data[6]= latest_gci & ~(Uint32)0; data[7]= latest_gci >> 32; - m_ndb->theImpl->send_event_report(data,8); + Ndb_internal().send_event_report(m_ndb, data,8); #ifdef VM_TRACE assert(m_total_alloc >= m_free_data_sz); #endif diff --git a/storage/ndb/src/ndbapi/ndb_internal.hpp b/storage/ndb/src/ndbapi/ndb_internal.hpp new file mode 100644 index 00000000000..488946dec83 --- /dev/null +++ b/storage/ndb/src/ndbapi/ndb_internal.hpp @@ -0,0 +1,27 @@ +/* Copyright (C) 2007 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include + +class Ndb_internal +{ +private: + friend class NdbEventBuffer; + Ndb_internal() {} + virtual ~Ndb_internal() {} + int send_event_report(Ndb *ndb, Uint32 *data, Uint32 length) + { return ndb->theImpl->send_event_report(data, length); } +}; From 5556ec7ceffbc2f906b50d6cfb58fda6b37fe234 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Mon, 11 Jun 2007 17:28:52 +0200 Subject: [PATCH 05/30] change include file --- storage/ndb/src/ndbapi/ndb_internal.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/ndb/src/ndbapi/ndb_internal.hpp b/storage/ndb/src/ndbapi/ndb_internal.hpp index 488946dec83..2ed7a7ecc8c 100644 --- a/storage/ndb/src/ndbapi/ndb_internal.hpp +++ b/storage/ndb/src/ndbapi/ndb_internal.hpp @@ -13,8 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include +#include "NdbImpl.hpp" class Ndb_internal { From 0b58af0911960f8f8adb8a70c98c20016f0f4219 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Mon, 11 Jun 2007 17:50:39 +0200 Subject: [PATCH 06/30] make function static --- storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp | 2 +- storage/ndb/src/ndbapi/ndb_internal.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp index bfedf30d201..a82983fca8c 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -2839,7 +2839,7 @@ send_report: data[5]= apply_gci >> 32; data[6]= latest_gci & ~(Uint32)0; data[7]= latest_gci >> 32; - Ndb_internal().send_event_report(m_ndb, data,8); + Ndb_internal::send_event_report(m_ndb, data,8); #ifdef VM_TRACE assert(m_total_alloc >= m_free_data_sz); #endif diff --git a/storage/ndb/src/ndbapi/ndb_internal.hpp b/storage/ndb/src/ndbapi/ndb_internal.hpp index 2ed7a7ecc8c..f5f37f95a04 100644 --- a/storage/ndb/src/ndbapi/ndb_internal.hpp +++ b/storage/ndb/src/ndbapi/ndb_internal.hpp @@ -21,6 +21,6 @@ private: friend class NdbEventBuffer; Ndb_internal() {} virtual ~Ndb_internal() {} - int send_event_report(Ndb *ndb, Uint32 *data, Uint32 length) + static int send_event_report(Ndb *ndb, Uint32 *data, Uint32 length) { return ndb->theImpl->send_event_report(data, length); } }; From 4b8baaaed1bf405ba4bb94977b8ce449599da4b9 Mon Sep 17 00:00:00 2001 From: "jonas@perch.ndb.mysql.com" <> Date: Tue, 12 Jun 2007 09:13:42 +0200 Subject: [PATCH 07/30] ndb - bug#29044 Improve buddy high order allocation Make removeCommonArea O(1) instead of O(N) Add limit to left/right search --- .../src/kernel/blocks/dbtup/DbtupDebug.cpp | 47 +++++++++++--- .../src/kernel/blocks/dbtup/DbtupPagMan.cpp | 61 +++++++++++++------ 2 files changed, 83 insertions(+), 25 deletions(-) diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp index ecee7e867f8..9b60d5d47ed 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp @@ -76,6 +76,10 @@ Dbtup::reportMemoryUsage(Signal* signal, int incDec){ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB); } +#ifdef VM_TRACE +extern Uint32 fc_left, fc_right, fc_remove; +#endif + void Dbtup::execDUMP_STATE_ORD(Signal* signal) { @@ -157,12 +161,20 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) return; }//if #endif -#if defined VM_TRACE && 0 - if (type == 1211){ - ndbout_c("Startar modul test av Page Manager"); +#if defined VM_TRACE + if (type == 1211 || type == 1212 || type == 1213){ + Uint32 seed = time(0); + if (signal->getLength() > 1) + seed = signal->theData[1]; + ndbout_c("Startar modul test av Page Manager (seed: 0x%x)", seed); + srand(seed); Vector chunks; const Uint32 LOOPS = 1000; + Uint32 sum_req = 0; + Uint32 sum_conf = 0; + Uint32 sum_loop = 0; + Uint32 max_loop = 0; for(Uint32 i = 0; i> 3) + (sum_conf >> 4); + } switch(c){ case 0:{ // Release const int ch = rand() % chunks.size(); @@ -192,23 +211,33 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) case 2: { // Seize(n) - fail alloc += free; // Fall through + sum_req += free; + goto doalloc; } case 1: { // Seize(n) (success) - + sum_req += alloc; + doalloc: Chunk chunk; allocConsPages(alloc, chunk.pageCount, chunk.pageId); ndbrequire(chunk.pageCount <= alloc); if(chunk.pageCount != 0){ chunks.push_back(chunk); if(chunk.pageCount != alloc) { - ndbout_c(" Tried to allocate %d - only allocated %d - free: %d", - alloc, chunk.pageCount, free); + if (type == 1211) + ndbout_c(" Tried to allocate %d - only allocated %d - free: %d", + alloc, chunk.pageCount, free); } } else { ndbout_c(" Failed to alloc %d pages with %d pages free", alloc, free); } + sum_conf += chunk.pageCount; + Uint32 tot = fc_left + fc_right + fc_remove; + sum_loop += tot; + if (tot > max_loop) + max_loop = tot; + for(Uint32 i = 0; i 0) { + Uint32 loop = 0; + while (allocPageRef > 0 && + ++loop < 16) + { ljam(); pageLastPtr.i = allocPageRef - 1; c_page_pool.getPtr(pageLastPtr); @@ -258,6 +268,9 @@ void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef, remainAllocate -= listSize; }//if }//if +#ifdef VM_TRACE + fc_left++; +#endif }//while }//Dbtup::findFreeLeftNeighbours() @@ -271,7 +284,10 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef, ljam(); return; }//if - while ((allocPageRef + noPagesAllocated) < c_page_pool.getSize()) { + Uint32 loop = 0; + while ((allocPageRef + noPagesAllocated) < c_page_pool.getSize() && + ++loop < 16) + { ljam(); pageFirstPtr.i = allocPageRef + noPagesAllocated; c_page_pool.getPtr(pageFirstPtr); @@ -298,24 +314,37 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef, remainAllocate -= listSize; }//if }//if +#ifdef VM_TRACE + fc_right++; +#endif }//while }//Dbtup::findFreeRightNeighbours() void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList) { cnoOfAllocatedPages -= (1 << insList); - PagePtr pageLastPtr, pageInsPtr; + PagePtr pageLastPtr, pageInsPtr, pageHeadPtr; + pageHeadPtr.i = cfreepageList[insList]; c_page_pool.getPtr(pageInsPtr, insPageRef); ndbrequire(insList < 16); pageLastPtr.i = (pageInsPtr.i + (1 << insList)) - 1; - pageInsPtr.p->next_cluster_page = cfreepageList[insList]; + pageInsPtr.p->page_state = ZFREE_COMMON; + pageInsPtr.p->next_cluster_page = pageHeadPtr.i; pageInsPtr.p->prev_cluster_page = RNIL; pageInsPtr.p->last_cluster_page = pageLastPtr.i; cfreepageList[insList] = pageInsPtr.i; + if (pageHeadPtr.i != RNIL) + { + jam(); + c_page_pool.getPtr(pageHeadPtr); + pageHeadPtr.p->prev_cluster_page = pageInsPtr.i; + } + c_page_pool.getPtr(pageLastPtr); + pageLastPtr.p->page_state = ZFREE_COMMON; pageLastPtr.p->first_cluster_page = pageInsPtr.i; pageLastPtr.p->next_page = RNIL; }//Dbtup::insertCommonArea() @@ -323,12 +352,13 @@ void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList) void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list) { cnoOfAllocatedPages += (1 << list); - PagePtr pagePrevPtr, pageNextPtr, pageLastPtr, pageSearchPtr, remPagePtr; + PagePtr pagePrevPtr, pageNextPtr, pageLastPtr, remPagePtr; c_page_pool.getPtr(remPagePtr, remPageRef); ndbrequire(list < 16); if (cfreepageList[list] == remPagePtr.i) { ljam(); + ndbassert(remPagePtr.p->prev_cluster_page == RNIL); cfreepageList[list] = remPagePtr.p->next_cluster_page; pageNextPtr.i = cfreepageList[list]; if (pageNextPtr.i != RNIL) { @@ -337,30 +367,25 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list) pageNextPtr.p->prev_cluster_page = RNIL; }//if } else { - pageSearchPtr.i = cfreepageList[list]; - while (true) { - ljam(); - c_page_pool.getPtr(pageSearchPtr); - pagePrevPtr = pageSearchPtr; - pageSearchPtr.i = pageSearchPtr.p->next_cluster_page; - if (pageSearchPtr.i == remPagePtr.i) { - ljam(); - break; - }//if - }//while + pagePrevPtr.i = remPagePtr.p->prev_cluster_page; pageNextPtr.i = remPagePtr.p->next_cluster_page; + c_page_pool.getPtr(pagePrevPtr); pagePrevPtr.p->next_cluster_page = pageNextPtr.i; - if (pageNextPtr.i != RNIL) { + if (pageNextPtr.i != RNIL) + { ljam(); c_page_pool.getPtr(pageNextPtr); pageNextPtr.p->prev_cluster_page = pagePrevPtr.i; - }//if + } }//if remPagePtr.p->next_cluster_page= RNIL; remPagePtr.p->last_cluster_page= RNIL; remPagePtr.p->prev_cluster_page= RNIL; + remPagePtr.p->page_state = ~ZFREE_COMMON; pageLastPtr.i = (remPagePtr.i + (1 << list)) - 1; c_page_pool.getPtr(pageLastPtr); pageLastPtr.p->first_cluster_page= RNIL; + pageLastPtr.p->page_state = ~ZFREE_COMMON; + }//Dbtup::removeCommonArea() From a09ef976d396908afda095b5eca81c49fdcc1bec Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Tue, 12 Jun 2007 10:06:20 +0200 Subject: [PATCH 08/30] extend backup dump to give more info --- .../ndb/src/kernel/blocks/backup/Backup.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp index 645eb590ae3..6ad81df20be 100644 --- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp @@ -448,6 +448,41 @@ Backup::execDUMP_STATE_ORD(Signal* signal) filePtr.p->m_flags); } } + + ndbout_c("m_curr_disk_write_speed: %u m_words_written_this_period: %u m_overflow_disk_write: %u", + m_curr_disk_write_speed, m_words_written_this_period, m_overflow_disk_write); + ndbout_c("m_reset_delay_used: %u m_reset_disk_speed_time: %llu", + m_reset_delay_used, (Uint64)m_reset_disk_speed_time); + for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) + { + ndbout_c("BackupRecord %u: BackupId: %u MasterRef: %x ClientRef: %x", + ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef); + ndbout_c(" State: %u", ptr.p->slaveState.getState()); + ndbout_c(" noOfByte: %llu noOfRecords: %llu", + ptr.p->noOfBytes, ptr.p->noOfRecords); + ndbout_c(" noOfLogBytes: %llu noOfLogRecords: %llu", + ptr.p->noOfLogBytes, ptr.p->noOfLogRecords); + ndbout_c(" errorCode: %u", ptr.p->errorCode); + BackupFilePtr filePtr; + for(ptr.p->files.first(filePtr); filePtr.i != RNIL; + ptr.p->files.next(filePtr)) + { + ndbout_c(" file %u: type: %u flags: H'%x tableId: %u fragmentId: %u", + filePtr.i, filePtr.p->fileType, filePtr.p->m_flags, + filePtr.p->tableId, filePtr.p->fragmentNo); + } + if (ptr.p->slaveState.getState() == SCANNING && ptr.p->dataFilePtr != RNIL) + { + c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr); + OperationRecord & op = filePtr.p->operation; + Uint32 *tmp = NULL; + Uint32 sz = 0; + bool eof = FALSE; + bool ready = op.dataBuffer.getReadPtr(&tmp, &sz, &eof); + ndbout_c("ready: %s eof: %s", ready ? "TRUE" : "FALSE", eof ? "TRUE" : "FALSE"); + } + } + return; } if(signal->theData[0] == 24){ /** From 2606bb1ce5a9aab178f9609f8eca87342765062f Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Tue, 12 Jun 2007 10:35:21 +0200 Subject: [PATCH 09/30] Bug#29044 - memory buddy allocator "unoptimal" memory handling - add config param to have better behavior with large tables --- .../ndb/include/mgmapi/mgmapi_config_parameters.h | 2 ++ storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp | 1 + storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp | 6 ++++++ storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp | 5 +++++ storage/ndb/src/mgmsrv/ConfigInfo.cpp | 12 ++++++++++++ 5 files changed, 26 insertions(+) diff --git a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h index d0bd8be16a3..ac2cbf060fd 100644 --- a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h +++ b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -118,6 +118,8 @@ #define CFG_DB_O_DIRECT 168 +#define CFG_DB_MAX_ALLOCATE 169 + #define CFG_DB_SGA 198 /* super pool mem */ #define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */ diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index d59d5cd79f2..7845305da6c 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -2618,6 +2618,7 @@ private: ArrayPool c_page_pool; Uint32 cnoOfAllocatedPages; + Uint32 m_max_allocate_pages; Tablerec *tablerec; Uint32 cnoOfTablerec; diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index f4fd80a482a..3a8e996d435 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -308,6 +308,12 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) Uint32 noOfTriggers= 0; Uint32 tmp= 0; + + if (ndb_mgm_get_int_parameter(p, CFG_DB_MAX_ALLOCATE, &tmp)) + tmp = 32 * 1024 * 1024; + m_max_allocate_pages = (tmp + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE; + + tmp = 0; ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE_RANGE, &tmp)); initPageRangeSize(tmp); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE, &cnoOfTablerec)); diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp index 8493e0561cc..ed8f63ce3ad 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp @@ -434,6 +434,11 @@ void Dbtup::allocMoreFragPages(Fragrecord* const regFragPtr) // We will grow by 18.75% plus two more additional pages to grow // a little bit quicker in the beginning. /* -----------------------------------------------------------------*/ + + if (noAllocPages > m_max_allocate_pages) + { + noAllocPages = m_max_allocate_pages; + } Uint32 allocated = allocFragPages(regFragPtr, noAllocPages); regFragPtr->noOfPagesToGrow += allocated; }//Dbtup::allocMoreFragPages() diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp index 56aacda214d..229824c49bf 100644 --- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp @@ -1313,6 +1313,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { "0", STR_VALUE(MAX_INT_RNIL) }, + { + CFG_DB_MAX_ALLOCATE, + "MaxAllocate", + DB_TOKEN, + "Maximum size of allocation to use when allocating memory for tables", + ConfigInfo::CI_USED, + false, + ConfigInfo::CI_INT, + "32M", + "1M", + "1G" }, + { CFG_DB_MEMREPORT_FREQUENCY, "MemReportFrequency", From 17fc7a816195bb28de2af30364287fb1c00f5fa9 Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 22:54:00 +1000 Subject: [PATCH 10/30] [PATCH] BUG#29063 TESTCASE mgmapi: connect timeout set incorrectly Add test to testMgm for Connect timeout. add to autotest. Index: ndb-work/storage/ndb/test/ndbapi/testMgm.cpp =================================================================== --- storage/ndb/test/ndbapi/testMgm.cpp | 75 +++++++++++++++++++ .../ndb/test/run-test/daily-basic-tests.txt | 4 + 2 files changed, 79 insertions(+) diff --git a/storage/ndb/test/ndbapi/testMgm.cpp b/storage/ndb/test/ndbapi/testMgm.cpp index cc074087bdb..e43972c8c29 100644 --- a/storage/ndb/test/ndbapi/testMgm.cpp +++ b/storage/ndb/test/ndbapi/testMgm.cpp @@ -212,6 +212,76 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step) } } +int runTestApiConnectTimeout(NDBT_Context* ctx, NDBT_Step* step) +{ + char *mgm= ctx->getRemoteMgm(); + int result= NDBT_FAILED; + int cc= 0; + int mgmd_nodeid= 0; + ndb_mgm_reply reply; + + NdbMgmHandle h; + h= ndb_mgm_create_handle(); + ndb_mgm_set_connectstring(h, mgm); + + ndbout << "TEST connect timeout" << endl; + + ndb_mgm_set_timeout(h, 3000); + + struct timeval tstart, tend; + int secs; + timerclear(&tstart); + timerclear(&tend); + gettimeofday(&tstart,NULL); + + ndb_mgm_connect(h,0,0,0); + + gettimeofday(&tend,NULL); + + secs= tend.tv_sec - tstart.tv_sec; + ndbout << "Took about: " << secs <<" seconds"<getRemoteMgm(); @@ -727,6 +797,11 @@ TESTCASE("ApiSessionFailure", "Test failures in MGMAPI session"){ INITIALIZER(runTestApiSession); +} +TESTCASE("ApiConnectTimeout", + "Connect timeout tests for MGMAPI"){ + INITIALIZER(runTestApiConnectTimeout); + } TESTCASE("ApiTimeoutBasic", "Basic timeout tests for MGMAPI"){ diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt index 6ce2da47670..0e1cdfc647e 100644 --- a/storage/ndb/test/run-test/daily-basic-tests.txt +++ b/storage/ndb/test/run-test/daily-basic-tests.txt @@ -898,6 +898,10 @@ max-time: 120 cmd: testMgm args: -n ApiSessionFailure T1 +max-time: 15 +cmd: testMgm +args: -n ApiConnectTimeout T1 + max-time: 120 cmd: testMgm args: -n ApiTimeoutBasic T1 From 23eb8698dc5712272d8622b33c6f9de069d2e9b8 Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 22:54:14 +1000 Subject: [PATCH 11/30] [PATCH] BUG#29063 mgmapi: connect timeout set incorrectly correctly divide timeout by 1000 to convert to seconds for SocketClient Index: ndb-work/storage/ndb/src/mgmapi/mgmapi.cpp =================================================================== --- storage/ndb/src/mgmapi/mgmapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp index e7dc1d1d503..5f975da8c73 100644 --- a/storage/ndb/src/mgmapi/mgmapi.cpp +++ b/storage/ndb/src/mgmapi/mgmapi.cpp @@ -524,7 +524,7 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries, NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET; Uint32 i; SocketClient s(0, 0); - s.set_connect_timeout(handle->timeout); + s.set_connect_timeout((handle->timeout+999)/1000); if (!s.init()) { fprintf(handle->errstream, From 35006868d1a938d68d831d478b11efbc7d42c82a Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:33:37 +1000 Subject: [PATCH 12/30] [PATCH] Disable mysql_upgrade test (Bug#28560) Index: ndb-work/mysql-test/t/disabled.def =================================================================== --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index e283ca9458f..90fd997e615 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -40,3 +40,4 @@ synchronization : Bug#24529 Test 'synchronization' fails on Mac pushb #rpl_ndb_dd_advance : Bug#25913 rpl_ndb_dd_advance fails randomly ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms +mysql_upgrade : Bug#28560 test links to /usr/local/mysql/lib libraries, causes non-determinism and failures on ABI breakage From 367076371ef0e016ffcfb1bc413c6ba8d9876eac Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:33:51 +1000 Subject: [PATCH 13/30] [PATCH] Add tests for ndb variables (related to BUG#26675) This is somewhat related to BUG#26675 (ndb_connectstring not reported in show global variables) Index: ndb-work/mysql-test/r/ndb_basic.result =================================================================== --- mysql-test/r/ndb_basic.result | 21 +++++++++++++++++++++ mysql-test/t/ndb_basic.test | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index c84c7fffd66..0f28e6ac497 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -1,5 +1,26 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7; drop database if exists mysqltest; +SHOW GLOBAL STATUS LIKE 'ndb%'; +Variable_name Value +Ndb_cluster_node_id # +Ndb_config_from_host # +Ndb_config_from_port # +Ndb_number_of_data_nodes # +SHOW GLOBAL VARIABLES LIKE 'ndb%'; +Variable_name Value +ndb_autoincrement_prefetch_sz # +ndb_cache_check_time # +ndb_connectstring # +ndb_extra_logging # +ndb_force_send # +ndb_index_stat_cache_entries # +ndb_index_stat_enable # +ndb_index_stat_update_freq # +ndb_report_thresh_binlog_epoch_slip # +ndb_report_thresh_binlog_mem_usage # +ndb_use_copying_alter_table # +ndb_use_exact_count # +ndb_use_transactions # CREATE TABLE t1 ( pk1 INT NOT NULL PRIMARY KEY, attr1 INT NOT NULL, diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 870c7435d3e..6668ca86a94 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -22,6 +22,14 @@ drop database if exists mysqltest; # table handler is working # +# +# Show status and variables +# +--replace_column 2 # +SHOW GLOBAL STATUS LIKE 'ndb%'; +--replace_column 2 # +SHOW GLOBAL VARIABLES LIKE 'ndb%'; + # # Create a normal table with primary key # From 7a8961fca3a748b2a9e56947e6b6719b540a4e95 Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:34:09 +1000 Subject: [PATCH 14/30] [PATCH] BUG#29073 Store history for ndb_mgm Index: ndb-work/storage/ndb/src/mgmclient/main.cpp =================================================================== --- storage/ndb/src/mgmclient/main.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/storage/ndb/src/mgmclient/main.cpp b/storage/ndb/src/mgmclient/main.cpp index 44408362f09..429ccb27b2e 100644 --- a/storage/ndb/src/mgmclient/main.cpp +++ b/storage/ndb/src/mgmclient/main.cpp @@ -155,10 +155,31 @@ int main(int argc, char** argv){ signal(SIGPIPE, handler); com = new Ndb_mgmclient(opt_connect_str,1); int ret= 0; + BaseString histfile; if (!opt_execute_str) { + char *histfile_env= getenv("NDB_MGM_HISTFILE"); + if (histfile_env) + histfile.assign(histfile_env,strlen(histfile_env)); + else if(getenv("HOME")) + { + histfile.assign(getenv("HOME"),strlen(getenv("HOME"))); + histfile.append("/.ndb_mgm_history"); + } + if (histfile.length()) + read_history(histfile.c_str()); + ndbout << "-- NDB Cluster -- Management Client --" << endl; while(read_and_execute(_try_reconnect)); + + if (histfile.length()) + { + BaseString histfile_tmp; + histfile_tmp.assign(histfile); + histfile_tmp.append(".TMP"); + if(!write_history(histfile_tmp.c_str())) + my_rename(histfile_tmp.c_str(), histfile.c_str(), MYF(MY_WME)); + } } else { From 85eba85b403549a208b30b92918a8e9b23530299 Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:34:22 +1000 Subject: [PATCH 15/30] [PATCH] Enable test for (Closed) bug 16445 Bug was updated on May 30th by Tomas to say that hasn't been seen in PB since global dict cache rewrite. This test should probably be enabled then. Index: ndb-work/mysql-test/t/ndb_basic.test =================================================================== --- mysql-test/r/ndb_basic.result | 7 +++++++ mysql-test/t/ndb_basic.test | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 0f28e6ac497..4eddaeb1227 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -1,5 +1,12 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7; drop database if exists mysqltest; +CREATE TABLE t1 ( +pk1 INT NOT NULL PRIMARY KEY, +attr1 INT NOT NULL, +attr2 INT, +attr3 VARCHAR(10) +) ENGINE=ndbcluster; +drop table t1; SHOW GLOBAL STATUS LIKE 'ndb%'; Variable_name Value Ndb_cluster_node_id # diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 6668ca86a94..90839ce6cab 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -6,16 +6,16 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7; drop database if exists mysqltest; --enable_warnings -## workaround for bug#16445 -## remove to reproduce bug and run tests from ndb start -## and with ndb_autodiscover disabled. Fails on Linux 50 % of the times -#CREATE TABLE t1 ( -# pk1 INT NOT NULL PRIMARY KEY, -# attr1 INT NOT NULL, -# attr2 INT, -# attr3 VARCHAR(10) -#) ENGINE=ndbcluster; -#drop table t1; +# workaround for bug#16445 +# remove to reproduce bug and run tests from ndb start +# and with ndb_autodiscover disabled. Fails on Linux 50 % of the times +CREATE TABLE t1 ( + pk1 INT NOT NULL PRIMARY KEY, + attr1 INT NOT NULL, + attr2 INT, + attr3 VARCHAR(10) +) ENGINE=ndbcluster; +drop table t1; # # Basic test to show that the NDB From 155390c3a7aabdb4bc01b21500ef49437e2b321c Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:34:36 +1000 Subject: [PATCH 16/30] [PATCH] BUG#29074 preserve file timestamps in ndb_error_reporter Index: ndb-work/storage/ndb/tools/ndb_error_reporter =================================================================== --- storage/ndb/tools/ndb_error_reporter | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/ndb/tools/ndb_error_reporter b/storage/ndb/tools/ndb_error_reporter index 2b5aadb6171..7ad7a2f478a 100644 --- a/storage/ndb/tools/ndb_error_reporter +++ b/storage/ndb/tools/ndb_error_reporter @@ -62,13 +62,13 @@ foreach my $node (@nodes) (($config_get_fs)?" with filesystem":""). "\n\n"; my $recurse= ($config_get_fs)?'-r ':''; - system 'scp '.$recurse.$config_username.config($node,'host'). + system 'scp -p '.$recurse.$config_username.config($node,'host'). ':'.config($node,'datadir')."/ndb_".$node."* ". "$reportdir/\n"; } print "\n\n Copying configuration file...\n\n\t$config_file\n\n"; -system "cp $config_file $reportdir/"; +system "cp -p $config_file $reportdir/"; my $r = system 'bzip2 2>&1 > /dev/null < /dev/null'; my $outfile; From 1518abe7f96de4eb892f225cf49974b6c4ec2912 Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:52:47 +1000 Subject: [PATCH 17/30] [PATCH] Add MAINTAINERS file for NDB Index: ndb-merge/storage/ndb/MAINTAINERS =================================================================== --- storage/ndb/MAINTAINERS | 157 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 storage/ndb/MAINTAINERS diff --git a/storage/ndb/MAINTAINERS b/storage/ndb/MAINTAINERS new file mode 100644 index 00000000000..76318687dde --- /dev/null +++ b/storage/ndb/MAINTAINERS @@ -0,0 +1,157 @@ +MySQL Cluster MAINTAINERS +------------------------- + +This is a list of knowledgable people in parts of the NDB code. + +In changing that area of code, you probably want to talk to the +people who know a lot about it to look over the patch. + +When sending patches and queries, always CC the mailing list. + +If no list specified, assume internals@lists.mysql.com + +P: Person +M: Mail +L: Mailing list +W: Web page with status/info +C: Comment +SRC: Source directory (relative to this directory) +T: SCM tree type and location +S: Status, one of: + + Supported: Somebody is paid to maintain this. + Maintained: Not their primary job, but maintained. + Orphan: No current obvious maintainer. + Obsolete: Replaced by something else. + +------------------------------------------------------------- + +Binlog Injector +SRC: ha_ndbcluster_binlog.cc +C: see also row based replication +P: Stewart Smith +M: stewart@mysql.com +C: Original author +P: Tomas Ulin +M: tomas@mysql.com +C: Lots of updates +P: Martin Skold +M: martin@mysql.com +C: Metadata ops +S: Supported + +BLOBs +SRC: ha_ndbcluster.cc +SRC: src/ndbapi/NdbBlob* +P: Pekka +M: pekka@mysql.com +S: Supported + +cpcd/cpcc +SRC: src/cw/cpcd +SRC: src/cw/cpcc +C: Maintained only as part of autotest +P: Jonas Orland +M: jonas@mysql.com +S: Maintained + +cpcc-win32 +SRC: src/cw/cpcc-win32 +S: Obsolete + +Handler +SRC: ha_ndbcluster.cc +P: Martin Skold +M: martin@mysql.com +S: Supported + +Management Server +SRC: src/mgmsrv/ +P: Stewart Smith +M: stewart@mysql.com +S: Supported + +Management Client +SRC: src/mgmclient/ +P: Stewart Smith +M: stewart@mysql.com +S: Supported + +Management API +SRC: src/mgmapi/ +P: Stewart Smith +M: stewart@mysql.com +S: Supported + +NDB API Examples +SRC: ndbapi-examples/ +P: Tomas Ulin +M: tomas@mysql.com +C: Originally by Lars +P: Lars Thalmann +M: lars@mysql.com +S: Maintained + +tsman +C: Disk Data (Table Space MANager) +SRC: src/kernel/blocks/tsman.cpp +SRC: src/kernel/blocks/tsman.hpp +P: Jonas Oreland +M: jonas@mysql.com +S: Supported + +lgman +C: Disk Data (LoG MANager) +SRC: src/kernel/blocks/lgman.cpp +SRC: src/kernel/blocks/lgman.hpp +P: Jonas Oreland +M: jonas@mysql.com +S: Supported + +pgman +C: Disk Data (PaGe MANager) +SRC: src/kernel/blocks/lgman.cpp +SRC: src/kernel/blocks/lgman.hpp +P: Jonas Oreland +M: jonas@mysql.com +S: Supported + +SUMA +C: SUbscription MAnager +C: Used for replication +SRC: src/kernel/blocks/suma/ +P: Tomas Ulin +P: tomas@mysql.com +P: Jonas Oreland +P: jonas@mysql.com +S: Supported + +TRIX +C: TRiggers and IndeXs (but only online Index build) +SRC: src/kernel/blocks/trix +P: Martin Skold +P: mskold@mysql.com +S: Supported + +QMGR +C: Cluster (with a Q) ManaGeR +C: Heartbeats etc +SRC: src/kernel/blocks/qmgr +S: Supported + +NDBFS +C: NDB FileSystem +C: File System abstraction +SRC: src/kernel/blocks/ndbfs +S: Supported + +TRIX +C: TRiggers and IndeXs (but only online Index build) +SRC: src/kernel/blocks/trix +S: Supported + +TRIX +C: TRiggers and IndeXs (but only online Index build) +SRC: src/kernel/blocks/trix +S: Supported + From 13c4d317bb218c6320006582a4aaefe41c56383b Mon Sep 17 00:00:00 2001 From: "stewart@flamingspork.com[stewart]" <> Date: Wed, 13 Jun 2007 23:53:01 +1000 Subject: [PATCH 18/30] [PATCH] add knielsen as MAINTAINER of NDBAPI NdbRecord examples Index: ndb-merge/storage/ndb/MAINTAINERS =================================================================== --- storage/ndb/MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/ndb/MAINTAINERS b/storage/ndb/MAINTAINERS index 76318687dde..d1547d48234 100644 --- a/storage/ndb/MAINTAINERS +++ b/storage/ndb/MAINTAINERS @@ -92,6 +92,12 @@ P: Lars Thalmann M: lars@mysql.com S: Maintained +NDB API NdbRecord Examples +SRC: ndbapi-examples/ +P: Kristian Nielsen +M: knielsen@mysql.com +S: Maintained + tsman C: Disk Data (Table Space MANager) SRC: src/kernel/blocks/tsman.cpp From afdee6e0a5c18f30d9e7c9d2e4076566351bffd3 Mon Sep 17 00:00:00 2001 From: "stewart@willster.(none)" <> Date: Thu, 14 Jun 2007 11:59:25 +1000 Subject: [PATCH 19/30] fix build of mgm client with history - caught by pb. --- storage/ndb/src/mgmclient/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/ndb/src/mgmclient/main.cpp b/storage/ndb/src/mgmclient/main.cpp index 429ccb27b2e..7513064d273 100644 --- a/storage/ndb/src/mgmclient/main.cpp +++ b/storage/ndb/src/mgmclient/main.cpp @@ -23,6 +23,8 @@ extern "C" { #elif !defined(__NETWARE__) #include extern "C" int add_history(const char *command); /* From readline directory */ +extern "C" int read_history(const char *command); +extern "C" int write_history(const char *command); #define HAVE_READLINE #endif } @@ -158,6 +160,7 @@ int main(int argc, char** argv){ BaseString histfile; if (!opt_execute_str) { +#ifdef HAVE_READLINE char *histfile_env= getenv("NDB_MGM_HISTFILE"); if (histfile_env) histfile.assign(histfile_env,strlen(histfile_env)); @@ -168,10 +171,12 @@ int main(int argc, char** argv){ } if (histfile.length()) read_history(histfile.c_str()); +#endif ndbout << "-- NDB Cluster -- Management Client --" << endl; while(read_and_execute(_try_reconnect)); +#ifdef HAVE_READLINE if (histfile.length()) { BaseString histfile_tmp; @@ -180,6 +185,7 @@ int main(int argc, char** argv){ if(!write_history(histfile_tmp.c_str())) my_rename(histfile_tmp.c_str(), histfile.c_str(), MYF(MY_WME)); } +#endif } else { From 71bbcc0e8428f2e1c841394e25fee32289050471 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 11:26:54 +0200 Subject: [PATCH 20/30] move all error codes to ndberror.c - step 1 mgmtsrvr error codes --- storage/ndb/src/mgmsrv/MgmtSrvr.cpp | 76 +------------------------ storage/ndb/src/mgmsrv/MgmtSrvr.hpp | 39 ------------- storage/ndb/src/mgmsrv/ndb_mgmd_error.h | 33 +++++++++++ storage/ndb/src/ndbapi/ndberror.c | 30 ++++++++++ 4 files changed, 64 insertions(+), 114 deletions(-) create mode 100644 storage/ndb/src/mgmsrv/ndb_mgmd_error.h diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp index f84c79b704f..af708664a69 100644 --- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -18,6 +18,7 @@ #include "MgmtSrvr.hpp" #include "MgmtErrorReporter.hpp" +#include "ndb_mgmd_error.h" #include #include @@ -239,13 +240,6 @@ MgmtSrvr::stopEventLog() // Nothing yet } -class ErrorItem -{ -public: - int _errorCode; - const char * _errorText; -}; - bool MgmtSrvr::setEventLogFilter(int severity, int enable) { @@ -268,62 +262,6 @@ MgmtSrvr::isEventLogFilterEnabled(int severity) return g_eventLogger.isEnable((Logger::LoggerLevel)severity); } -static ErrorItem errorTable[] = -{ - {MgmtSrvr::NO_CONTACT_WITH_PROCESS, "No contact with the process (dead ?)."}, - {MgmtSrvr::PROCESS_NOT_CONFIGURED, "The process is not configured."}, - {MgmtSrvr::WRONG_PROCESS_TYPE, - "The process has wrong type. Expected a DB process."}, - {MgmtSrvr::COULD_NOT_ALLOCATE_MEMORY, "Could not allocate memory."}, - {MgmtSrvr::SEND_OR_RECEIVE_FAILED, "Send to process or receive failed."}, - {MgmtSrvr::INVALID_LEVEL, "Invalid level. Should be between 1 and 30."}, - {MgmtSrvr::INVALID_ERROR_NUMBER, "Invalid error number. Should be >= 0."}, - {MgmtSrvr::INVALID_TRACE_NUMBER, "Invalid trace number."}, - {MgmtSrvr::NOT_IMPLEMENTED, "Not implemented."}, - {MgmtSrvr::INVALID_BLOCK_NAME, "Invalid block name"}, - - {MgmtSrvr::CONFIG_PARAM_NOT_EXIST, - "The configuration parameter does not exist for the process type."}, - {MgmtSrvr::CONFIG_PARAM_NOT_UPDATEABLE, - "The configuration parameter is not possible to update."}, - {MgmtSrvr::VALUE_WRONG_FORMAT_INT_EXPECTED, - "Incorrect value. Expected integer."}, - {MgmtSrvr::VALUE_TOO_LOW, "Value is too low."}, - {MgmtSrvr::VALUE_TOO_HIGH, "Value is too high."}, - {MgmtSrvr::VALUE_WRONG_FORMAT_BOOL_EXPECTED, - "Incorrect value. Expected TRUE or FALSE."}, - - {MgmtSrvr::CONFIG_FILE_OPEN_WRITE_ERROR, - "Could not open configuration file for writing."}, - {MgmtSrvr::CONFIG_FILE_OPEN_READ_ERROR, - "Could not open configuration file for reading."}, - {MgmtSrvr::CONFIG_FILE_WRITE_ERROR, - "Write error when writing configuration file."}, - {MgmtSrvr::CONFIG_FILE_READ_ERROR, - "Read error when reading configuration file."}, - {MgmtSrvr::CONFIG_FILE_CLOSE_ERROR, "Could not close configuration file."}, - - {MgmtSrvr::CONFIG_CHANGE_REFUSED_BY_RECEIVER, - "The change was refused by the receiving process."}, - {MgmtSrvr::COULD_NOT_SYNC_CONFIG_CHANGE_AGAINST_PHYSICAL_MEDIUM, - "The change could not be synced against physical medium."}, - {MgmtSrvr::CONFIG_FILE_CHECKSUM_ERROR, - "The config file is corrupt. Checksum error."}, - {MgmtSrvr::NOT_POSSIBLE_TO_SEND_CONFIG_UPDATE_TO_PROCESS_TYPE, - "It is not possible to send an update of a configuration variable " - "to this kind of process."}, - {MgmtSrvr::NODE_SHUTDOWN_IN_PROGESS, "Node shutdown in progress" }, - {MgmtSrvr::SYSTEM_SHUTDOWN_IN_PROGRESS, "System shutdown in progress" }, - {MgmtSrvr::NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH, - "Node shutdown would cause system crash" }, - {MgmtSrvr::UNSUPPORTED_NODE_SHUTDOWN, - "Unsupported multi node shutdown. Abort option required." }, - {MgmtSrvr::NODE_NOT_API_NODE, "The specified node is not an API node." }, - {MgmtSrvr::OPERATION_NOT_ALLOWED_START_STOP, - "Operation not allowed while nodes are starting or stopping."}, - {MgmtSrvr::NO_CONTACT_WITH_DB_NODES, "No contact with database nodes" } -}; - int MgmtSrvr::translateStopRef(Uint32 errCode) { switch(errCode){ @@ -343,8 +281,6 @@ int MgmtSrvr::translateStopRef(Uint32 errCode) return 4999; } -static int noOfErrorCodes = sizeof(errorTable) / sizeof(ErrorItem); - int MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const { @@ -1969,18 +1905,8 @@ MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no) const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz) { - - for (int i = 0; i < noOfErrorCodes; ++i) { - if (errorCode == errorTable[i]._errorCode) { - BaseString::snprintf(buf, buf_sz, errorTable[i]._errorText); - buf[buf_sz-1]= 0; - return buf; - } - } - ndb_error_string(errorCode, buf, buf_sz); buf[buf_sz-1]= 0; - return buf; } diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp index a54b7866091..90287554ef8 100644 --- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -148,45 +148,6 @@ public: */ bool isEventLogFilterEnabled(int severity); - STATIC_CONST( NO_CONTACT_WITH_PROCESS = 5000 ); - STATIC_CONST( PROCESS_NOT_CONFIGURED = 5001 ); - STATIC_CONST( WRONG_PROCESS_TYPE = 5002 ); - STATIC_CONST( COULD_NOT_ALLOCATE_MEMORY = 5003 ); - STATIC_CONST( SEND_OR_RECEIVE_FAILED = 5005 ); - STATIC_CONST( INVALID_LEVEL = 5006 ); - STATIC_CONST( INVALID_ERROR_NUMBER = 5007 ); - STATIC_CONST( INVALID_TRACE_NUMBER = 5008 ); - STATIC_CONST( NOT_IMPLEMENTED = 5009 ); - STATIC_CONST( INVALID_BLOCK_NAME = 5010 ); - - STATIC_CONST( CONFIG_PARAM_NOT_EXIST = 5011 ); - STATIC_CONST( CONFIG_PARAM_NOT_UPDATEABLE = 5012 ); - STATIC_CONST( VALUE_WRONG_FORMAT_INT_EXPECTED = 5013 ); - STATIC_CONST( VALUE_TOO_LOW = 5014 ); - STATIC_CONST( VALUE_TOO_HIGH = 5015 ); - STATIC_CONST( VALUE_WRONG_FORMAT_BOOL_EXPECTED = 5016 ); - - STATIC_CONST( CONFIG_FILE_OPEN_WRITE_ERROR = 5017 ); - STATIC_CONST( CONFIG_FILE_OPEN_READ_ERROR = 5018 ); - STATIC_CONST( CONFIG_FILE_WRITE_ERROR = 5019 ); - STATIC_CONST( CONFIG_FILE_READ_ERROR = 5020 ); - STATIC_CONST( CONFIG_FILE_CLOSE_ERROR = 5021 ); - - STATIC_CONST( CONFIG_CHANGE_REFUSED_BY_RECEIVER = 5022 ); - STATIC_CONST( COULD_NOT_SYNC_CONFIG_CHANGE_AGAINST_PHYSICAL_MEDIUM = 5023 ); - STATIC_CONST( CONFIG_FILE_CHECKSUM_ERROR = 5024 ); - STATIC_CONST( NOT_POSSIBLE_TO_SEND_CONFIG_UPDATE_TO_PROCESS_TYPE = 5025 ); - - STATIC_CONST( NODE_SHUTDOWN_IN_PROGESS = 5026 ); - STATIC_CONST( SYSTEM_SHUTDOWN_IN_PROGRESS = 5027 ); - STATIC_CONST( NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH = 5028 ); - - STATIC_CONST( NO_CONTACT_WITH_DB_NODES = 5030 ); - STATIC_CONST( UNSUPPORTED_NODE_SHUTDOWN = 5031 ); - - STATIC_CONST( NODE_NOT_API_NODE = 5062 ); - STATIC_CONST( OPERATION_NOT_ALLOWED_START_STOP = 5063 ); - /** * This enum specifies the different signal loggig modes possible to set * with the setSignalLoggingMode method. diff --git a/storage/ndb/src/mgmsrv/ndb_mgmd_error.h b/storage/ndb/src/mgmsrv/ndb_mgmd_error.h new file mode 100644 index 00000000000..2438f15c808 --- /dev/null +++ b/storage/ndb/src/mgmsrv/ndb_mgmd_error.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2007 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef NDB_MGMD_ERROR_H +#define NDB_MGMD_ERROR_H + +#define NO_CONTACT_WITH_PROCESS 5000 +#define WRONG_PROCESS_TYPE 5002 +#define SEND_OR_RECEIVE_FAILED 5005 +#define INVALID_ERROR_NUMBER 5007 +#define INVALID_TRACE_NUMBER 5008 +#define INVALID_BLOCK_NAME 5010 +#define NODE_SHUTDOWN_IN_PROGESS 5026 +#define SYSTEM_SHUTDOWN_IN_PROGRESS 5027 +#define NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH 5028 +#define NO_CONTACT_WITH_DB_NODES 5030 +#define UNSUPPORTED_NODE_SHUTDOWN 5031 +#define NODE_NOT_API_NODE 5062 +#define OPERATION_NOT_ALLOWED_START_STOP 5063 + +#endif diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index b10859c3180..914acd17c08 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -19,6 +19,9 @@ #include #include +#include "../mgmsrv/ndb_mgmd_error.h" + + typedef struct ErrorBundle { int code; int mysql_code; @@ -619,6 +622,33 @@ ErrorBundle ErrorCodes[] = { { 4273, DMEC, IE, "No blob table in dict cache" }, { 4274, DMEC, IE, "Corrupted main table PK in blob operation" }, { 4275, DMEC, AE, "The blob method is incompatible with operation type or lock mode" }, + + { NO_CONTACT_WITH_PROCESS, DMEC, AE, + "No contact with the process (dead ?)."}, + { WRONG_PROCESS_TYPE, DMEC, AE, + "The process has wrong type. Expected a DB process."}, + { SEND_OR_RECEIVE_FAILED, DMEC, AE, + "Send to process or receive failed."}, + { INVALID_ERROR_NUMBER, DMEC, AE, + "Invalid error number. Should be >= 0."}, + { INVALID_TRACE_NUMBER, DMEC, AE, + "Invalid trace number."}, + { INVALID_BLOCK_NAME, DMEC, AE, + "Invalid block name"}, + { NODE_SHUTDOWN_IN_PROGESS, DMEC, AE, + "Node shutdown in progress" }, + { SYSTEM_SHUTDOWN_IN_PROGRESS, DMEC, AE, + "System shutdown in progress" }, + { NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH, DMEC, AE, + "Node shutdown would cause system crash" }, + { UNSUPPORTED_NODE_SHUTDOWN, DMEC, AE, + "Unsupported multi node shutdown. Abort option required." }, + { NODE_NOT_API_NODE, DMEC, AE, + "The specified node is not an API node." }, + { OPERATION_NOT_ALLOWED_START_STOP, DMEC, AE, + "Operation not allowed while nodes are starting or stopping."}, + { NO_CONTACT_WITH_DB_NODES, DMEC, AE, + "No contact with database nodes" } }; static From ca7180c73e1bf3d633b4e8686c43639dc4106da9 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 12:35:35 +0200 Subject: [PATCH 21/30] get mgmapi error codes into perror --- extra/perror.c | 20 +++- storage/ndb/include/mgmapi/mgmapi.h | 100 +----------------- storage/ndb/include/mgmapi/mgmapi_error.h | 121 ++++++++++++++++++++++ 3 files changed, 140 insertions(+), 101 deletions(-) create mode 100644 storage/ndb/include/mgmapi/mgmapi_error.h diff --git a/extra/perror.c b/extra/perror.c index c49869be681..6ab2afe0b71 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -25,6 +25,7 @@ #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE #include "../storage/ndb/src/ndbapi/ndberror.c" #include "../storage/ndb/src/kernel/error/ndbd_exit_codes.c" +#include "../storage/ndb/include/mgmapi/mgmapi_error.h" #endif static my_bool verbose, print_all_codes; @@ -32,6 +33,20 @@ static my_bool verbose, print_all_codes; #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE static my_bool ndb_code; static char ndb_string[1024]; +int mgmapi_error_string(int err_no, char *str, int size) +{ + int i; + for (i= 0; i < ndb_mgm_noOfErrorMsgs; i++) + { + if (ndb_mgm_error_msgs[i].code == err_no) + { + my_snprintf(str, size-1, "%s", ndb_mgm_error_msgs[i].msg); + str[size-1]= '\0'; + return 0; + } + } + return -1; +} #endif static struct my_option my_long_options[] = @@ -238,8 +253,9 @@ int main(int argc,char *argv[]) #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE if (ndb_code) { - if ((ndb_error_string(code, ndb_string, sizeof(ndb_string)) < 0) && - (ndbd_exit_string(code, ndb_string, sizeof(ndb_string)) < 0)) + if ((ndb_error_string(code, ndb_string, sizeof(ndb_string)) < 0) && + (ndbd_exit_string(code, ndb_string, sizeof(ndb_string)) < 0) && + (mgmapi_error_string(code, ndb_string, sizeof(ndb_string)) < 0)) { msg= 0; } diff --git a/storage/ndb/include/mgmapi/mgmapi.h b/storage/ndb/include/mgmapi/mgmapi.h index ffed44c7da1..0853f5a4422 100644 --- a/storage/ndb/include/mgmapi/mgmapi.h +++ b/storage/ndb/include/mgmapi/mgmapi.h @@ -18,6 +18,7 @@ #include "mgmapi_config_parameters.h" #include "ndb_logevent.h" +#include "mgmapi_error.h" #define MGM_LOGLEVELS CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1 #define NDB_MGM_MAX_LOGLEVEL 15 @@ -211,105 +212,6 @@ extern "C" { #endif }; - /** - * Error codes - */ - enum ndb_mgm_error { - /** Not an error */ - NDB_MGM_NO_ERROR = 0, - - /* Request for service errors */ - /** Supplied connectstring is illegal */ - NDB_MGM_ILLEGAL_CONNECT_STRING = 1001, - /** Supplied NdbMgmHandle is illegal */ - NDB_MGM_ILLEGAL_SERVER_HANDLE = 1005, - /** Illegal reply from server */ - NDB_MGM_ILLEGAL_SERVER_REPLY = 1006, - /** Illegal number of nodes */ - NDB_MGM_ILLEGAL_NUMBER_OF_NODES = 1007, - /** Illegal node status */ - NDB_MGM_ILLEGAL_NODE_STATUS = 1008, - /** Memory allocation error */ - NDB_MGM_OUT_OF_MEMORY = 1009, - /** Management server not connected */ - NDB_MGM_SERVER_NOT_CONNECTED = 1010, - /** Could not connect to socker */ - NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET = 1011, - /** Could not bind local address */ - NDB_MGM_BIND_ADDRESS = 1012, - - /* Alloc node id failures */ - /** Generic error, retry may succeed */ - NDB_MGM_ALLOCID_ERROR = 1101, - /** Non retriable error */ - NDB_MGM_ALLOCID_CONFIG_MISMATCH = 1102, - - /* Service errors - Start/Stop Node or System */ - /** Start failed */ - NDB_MGM_START_FAILED = 2001, - /** Stop failed */ - NDB_MGM_STOP_FAILED = 2002, - /** Restart failed */ - NDB_MGM_RESTART_FAILED = 2003, - - /* Service errors - Backup */ - /** Unable to start backup */ - NDB_MGM_COULD_NOT_START_BACKUP = 3001, - /** Unable to abort backup */ - NDB_MGM_COULD_NOT_ABORT_BACKUP = 3002, - - /* Service errors - Single User Mode */ - /** Unable to enter single user mode */ - NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE = 4001, - /** Unable to exit single user mode */ - NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE = 4002, - - /* Usage errors */ - /** Usage error */ - NDB_MGM_USAGE_ERROR = 5001 - }; - -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - struct Ndb_Mgm_Error_Msg { - enum ndb_mgm_error code; - const char * msg; - }; - const struct Ndb_Mgm_Error_Msg ndb_mgm_error_msgs[] = { - { NDB_MGM_NO_ERROR, "No error" }, - - /* Request for service errors */ - { NDB_MGM_ILLEGAL_CONNECT_STRING, "Illegal connect string" }, - { NDB_MGM_ILLEGAL_SERVER_HANDLE, "Illegal server handle" }, - { NDB_MGM_ILLEGAL_SERVER_REPLY, "Illegal reply from server" }, - { NDB_MGM_ILLEGAL_NUMBER_OF_NODES, "Illegal number of nodes" }, - { NDB_MGM_ILLEGAL_NODE_STATUS, "Illegal node status" }, - { NDB_MGM_OUT_OF_MEMORY, "Out of memory" }, - { NDB_MGM_SERVER_NOT_CONNECTED, "Management server not connected" }, - { NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, "Could not connect to socket" }, - - /* Service errors - Start/Stop Node or System */ - { NDB_MGM_START_FAILED, "Start failed" }, - { NDB_MGM_STOP_FAILED, "Stop failed" }, - { NDB_MGM_RESTART_FAILED, "Restart failed" }, - - /* Service errors - Backup */ - { NDB_MGM_COULD_NOT_START_BACKUP, "Could not start backup" }, - { NDB_MGM_COULD_NOT_ABORT_BACKUP, "Could not abort backup" }, - - /* Service errors - Single User Mode */ - { NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE, - "Could not enter single user mode" }, - { NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE, - "Could not exit single user mode" }, - - /* Usage errors */ - { NDB_MGM_USAGE_ERROR, - "Usage error" } - }; - const int ndb_mgm_noOfErrorMsgs = - sizeof(ndb_mgm_error_msgs)/sizeof(struct Ndb_Mgm_Error_Msg); -#endif - /** * Status of a node in the cluster. * diff --git a/storage/ndb/include/mgmapi/mgmapi_error.h b/storage/ndb/include/mgmapi/mgmapi_error.h new file mode 100644 index 00000000000..2d0aa1ded0f --- /dev/null +++ b/storage/ndb/include/mgmapi/mgmapi_error.h @@ -0,0 +1,121 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef MGMAPI_ERROR_H +#define MGMAPI_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + /** + * Error codes + */ + enum ndb_mgm_error { + /** Not an error */ + NDB_MGM_NO_ERROR = 0, + + /* Request for service errors */ + /** Supplied connectstring is illegal */ + NDB_MGM_ILLEGAL_CONNECT_STRING = 1001, + /** Supplied NdbMgmHandle is illegal */ + NDB_MGM_ILLEGAL_SERVER_HANDLE = 1005, + /** Illegal reply from server */ + NDB_MGM_ILLEGAL_SERVER_REPLY = 1006, + /** Illegal number of nodes */ + NDB_MGM_ILLEGAL_NUMBER_OF_NODES = 1007, + /** Illegal node status */ + NDB_MGM_ILLEGAL_NODE_STATUS = 1008, + /** Memory allocation error */ + NDB_MGM_OUT_OF_MEMORY = 1009, + /** Management server not connected */ + NDB_MGM_SERVER_NOT_CONNECTED = 1010, + /** Could not connect to socker */ + NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET = 1011, + /** Could not bind local address */ + NDB_MGM_BIND_ADDRESS = 1012, + + /* Alloc node id failures */ + /** Generic error, retry may succeed */ + NDB_MGM_ALLOCID_ERROR = 1101, + /** Non retriable error */ + NDB_MGM_ALLOCID_CONFIG_MISMATCH = 1102, + + /* Service errors - Start/Stop Node or System */ + /** Start failed */ + NDB_MGM_START_FAILED = 2001, + /** Stop failed */ + NDB_MGM_STOP_FAILED = 2002, + /** Restart failed */ + NDB_MGM_RESTART_FAILED = 2003, + + /* Service errors - Backup */ + /** Unable to start backup */ + NDB_MGM_COULD_NOT_START_BACKUP = 3001, + /** Unable to abort backup */ + NDB_MGM_COULD_NOT_ABORT_BACKUP = 3002, + + /* Service errors - Single User Mode */ + /** Unable to enter single user mode */ + NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE = 4001, + /** Unable to exit single user mode */ + NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE = 4002, + + /* Usage errors */ + /** Usage error */ + NDB_MGM_USAGE_ERROR = 5001 + }; + struct Ndb_Mgm_Error_Msg { + enum ndb_mgm_error code; + const char * msg; + }; + const struct Ndb_Mgm_Error_Msg ndb_mgm_error_msgs[] = { + { NDB_MGM_NO_ERROR, "No error" }, + + /* Request for service errors */ + { NDB_MGM_ILLEGAL_CONNECT_STRING, "Illegal connect string" }, + { NDB_MGM_ILLEGAL_SERVER_HANDLE, "Illegal server handle" }, + { NDB_MGM_ILLEGAL_SERVER_REPLY, "Illegal reply from server" }, + { NDB_MGM_ILLEGAL_NUMBER_OF_NODES, "Illegal number of nodes" }, + { NDB_MGM_ILLEGAL_NODE_STATUS, "Illegal node status" }, + { NDB_MGM_OUT_OF_MEMORY, "Out of memory" }, + { NDB_MGM_SERVER_NOT_CONNECTED, "Management server not connected" }, + { NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, "Could not connect to socket" }, + + /* Service errors - Start/Stop Node or System */ + { NDB_MGM_START_FAILED, "Start failed" }, + { NDB_MGM_STOP_FAILED, "Stop failed" }, + { NDB_MGM_RESTART_FAILED, "Restart failed" }, + + /* Service errors - Backup */ + { NDB_MGM_COULD_NOT_START_BACKUP, "Could not start backup" }, + { NDB_MGM_COULD_NOT_ABORT_BACKUP, "Could not abort backup" }, + + /* Service errors - Single User Mode */ + { NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE, + "Could not enter single user mode" }, + { NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE, + "Could not exit single user mode" }, + + /* Usage errors */ + { NDB_MGM_USAGE_ERROR, + "Usage error" } + }; + const int ndb_mgm_noOfErrorMsgs = + sizeof(ndb_mgm_error_msgs)/sizeof(struct Ndb_Mgm_Error_Msg); +#ifdef __cplusplus +} +#endif + +#endif From b2aa8dd4d3418d17ecc851470a39fcf344b9a308 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 12:51:13 +0200 Subject: [PATCH 22/30] Bug #29103 ndb_restore segfaults on NULL var[char|binary] --- mysql-test/r/ndb_restore.result | 20 ++++++------- mysql-test/t/ndb_restore.test | 2 +- .../ndb/tools/restore/consumer_restore.cpp | 29 ++++++++++--------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/ndb_restore.result b/mysql-test/r/ndb_restore.result index 8ecffa437b0..d1c76192cef 100644 --- a/mysql-test/r/ndb_restore.result +++ b/mysql-test/r/ndb_restore.result @@ -18,7 +18,7 @@ CREATE TABLE `t2_c` ( PRIMARY KEY (`capgotod`), KEY `i quadaddsvr` (`gotod`) ) ENGINE=ndbcluster DEFAULT CHARSET=latin1; -INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); +INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'),(5,0,'',NULL,NULL,''); CREATE TABLE `t3_c` ( `CapGoaledatta` smallint(5) unsigned NOT NULL default '0', `capgotod` smallint(5) unsigned NOT NULL default '0', @@ -154,15 +154,15 @@ count(*) 5 select count(*) from t2; count(*) -6 +7 select count(*) from t2_c; count(*) -6 +7 select count(*) from (select * from t2 union select * from t2_c) a; count(*) -6 +7 select count(*) from t3; count(*) 4 @@ -286,15 +286,15 @@ count(*) 5 select count(*) from t2; count(*) -6 +7 select count(*) from t2_c; count(*) -6 +7 select count(*) from (select * from t2 union select * from t2_c) a; count(*) -6 +7 select count(*) from t3; count(*) 4 @@ -386,15 +386,15 @@ count(*) 5 select count(*) from t2; count(*) -6 +7 select count(*) from t2_c; count(*) -6 +7 select count(*) from (select * from t2 union select * from t2_c) a; count(*) -6 +7 select count(*) from t3; count(*) 4 diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test index 61927a1f90a..7f0cafdfd77 100644 --- a/mysql-test/t/ndb_restore.test +++ b/mysql-test/t/ndb_restore.test @@ -33,7 +33,7 @@ CREATE TABLE `t2_c` ( PRIMARY KEY (`capgotod`), KEY `i quadaddsvr` (`gotod`) ) ENGINE=ndbcluster DEFAULT CHARSET=latin1; -INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); +INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'),(5,0,'',NULL,NULL,''); # Added ROW_FORMAT=FIXED to use below to see that setting is preserved # by restore diff --git a/storage/ndb/tools/restore/consumer_restore.cpp b/storage/ndb/tools/restore/consumer_restore.cpp index b7db8145c56..fde1f4c3074 100644 --- a/storage/ndb/tools/restore/consumer_restore.cpp +++ b/storage/ndb/tools/restore/consumer_restore.cpp @@ -1158,19 +1158,22 @@ void BackupRestore::tuple_a(restore_callback_t *cb) char * dataPtr = attr_data->string_value; Uint32 length = 0; - const unsigned char * src = (const unsigned char *)dataPtr; - switch(attr_desc->m_column->getType()){ - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Varbinary: - length = src[0] + 1; - break; - case NdbDictionary::Column::Longvarchar: - case NdbDictionary::Column::Longvarbinary: - length = src[0] + (src[1] << 8) + 2; - break; - default: - length = attr_data->size; - break; + if (!attr_data->null) + { + const unsigned char * src = (const unsigned char *)dataPtr; + switch(attr_desc->m_column->getType()){ + case NdbDictionary::Column::Varchar: + case NdbDictionary::Column::Varbinary: + length = src[0] + 1; + break; + case NdbDictionary::Column::Longvarchar: + case NdbDictionary::Column::Longvarbinary: + length = src[0] + (src[1] << 8) + 2; + break; + default: + length = attr_data->size; + break; + } } if (j == 0 && tup.getTable()->have_auto_inc(i)) tup.getTable()->update_max_auto_val(dataPtr,size*arraySize); From 48c43e00b9126e822c234b3bcfd0296d2b1da260 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 12:57:32 +0200 Subject: [PATCH 23/30] Makefile.am: new public file needs to get into distribution --- storage/ndb/include/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/ndb/include/Makefile.am b/storage/ndb/include/Makefile.am index bf8fe392072..9e6ad016d75 100644 --- a/storage/ndb/include/Makefile.am +++ b/storage/ndb/include/Makefile.am @@ -45,6 +45,7 @@ ndbapi/ndberror.h mgmapiinclude_HEADERS = \ mgmapi/mgmapi.h \ +mgmapi/mgmapi_error.h \ mgmapi/mgmapi_debug.h \ mgmapi/mgmapi_config_parameters.h \ mgmapi/mgmapi_config_parameters_debug.h \ From 51fe11b494da53e338c46ae1f28e30339c808f7b Mon Sep 17 00:00:00 2001 From: "Justin.He/justin.he@dev3-240.dev.cn.tlan" <> Date: Thu, 14 Jun 2007 19:40:44 +0800 Subject: [PATCH 24/30] Bug#27640, backup id not displayed in the output of "ndb_mgm start backup wait completed" --- mysql-test/r/ndb_backup_print.result | 64 ++++++ mysql-test/t/ndb_backup_print.test | 66 ++++++ ndb/include/debugger/EventLogger.hpp | 2 +- ndb/src/mgmclient/CommandInterpreter.cpp | 258 +++++++++++++++++------ ndb/src/mgmclient/Makefile.am | 3 +- 5 files changed, 322 insertions(+), 71 deletions(-) create mode 100644 mysql-test/r/ndb_backup_print.result create mode 100644 mysql-test/t/ndb_backup_print.test diff --git a/mysql-test/r/ndb_backup_print.result b/mysql-test/r/ndb_backup_print.result new file mode 100644 index 00000000000..872ec9d2b72 --- /dev/null +++ b/mysql-test/r/ndb_backup_print.result @@ -0,0 +1,64 @@ +use test; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +Connected to Management Server at: : +Waiting for completed, this may take several minutes +Backup started from node +Backup started from node completed + StartGCP: StopGCP: + #Records: #LogRecords: + Data: bytes Log: bytes +create table t1 +(pk int key +,a1 BIT(1), a2 BIT(5), a3 BIT(33), a4 BIT(63), a5 BIT(64) +,b1 TINYINT, b2 TINYINT UNSIGNED +,c1 SMALLINT, c2 SMALLINT UNSIGNED +,d1 INT, d2 INT UNSIGNED +,e1 BIGINT, e2 BIGINT UNSIGNED +,f1 CHAR(1) BINARY, f2 CHAR(32) BINARY, f3 CHAR(255) BINARY +,g1 VARCHAR(32) BINARY, g2 VARCHAR(255) BINARY, g3 VARCHAR(1000) BINARY +,h1 BINARY(1), h2 BINARY(8), h3 BINARY(255) +,i1 VARBINARY(32), i2 VARBINARY(255), i3 VARBINARY(1000) +) engine ndb; +insert into t1 values +(1 +,0x1, 0x17, 0x789a, 0x789abcde, 0xfedc0001 +,127, 255 +,32767, 65535 +,2147483647, 4294967295 +,9223372036854775807, 18446744073709551615 +,'1','12345678901234567890123456789012','123456789' + ,'1','12345678901234567890123456789012','123456789' + ,0x12,0x123456789abcdef0, 0x012345 +,0x12,0x123456789abcdef0, 0x00123450 +); +insert into t1 values +(2 +,0, 0, 0, 0, 0 +,-128, 0 +,-32768, 0 +,-2147483648, 0 +,-9223372036854775808, 0 +,'','','' + ,'','','' + ,0x0,0x0,0x0 +,0x0,0x0,0x0 +); +insert into t1 values +(3 +,NULL,NULL,NULL,NULL,NULL +,NULL,NULL +,NULL,NULL +,NULL,NULL +,NULL,NULL +,NULL,NULL,NULL +,NULL,NULL,NULL +,NULL,NULL,NULL +,NULL,NULL,NULL +); +Connected to Management Server at: : +Waiting for completed, this may take several minutes +Backup started from node +Backup started from node completed + StartGCP: StopGCP: + #Records: #LogRecords: + Data: bytes Log: bytes diff --git a/mysql-test/t/ndb_backup_print.test b/mysql-test/t/ndb_backup_print.test new file mode 100644 index 00000000000..34bdf519694 --- /dev/null +++ b/mysql-test/t/ndb_backup_print.test @@ -0,0 +1,66 @@ +-- source include/have_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 + +#NO.1 test output of backup +--exec $NDB_TOOLS_DIR/../src/mgmclient/ndb_mgm -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g' + +create table t1 + (pk int key + ,a1 BIT(1), a2 BIT(5), a3 BIT(33), a4 BIT(63), a5 BIT(64) + ,b1 TINYINT, b2 TINYINT UNSIGNED + ,c1 SMALLINT, c2 SMALLINT UNSIGNED + ,d1 INT, d2 INT UNSIGNED + ,e1 BIGINT, e2 BIGINT UNSIGNED + ,f1 CHAR(1) BINARY, f2 CHAR(32) BINARY, f3 CHAR(255) BINARY + ,g1 VARCHAR(32) BINARY, g2 VARCHAR(255) BINARY, g3 VARCHAR(1000) BINARY + ,h1 BINARY(1), h2 BINARY(8), h3 BINARY(255) + ,i1 VARBINARY(32), i2 VARBINARY(255), i3 VARBINARY(1000) + ) engine ndb; + +insert into t1 values + (1 + ,0x1, 0x17, 0x789a, 0x789abcde, 0xfedc0001 + ,127, 255 + ,32767, 65535 + ,2147483647, 4294967295 + ,9223372036854775807, 18446744073709551615 + ,'1','12345678901234567890123456789012','123456789' + ,'1','12345678901234567890123456789012','123456789' + ,0x12,0x123456789abcdef0, 0x012345 + ,0x12,0x123456789abcdef0, 0x00123450 + ); + +insert into t1 values + (2 + ,0, 0, 0, 0, 0 + ,-128, 0 + ,-32768, 0 + ,-2147483648, 0 + ,-9223372036854775808, 0 + ,'','','' + ,'','','' + ,0x0,0x0,0x0 + ,0x0,0x0,0x0 + ); + +insert into t1 values + (3 + ,NULL,NULL,NULL,NULL,NULL + ,NULL,NULL + ,NULL,NULL + ,NULL,NULL + ,NULL,NULL + ,NULL,NULL,NULL + ,NULL,NULL,NULL + ,NULL,NULL,NULL + ,NULL,NULL,NULL + ); + +#NO.2 test output of backup after some simple SQL operations +--exec $NDB_TOOLS_DIR/../src/mgmclient/ndb_mgm -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g' diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp index 11df3f513fc..f6762743df0 100644 --- a/ndb/include/debugger/EventLogger.hpp +++ b/ndb/include/debugger/EventLogger.hpp @@ -175,5 +175,5 @@ private: char m_text[MAX_TEXT_LENGTH]; }; - +extern void getRestartAction(Uint32 action, BaseString &str); #endif diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 2ea98a57866..6212592461b 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -25,6 +25,7 @@ #include #include +#include class MgmtSrvr; @@ -125,7 +126,7 @@ public: int executeStatus(int processId, const char* parameters, bool all); int executeEventReporting(int processId, const char* parameters, bool all); int executeDumpState(int processId, const char* parameters, bool all); - int executeStartBackup(char * parameters); + int executeStartBackup(char * parameters, bool interactive); int executeAbortBackup(char * parameters); int executeStop(Vector &command_list, unsigned command_pos, int *node_ids, int no_of_nodes); @@ -768,6 +769,113 @@ CommandInterpreter::printError() } } +/* + * print log event from mgmsrv to console screen + */ +static void +printLogEvent(struct ndb_logevent* event) +{ + switch (event->type) { + /** + * NDB_MGM_EVENT_CATEGORY_BACKUP + */ + case NDB_LE_BackupStarted: + ndbout_c("Backup %d started from node %d", + event->BackupStarted.backup_id, event->BackupStarted.starting_node); + break; + case NDB_LE_BackupFailedToStart: + ndbout_c("Backup request from %d failed to start. Error: %d", + event->BackupFailedToStart.starting_node, event->BackupFailedToStart.error); + break; + case NDB_LE_BackupCompleted: + ndbout_c("Backup %u started from node %u completed\n" + " StartGCP: %u StopGCP: %u\n" + " #Records: %u #LogRecords: %u\n" + " Data: %u bytes Log: %u bytes", + event->BackupCompleted.backup_id, event->BackupCompleted.starting_node, + event->BackupCompleted.start_gci, event->BackupCompleted.stop_gci, + event->BackupCompleted.n_records, event->BackupCompleted.n_log_records, + event->BackupCompleted.n_bytes, event->BackupCompleted.n_log_bytes); + break; + case NDB_LE_BackupAborted: + ndbout_c("Backup %d started from %d has been aborted. Error: %d", + event->BackupAborted.backup_id, event->BackupAborted.starting_node, + event->BackupAborted.error); + break; + /** + * NDB_MGM_EVENT_CATEGORY_STARTUP + */ + case NDB_LE_NDBStartStarted: + ndbout_c("Start initiated (version %d.%d.%d)", + getMajor(event->NDBStartStarted.version), + getMinor(event->NDBStartStarted.version), + getBuild(event->NDBStartStarted.version)); + break; + case NDB_LE_NDBStartCompleted: + ndbout_c("Started (version %d.%d.%d)", + getMajor(event->NDBStartCompleted.version), + getMinor(event->NDBStartCompleted.version), + getBuild(event->NDBStartCompleted.version)); + break; + case NDB_LE_NDBStopStarted: + ndbout_c("%s shutdown initiated", + (event->NDBStopStarted.stoptype == 1 ? "Cluster" : "Node")); + break; + case NDB_LE_NDBStopCompleted: + { + BaseString action_str(""); + BaseString signum_str(""); + getRestartAction(event->NDBStopCompleted.action, action_str); + if (event->NDBStopCompleted.signum) + signum_str.appfmt(" Initiated by signal %d.", + event->NDBStopCompleted.signum); + ndbout_c("Node shutdown completed%s.%s", + action_str.c_str(), + signum_str.c_str()); + } + break; + case NDB_LE_NDBStopForced: + { + BaseString action_str(""); + BaseString reason_str(""); + BaseString sphase_str(""); + int signum = event->NDBStopForced.signum; + int error = event->NDBStopForced.error; + int sphase = event->NDBStopForced.sphase; + int extra = event->NDBStopForced.extra; + getRestartAction(event->NDBStopForced.action, action_str); + if (signum) + reason_str.appfmt(" Initiated by signal %d.", signum); + if (error) + { + ndbd_exit_classification cl; + ndbd_exit_status st; + const char *msg = ndbd_exit_message(error, &cl); + const char *cl_msg = ndbd_exit_classification_message(cl, &st); + const char *st_msg = ndbd_exit_status_message(st); + reason_str.appfmt(" Caused by error %d: \'%s(%s). %s\'.", + error, msg, cl_msg, st_msg); + if (extra != 0) + reason_str.appfmt(" (extra info %d)", extra); + } + if (sphase < 255) + sphase_str.appfmt(" Occured during startphase %u.", sphase); + ndbout_c("Forced node shutdown completed%s.%s%s", + action_str.c_str(), sphase_str.c_str(), + reason_str.c_str()); + } + break; + case NDB_LE_NDBStopAborted: + ndbout_c("Node shutdown aborted"); + break; + /** + * default nothing to print + */ + default: + break; + } +} + //***************************************************************************** //***************************************************************************** @@ -784,27 +892,21 @@ event_thread_run(void* p) int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 1, NDB_MGM_EVENT_CATEGORY_STARTUP, 0 }; - int fd = ndb_mgm_listen_event(handle, filter); - if (fd != NDB_INVALID_SOCKET) + + NdbLogEventHandle log_handle= NULL; + struct ndb_logevent log_event; + + log_handle= ndb_mgm_create_logevent_handle(handle, filter); + if (log_handle) { do_event_thread= 1; - char *tmp= 0; - char buf[1024]; - SocketInputStream in(fd,10); do { - if (tmp == 0) NdbSleep_MilliSleep(10); - if((tmp = in.gets(buf, 1024))) - { - const char ping_token[]= ""; - if (memcmp(ping_token,tmp,sizeof(ping_token)-1)) - if(tmp && strlen(tmp)) - { - Guard g(printmutex); - ndbout << tmp; - } - } + if (ndb_logevent_get_next(log_handle, &log_event, 2000) <= 0) + continue; + Guard g(printmutex); + printLogEvent(&log_event); } while(do_event_thread); - NDB_CLOSE_SOCKET(fd); + ndb_mgm_destroy_logevent_handle(&log_handle); } else { @@ -1054,7 +1156,7 @@ CommandInterpreter::execute_impl(const char *_line, bool interactive) else if(strcasecmp(firstToken, "START") == 0 && allAfterFirstToken != NULL && strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ - m_error= executeStartBackup(allAfterFirstToken); + m_error= executeStartBackup(allAfterFirstToken, interactive); DBUG_RETURN(true); } else if(strcasecmp(firstToken, "ABORT") == 0 && @@ -2518,20 +2620,11 @@ CommandInterpreter::executeEventReporting(int processId, * Backup *****************************************************************************/ int -CommandInterpreter::executeStartBackup(char* parameters) +CommandInterpreter::executeStartBackup(char* parameters, bool interactive) { struct ndb_mgm_reply reply; unsigned int backupId; -#if 0 - int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; - int fd = ndb_mgm_listen_event(m_mgmsrv, filter); - if (fd < 0) - { - ndbout << "Initializing start of backup failed" << endl; - printError(); - return fd; - } -#endif + Vector args; { BaseString(parameters).split(args); @@ -2544,25 +2637,20 @@ CommandInterpreter::executeStartBackup(char* parameters) int sz= args.size(); int result; - if (sz == 2 && - args[1] == "NOWAIT") + int flags = 2; + if (sz == 2 && args[1] == "NOWAIT") { - result = ndb_mgm_start_backup(m_mgmsrv, 0, &backupId, &reply); + flags = 0; } - else if (sz == 1 || - (sz == 3 && - args[1] == "WAIT" && - args[2] == "COMPLETED")) + else if (sz == 1 || (sz == 3 && args[1] == "WAIT" && args[2] == "COMPLETED")) { + flags = 2; ndbout_c("Waiting for completed, this may take several minutes"); - result = ndb_mgm_start_backup(m_mgmsrv, 2, &backupId, &reply); } - else if (sz == 3 && - args[1] == "WAIT" && - args[2] == "STARTED") + else if (sz == 3 && args[1] == "WAIT" && args[2] == "STARTED") { ndbout_c("Waiting for started, this may take several minutes"); - result = ndb_mgm_start_backup(m_mgmsrv, 1, &backupId, &reply); + flags = 1; } else { @@ -2570,48 +2658,80 @@ CommandInterpreter::executeStartBackup(char* parameters) return -1; } + NdbLogEventHandle log_handle= NULL; + struct ndb_logevent log_event; + if (flags == 2 && !interactive) + { + int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0, 0 }; + log_handle = ndb_mgm_create_logevent_handle(m_mgmsrv, filter); + if (!log_handle) + { + ndbout << "Initializing start of backup failed" << endl; + printError(); + return -1; + } + } + result = ndb_mgm_start_backup(m_mgmsrv, flags, &backupId, &reply); + if (result != 0) { ndbout << "Backup failed" << endl; printError(); -#if 0 - close(fd); -#endif + + if (log_handle) + ndb_mgm_destroy_logevent_handle(&log_handle); return result; } -#if 0 - ndbout_c("Waiting for completed, this may take several minutes"); - char *tmp; - char buf[1024]; + + /** + * If interactive, event listner thread is already running + */ + if (log_handle && !interactive) { - SocketInputStream in(fd); int count = 0; + int retry = 0; do { - tmp = in.gets(buf, 1024); - if(tmp) + if (ndb_logevent_get_next(log_handle, &log_event, 60000) > 0) { - ndbout << tmp; - unsigned int id; - if(sscanf(tmp, "%*[^:]: Backup %d ", &id) == 1 && id == backupId){ - count++; - } + int print = 0; + switch (log_event.type) { + case NDB_LE_BackupStarted: + if (log_event.BackupStarted.backup_id == backupId) + print = 1; + break; + case NDB_LE_BackupCompleted: + if (log_event.BackupCompleted.backup_id == backupId) + print = 1; + break; + case NDB_LE_BackupAborted: + if (log_event.BackupAborted.backup_id == backupId) + print = 1; + break; + default: + break; + } + if (print) + { + Guard g(m_print_mutex); + printLogEvent(&log_event); + count++; + } } - } while(count < 2); + else + { + retry++; + } + } while(count < 2 && retry < 3); + + if (retry >= 3) + ndbout << "get backup event failed for " << retry << " times" << endl; + + ndb_mgm_destroy_logevent_handle(&log_handle); } - SocketInputStream in(fd, 10); - do { - tmp = in.gets(buf, 1024); - if(tmp && tmp[0] != 0) - { - ndbout << tmp; - } - } while(tmp && tmp[0] != 0); - - close(fd); -#endif return 0; } + int CommandInterpreter::executeAbortBackup(char* parameters) { diff --git a/ndb/src/mgmclient/Makefile.am b/ndb/src/mgmclient/Makefile.am index 8ce8bf4da45..99540160341 100644 --- a/ndb/src/mgmclient/Makefile.am +++ b/ndb/src/mgmclient/Makefile.am @@ -21,7 +21,8 @@ libndbmgmclient_la_LIBADD = ../mgmapi/libmgmapi.la \ ../common/logger/liblogger.la \ ../common/portlib/libportlib.la \ ../common/util/libgeneral.la \ - ../common/portlib/libportlib.la + ../common/portlib/libportlib.la \ + ../common/debugger/libtrace.la ndb_mgm_SOURCES = main.cpp From 36584cf3f732e8107ddee8c2f8138b4f9a7df81d Mon Sep 17 00:00:00 2001 From: "Justin.He/justin.he@dev3-240.dev.cn.tlan" <> Date: Thu, 14 Jun 2007 20:25:45 +0800 Subject: [PATCH 25/30] Bug#27640, backup id not dispalyed in the output of "ndb_mgm start backup wait completed" correct related sourcecode after merge from 5.0 --- .../ndb/src/mgmclient/CommandInterpreter.cpp | 348 ++---------------- 1 file changed, 35 insertions(+), 313 deletions(-) diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp index 6212592461b..8175a1916b5 100644 --- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp @@ -15,14 +15,7 @@ #include #include - -//#define HAVE_GLOBAL_REPLICATION - #include -#ifdef HAVE_GLOBAL_REPLICATION -#include "../rep/repapi/repapi.h" -#endif - #include #include #include @@ -168,11 +161,6 @@ private: int m_verbose; int try_reconnect; int m_error; -#ifdef HAVE_GLOBAL_REPLICATION - NdbRepHandle m_repserver; - const char *rep_host; - bool rep_connected; -#endif struct NdbThread* m_event_thread; NdbMutex *m_print_mutex; }; @@ -237,10 +225,6 @@ extern "C" { #include #include #include -#include -#ifdef HAVE_GLOBAL_REPLICATION - -#endif // HAVE_GLOBAL_REPLICATION #include "MgmtErrorReporter.hpp" #include #include @@ -268,9 +252,6 @@ static const char* helpText = "---------------------------------------------------------------------------\n" "HELP Print help text\n" "HELP COMMAND Print detailed help for COMMAND(e.g. SHOW)\n" -#ifdef HAVE_GLOBAL_REPLICATION -"HELP REPLICATION Help for global replication\n" -#endif // HAVE_GLOBAL_REPLICATION #ifdef VM_TRACE // DEBUG ONLY "HELP DEBUG Help for debug compiled version\n" #endif @@ -294,9 +275,6 @@ static const char* helpText = "EXIT SINGLE USER MODE Exit single user mode\n" " STATUS Print status\n" " CLUSTERLOG {=}+ Set log level for cluster log\n" -#ifdef HAVE_GLOBAL_REPLICATION -"REP CONNECT Connect to REP server on host:port\n" -#endif "PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n" "CONNECT [] Connect to management server (reconnect if already connected)\n" "QUIT Quit management client\n" @@ -596,39 +574,6 @@ static const char* helpTextQuit = ; -#ifdef HAVE_GLOBAL_REPLICATION -static const char* helpTextRep = -"---------------------------------------------------------------------------\n" -" NDB Cluster -- Management Client -- Help for Global Replication\n" -"---------------------------------------------------------------------------\n" -"Commands should be executed on the standby NDB Cluster\n" -"These features are in an experimental release state.\n" -"\n" -"Simple Commands:\n" -"REP START Start Global Replication\n" -"REP START REQUESTOR Start Global Replication Requestor\n" -"REP STATUS Show Global Replication status\n" -"REP STOP Stop Global Replication\n" -"REP STOP REQUESTOR Stop Global Replication Requestor\n" -"\n" -"Advanced Commands:\n" -"REP START Starts protocol\n" -"REP STOP Stops protocol\n" -" = TRANSFER | APPLY | DELETE\n" -"\n" -#ifdef VM_TRACE // DEBUG ONLY -"Debugging commands:\n" -"REP DELETE Removes epochs stored in primary and standy systems\n" -"REP DROP Drop a table in SS identified by table id\n" -"REP SLOWSTOP Stop Replication (Tries to synchonize with primary)\n" -"REP FASTSTOP Stop Replication (Stops in consistent state)\n" -" = SUBSCRIPTION\n" -" METALOG | METASCAN | DATALOG | DATASCAN\n" -" REQUESTOR | TRANSFER | APPLY | DELETE\n" -#endif -; -#endif // HAVE_GLOBAL_REPLICATION - #ifdef VM_TRACE // DEBUG ONLY static const char* helpTextDebug = "---------------------------------------------------------------------------\n" @@ -681,10 +626,6 @@ struct st_cmd_help { {"PURGE STALE SESSIONS", helpTextPurgeStaleSessions}, {"CONNECT", helpTextConnect}, {"QUIT", helpTextQuit}, -#ifdef HAVE_GLOBAL_REPLICATION - {"REPLICATION", helpTextRep}, - {"REP", helpTextRep}, -#endif // HAVE_GLOBAL_REPLICATION #ifdef VM_TRACE // DEBUG ONLY {"DEBUG", helpTextDebug}, #endif //VM_TRACE @@ -724,11 +665,6 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose) m_event_thread= NULL; try_reconnect = 0; m_print_mutex= NdbMutex_Create(); -#ifdef HAVE_GLOBAL_REPLICATION - rep_host = NULL; - m_repserver = NULL; - rep_connected = false; -#endif } /* @@ -1168,15 +1104,9 @@ CommandInterpreter::execute_impl(const char *_line, bool interactive) else if (strcasecmp(firstToken, "PURGE") == 0) { m_error = executePurge(allAfterFirstToken); DBUG_RETURN(true); - } -#ifdef HAVE_GLOBAL_REPLICATION - else if(strcasecmp(firstToken, "REPLICATION") == 0 || - strcasecmp(firstToken, "REP") == 0) { - m_error = executeRep(allAfterFirstToken); - DBUG_RETURN(true); - } -#endif // HAVE_GLOBAL_REPLICATION + } else if(strcasecmp(firstToken, "ENTER") == 0 && + allAfterFirstToken != NULL && allAfterFirstToken != NULL && strncasecmp(allAfterFirstToken, "SINGLE USER MODE ", sizeof("SINGLE USER MODE") - 1) == 0){ @@ -1651,7 +1581,6 @@ CommandInterpreter::executePurge(char* parameters) return -1; } - int i; char *str; if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) { @@ -1730,8 +1659,8 @@ CommandInterpreter::executeShow(char* parameters) case NDB_MGM_NODE_TYPE_UNKNOWN: ndbout << "Error: Unknown Node Type" << endl; return -1; - case NDB_MGM_NODE_TYPE_REP: - abort(); + case NDB_MGM_NODE_TYPE_MAX: + break; /* purify: deadcode */ } } @@ -1769,7 +1698,6 @@ CommandInterpreter::executeConnect(char* parameters, bool interactive) { BaseString *basestring = NULL; - int retval; disconnect(); if (!emptyString(parameters)) { basestring= new BaseString(parameters); @@ -1806,7 +1734,15 @@ CommandInterpreter::executeClusterLog(char* parameters) char * item = strtok_r(tmpString, " ", &tmpPtr); int enable; - const unsigned int *enabled= ndb_mgm_get_logfilter(m_mgmsrv); + ndb_mgm_severity enabled[NDB_MGM_EVENT_SEVERITY_ALL] = + {{NDB_MGM_EVENT_SEVERITY_ON,0}, + {NDB_MGM_EVENT_SEVERITY_DEBUG,0}, + {NDB_MGM_EVENT_SEVERITY_INFO,0}, + {NDB_MGM_EVENT_SEVERITY_WARNING,0}, + {NDB_MGM_EVENT_SEVERITY_ERROR,0}, + {NDB_MGM_EVENT_SEVERITY_CRITICAL,0}, + {NDB_MGM_EVENT_SEVERITY_ALERT,0}}; + ndb_mgm_get_clusterlog_severity_filter(m_mgmsrv, &enabled[0], NDB_MGM_EVENT_SEVERITY_ALL); if(enabled == NULL) { ndbout << "Couldn't get status" << endl; printError(); @@ -1819,25 +1755,25 @@ CommandInterpreter::executeClusterLog(char* parameters) ********************/ if (strcasecmp(item, "INFO") == 0) { DBUG_PRINT("info",("INFO")); - if(enabled[0] == 0) + if(enabled[0].value == 0) { ndbout << "Cluster logging is disabled." << endl; m_error = 0; DBUG_VOID_RETURN; } #if 0 - for(i = 0; i<7;i++) - printf("enabled[%d] = %d\n", i, enabled[i]); + for(i = 0; i &command_list, return -1; } + if (!nostart) + ndbout_c("Shutting down nodes with \"-n, no start\" option, to subsequently start the nodes."); + result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids, initialstart, nostart, abort, &need_disconnect); @@ -2204,7 +2143,6 @@ CommandInterpreter::executeStatus(int processId, ndb_mgm_node_status status; Uint32 startPhase, version; - bool system; struct ndb_mgm_cluster_state *cl; cl = ndb_mgm_get_status(m_mgmsrv); @@ -2222,6 +2160,19 @@ CommandInterpreter::executeStatus(int processId, ndbout << processId << ": Node not found" << endl; return -1; } + if (cl->node_states[i].node_type != NDB_MGM_NODE_TYPE_NDB){ + if (cl->node_states[i].version != 0){ + version = cl->node_states[i].version; + ndbout << "Node "<< cl->node_states[i].node_id <<": connected" ; + ndbout_c(" (Version %d.%d.%d)", + getMajor(version) , + getMinor(version), + getBuild(version)); + + }else + ndbout << "Node "<< cl->node_states[i].node_id <<": not connected" << endl; + return 0; + } status = cl->node_states[i].node_status; startPhase = cl->node_states[i].start_phase; version = cl->node_states[i].version; @@ -2616,6 +2567,7 @@ CommandInterpreter::executeEventReporting(int processId, return retval; } + /***************************************************************************** * Backup *****************************************************************************/ @@ -2731,7 +2683,6 @@ CommandInterpreter::executeStartBackup(char* parameters, bool interactive) return 0; } - int CommandInterpreter::executeAbortBackup(char* parameters) { @@ -2762,233 +2713,4 @@ CommandInterpreter::executeAbortBackup(char* parameters) return -1; } -#ifdef HAVE_GLOBAL_REPLICATION -/***************************************************************************** - * Global Replication - * - * For information about the different commands, see - * GrepReq::Request in file signaldata/grepImpl.cpp. - * - * Below are commands as of 2003-07-05 (may change!): - * START = 0, ///< Start Global Replication (all phases) - * START_METALOG = 1, ///< Start Global Replication (all phases) - * START_METASCAN = 2, ///< Start Global Replication (all phases) - * START_DATALOG = 3, ///< Start Global Replication (all phases) - * START_DATASCAN = 4, ///< Start Global Replication (all phases) - * START_REQUESTOR = 5, ///< Start Global Replication (all phases) - * ABORT = 6, ///< Immediate stop (removes subscription) - * SLOW_STOP = 7, ///< Stop after finishing applying current GCI epoch - * FAST_STOP = 8, ///< Stop after finishing applying all PS GCI epochs - * START_TRANSFER = 9, ///< Start SS-PS transfer - * STOP_TRANSFER = 10, ///< Stop SS-PS transfer - * START_APPLY = 11, ///< Start applying GCI epochs in SS - * STOP_APPLY = 12, ///< Stop applying GCI epochs in SS - * STATUS = 13, ///< Status - * START_SUBSCR = 14, - * REMOVE_BUFFERS = 15, - * DROP_TABLE = 16 - - *****************************************************************************/ - -int -CommandInterpreter::executeRep(char* parameters) -{ - if (emptyString(parameters)) { - ndbout << helpTextRep; - return 0; - } - - char * line = my_strdup(parameters,MYF(MY_WME)); - My_auto_ptr ap1((char*)line); - char * firstToken = strtok(line, " "); - - struct ndb_rep_reply reply; - unsigned int repId; - - - if (!strcasecmp(firstToken, "CONNECT")) { - char * host = strtok(NULL, "\0"); - for (unsigned int i = 0; i < strlen(host); ++i) { - host[i] = tolower(host[i]); - } - - if(host == NULL) - { - ndbout_c("host:port must be specified."); - return -1; - } - - if(rep_connected) { - if(m_repserver != NULL) { - ndb_rep_disconnect(m_repserver); - rep_connected = false; - } - } - - if(m_repserver == NULL) - m_repserver = ndb_rep_create_handle(); - if(ndb_rep_connect(m_repserver, host) < 0){ - ndbout_c("Failed to connect to %s", host); - return -1; - } - else - rep_connected=true; - return 0; - - if(!rep_connected) { - ndbout_c("Not connected to REP server"); - return -1; - } - } - - /******** - * START - ********/ - if (!strcasecmp(firstToken, "START")) { - - unsigned int req; - char *startType = strtok(NULL, "\0"); - - if (startType == NULL) { - req = GrepReq::START; - } else if (!strcasecmp(startType, "SUBSCRIPTION")) { - req = GrepReq::START_SUBSCR; - } else if (!strcasecmp(startType, "METALOG")) { - req = GrepReq::START_METALOG; - } else if (!strcasecmp(startType, "METASCAN")) { - req = GrepReq::START_METASCAN; - } else if (!strcasecmp(startType, "DATALOG")) { - req = GrepReq::START_DATALOG; - } else if (!strcasecmp(startType, "DATASCAN")) { - req = GrepReq::START_DATASCAN; - } else if (!strcasecmp(startType, "REQUESTOR")) { - req = GrepReq::START_REQUESTOR; - } else if (!strcasecmp(startType, "TRANSFER")) { - req = GrepReq::START_TRANSFER; - } else if (!strcasecmp(startType, "APPLY")) { - req = GrepReq::START_APPLY; - } else if (!strcasecmp(startType, "DELETE")) { - req = GrepReq::START_DELETE; - } else { - ndbout_c("Illegal argument to command 'REPLICATION START'"); - return -1; - } - - int result = ndb_rep_command(m_repserver, req, &repId, &reply); - - if (result != 0) { - ndbout << "Start of Global Replication failed" << endl; - return -1; - } else { - ndbout << "Start of Global Replication ordered" << endl; - } - return 0; - } - - /******** - * STOP - ********/ - if (!strcasecmp(firstToken, "STOP")) { - unsigned int req; - char *startType = strtok(NULL, " "); - unsigned int epoch = 0; - - if (startType == NULL) { - /** - * Stop immediately - */ - req = GrepReq::STOP; - } else if (!strcasecmp(startType, "EPOCH")) { - char *strEpoch = strtok(NULL, "\0"); - if(strEpoch == NULL) { - ndbout_c("Epoch expected!"); - return -1; - } - req = GrepReq::STOP; - epoch=atoi(strEpoch); - } else if (!strcasecmp(startType, "SUBSCRIPTION")) { - req = GrepReq::STOP_SUBSCR; - } else if (!strcasecmp(startType, "METALOG")) { - req = GrepReq::STOP_METALOG; - } else if (!strcasecmp(startType, "METASCAN")) { - req = GrepReq::STOP_METASCAN; - } else if (!strcasecmp(startType, "DATALOG")) { - req = GrepReq::STOP_DATALOG; - } else if (!strcasecmp(startType, "DATASCAN")) { - req = GrepReq::STOP_DATASCAN; - } else if (!strcasecmp(startType, "REQUESTOR")) { - req = GrepReq::STOP_REQUESTOR; - } else if (!strcasecmp(startType, "TRANSFER")) { - req = GrepReq::STOP_TRANSFER; - } else if (!strcasecmp(startType, "APPLY")) { - req = GrepReq::STOP_APPLY; - } else if (!strcasecmp(startType, "DELETE")) { - req = GrepReq::STOP_DELETE; - } else { - ndbout_c("Illegal argument to command 'REPLICATION STOP'"); - return -1; - } - int result = ndb_rep_command(m_repserver, req, &repId, &reply, epoch); - - if (result != 0) { - ndbout << "Stop command failed" << endl; - return -1; - } else { - ndbout << "Stop ordered" << endl; - } - return 0; - } - - /********* - * STATUS - *********/ - if (!strcasecmp(firstToken, "STATUS")) { - struct rep_state repstate; - int result = - ndb_rep_get_status(m_repserver, &repId, &reply, &repstate); - - if (result != 0) { - ndbout << "Status request of Global Replication failed" << endl; - return -1; - } else { - ndbout << "Status request of Global Replication ordered" << endl; - ndbout << "See printout at one of the DB nodes" << endl; - ndbout << "(Better status report is under development.)" << endl; - ndbout << " SubscriptionId " << repstate.subid - << " SubscriptionKey " << repstate.subkey << endl; - } - return 0; - } - - /********* - * QUERY (see repapi.h for querable counters) - *********/ - if (!strcasecmp(firstToken, "QUERY")) { - char *query = strtok(NULL, "\0"); - int queryCounter=-1; - if(query != NULL) { - queryCounter = atoi(query); - } - struct rep_state repstate; - unsigned repId = 0; - int result = ndb_rep_query(m_repserver, (QueryCounter)queryCounter, - &repId, &reply, &repstate); - - if (result != 0) { - ndbout << "Query repserver failed" << endl; - return -1; - } else { - ndbout << "Query repserver sucessful" << endl; - ndbout_c("repstate : QueryCounter %d, f=%d l=%d" - " nodegroups %d" , - repstate.queryCounter, - repstate.first[0], repstate.last[0], - repstate.no_of_nodegroups ); - } - return 0; - } - return 0; -} -#endif // HAVE_GLOBAL_REPLICATION - template class Vector; From 404f9dc10dd51d9f00a40c2fe24564dbba16130c Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 15:15:45 +0200 Subject: [PATCH 26/30] correct warning --- extra/perror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/perror.c b/extra/perror.c index 6ab2afe0b71..f0b3d36f5d8 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -38,7 +38,7 @@ int mgmapi_error_string(int err_no, char *str, int size) int i; for (i= 0; i < ndb_mgm_noOfErrorMsgs; i++) { - if (ndb_mgm_error_msgs[i].code == err_no) + if ((int)ndb_mgm_error_msgs[i].code == err_no) { my_snprintf(str, size-1, "%s", ndb_mgm_error_msgs[i].msg); str[size-1]= '\0'; From c41a4472c7c73f662e3741fdff7f1a3fd3007516 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Thu, 14 Jun 2007 16:01:51 +0200 Subject: [PATCH 27/30] Bug#26342 auto_increment_increment AND auto_increment_offset REALLY REALLY anger NDB cluster, implemented support for auto_increment_offset and auto_increment_increment for Ndb, post review fix --- ndb/src/ndbapi/Ndb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index 941bfc88b24..dcdee3d4ea1 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -882,8 +882,8 @@ Ndb::getTupleIdFromNdb(Ndb_local_table_info* info, DBUG_PRINT("info", ("Next value fetched from database %lu", (ulong) opValue)); DBUG_PRINT("info", ("Increasing %lu by offset %lu, increment is %lu", (ulong) (ulong) opValue, (ulong) offset, (ulong) step)); Uint64 current, next; - next = ((Uint64) (opValue + step - offset)) / step; - next = next * step + offset; + Uint64 div = ((Uint64) (opValue + step - offset)) / step; + next = div * step + offset; current = (next < step) ? next : next - step; tupleId = (opValue <= current) ? current : next; DBUG_PRINT("info", ("Returning %lu", (ulong) tupleId)); From 1c8219c58d7bb0e6c7220345d7605f97d497a42d Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 16:10:13 +0200 Subject: [PATCH 28/30] bug#29099 - slow backup for disk data - implement read ahead during disk data scan --- storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp | 3 + .../ndb/src/kernel/blocks/dbtup/DbtupGen.cpp | 12 ++++ .../ndb/src/kernel/blocks/dbtup/DbtupScan.cpp | 64 ++++++++++++++++++- storage/ndb/src/kernel/blocks/pgman.cpp | 4 +- storage/ndb/src/kernel/vm/SimulatedBlock.cpp | 5 ++ storage/ndb/src/kernel/vm/SimulatedBlock.hpp | 4 ++ storage/ndb/src/ndbapi/TransporterFacade.cpp | 3 - storage/ndb/test/tools/hugoFill.cpp | 4 +- 8 files changed, 92 insertions(+), 7 deletions(-) diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 7845305da6c..05f993dcece 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -2619,6 +2619,9 @@ private: ArrayPool c_page_pool; Uint32 cnoOfAllocatedPages; Uint32 m_max_allocate_pages; + + /* read ahead in pages during disk order scan */ + Uint32 m_max_page_read_ahead; Tablerec *tablerec; Uint32 cnoOfTablerec; diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 3a8e996d435..3ea3deda04f 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -347,6 +347,18 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_BATCH_SIZE, &nScanBatch)); c_scanLockPool.setSize(nScanOp * nScanBatch); + + /* read ahead for disk scan can not be more that disk page buffer */ + { + Uint64 tmp = 64*1024*1024; + ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &tmp); + m_max_page_read_ahead = (tmp + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE; // in pages + // never read ahead more than 32 pages + if (m_max_page_read_ahead > 32) + m_max_page_read_ahead = 32; + } + + ScanOpPtr lcp; ndbrequire(c_scanOpPool.seize(lcp)); new (lcp.p) ScanOp(); diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp index d7ee08f29dd..bb3d8cc0626 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp @@ -686,13 +686,74 @@ Dbtup::scanNext(Signal* signal, ScanOpPtr scanPtr) // move to next extent jam(); pos.m_extent_info_ptr_i = ext_ptr.i; - Extent_info* ext = c_extent_pool.getPtr(pos.m_extent_info_ptr_i); + ext = c_extent_pool.getPtr(pos.m_extent_info_ptr_i); key.m_file_no = ext->m_key.m_file_no; key.m_page_no = ext->m_first_page_no; } } key.m_page_idx = 0; pos.m_get = ScanPos::Get_page_dd; + /* + read ahead for scan in disk order + do read ahead every 8:th page + */ + if ((bits & ScanOp::SCAN_DD) && + (((key.m_page_no - ext->m_first_page_no) & 7) == 0)) + { + jam(); + // initialize PGMAN request + Page_cache_client::Request preq; + preq.m_page = pos.m_key; + preq.m_callback = TheNULLCallback; + + // set maximum read ahead + Uint32 read_ahead = m_max_page_read_ahead; + + while (true) + { + // prepare page read ahead in current extent + Uint32 page_no = preq.m_page.m_page_no; + Uint32 page_no_limit = page_no + read_ahead; + Uint32 limit = ext->m_first_page_no + alloc.m_extent_size; + if (page_no_limit > limit) + { + jam(); + // read ahead crosses extent, set limit for this extent + read_ahead = page_no_limit - limit; + page_no_limit = limit; + // and make sure we only read one extra extent next time around + if (read_ahead > alloc.m_extent_size) + read_ahead = alloc.m_extent_size; + } + else + { + jam(); + read_ahead = 0; // no more to read ahead after this + } + // do read ahead pages for this extent + while (page_no < page_no_limit) + { + // page request to PGMAN + jam(); + preq.m_page.m_page_no = page_no; + int flags = 0; + // ignore result + m_pgman.get_page(signal, preq, flags); + jamEntry(); + page_no++; + } + if (!read_ahead || !list.next(ext_ptr)) + { + // no more extents after this or read ahead done + jam(); + break; + } + // move to next extent and initialize PGMAN request accordingly + Extent_info* ext = c_extent_pool.getPtr(ext_ptr.i); + preq.m_page.m_file_no = ext->m_key.m_file_no; + preq.m_page.m_page_no = ext->m_first_page_no; + } + } // if ScanOp::SCAN_DD read ahead } /*FALLTHRU*/ case ScanPos::Get_page_dd: @@ -725,6 +786,7 @@ Dbtup::scanNext(Signal* signal, ScanOpPtr scanPtr) safe_cast(&Dbtup::disk_page_tup_scan_callback); int flags = 0; int res = m_pgman.get_page(signal, preq, flags); + jamEntry(); if (res == 0) { jam(); // request queued diff --git a/storage/ndb/src/kernel/blocks/pgman.cpp b/storage/ndb/src/kernel/blocks/pgman.cpp index 78bc70427a9..3709748bae4 100644 --- a/storage/ndb/src/kernel/blocks/pgman.cpp +++ b/storage/ndb/src/kernel/blocks/pgman.cpp @@ -122,7 +122,7 @@ Pgman::execREAD_CONFIG_REQ(Signal* signal) if (page_buffer > 0) { - page_buffer /= GLOBAL_PAGE_SIZE; // in pages + page_buffer = (page_buffer + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE; // in pages m_param.m_max_pages = page_buffer; m_page_entry_pool.setSize(m_param.m_lirs_stack_mult * page_buffer); m_param.m_max_hot_pages = (page_buffer * 9) / 10; @@ -144,7 +144,7 @@ Pgman::Param::Param() : m_lirs_stack_mult(10), m_max_hot_pages(56), m_max_loop_count(256), - m_max_io_waits(64), + m_max_io_waits(256), m_stats_loop_delay(1000), m_cleanup_loop_delay(200), m_lcp_loop_delay(0) diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp index 7ad1d486a02..bc16b9f364e 100644 --- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -1658,6 +1658,11 @@ SimulatedBlock::sendFragmentedSignal(NodeReceiverGroup rg, } SimulatedBlock::Callback SimulatedBlock::TheEmptyCallback = {0, 0}; +void +SimulatedBlock::TheNULLCallbackFunction(class Signal*, Uint32, Uint32) +{ abort(); /* should never be called */ } +SimulatedBlock::Callback SimulatedBlock::TheNULLCallback = +{ &SimulatedBlock::TheNULLCallbackFunction, 0 }; void SimulatedBlock::sendFragmentedSignal(BlockReference ref, diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp index 86e26986f93..a78ee21fb8f 100644 --- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -131,6 +131,8 @@ public: virtual const char* get_filename(Uint32 fd) const { return "";} protected: static Callback TheEmptyCallback; + void TheNULLCallbackFunction(class Signal*, Uint32, Uint32); + static Callback TheNULLCallback; void execute(Signal* signal, Callback & c, Uint32 returnCode); @@ -599,6 +601,8 @@ inline void SimulatedBlock::execute(Signal* signal, Callback & c, Uint32 returnCode){ CallbackFunction fun = c.m_callbackFunction; + if (fun == TheNULLCallback.m_callbackFunction) + return; ndbrequire(fun != 0); c.m_callbackFunction = NULL; (this->*fun)(signal, c.m_callbackData, returnCode); diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp index f982c36cba1..19b384d8dc2 100644 --- a/storage/ndb/src/ndbapi/TransporterFacade.cpp +++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp @@ -1403,9 +1403,6 @@ int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend) } if (wait_time == -1) { -#ifdef VM_TRACE - ndbout << "Waited WAITFOR_RESPONSE_TIMEOUT, continuing wait" << endl; -#endif continue; } wait_time= max_time - NdbTick_CurrentMillisecond(); diff --git a/storage/ndb/test/tools/hugoFill.cpp b/storage/ndb/test/tools/hugoFill.cpp index 713c2ca5152..20ceb61b066 100644 --- a/storage/ndb/test/tools/hugoFill.cpp +++ b/storage/ndb/test/tools/hugoFill.cpp @@ -30,9 +30,11 @@ int main(int argc, const char** argv){ const char* _tabname = NULL; int _help = 0; int _batch = 512; + const char* db = "TEST_DB"; struct getargs args[] = { { "batch", 'b', arg_integer, &_batch, "Number of operations in each transaction", "batch" }, + { "database", 'd', arg_string, &db, "Database", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); @@ -55,7 +57,7 @@ int main(int argc, const char** argv){ { return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, "TEST_DB" ); + Ndb MyNdb(&con, db); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); From ad81e83c70030a6fbfc459c26232afbce7e266b8 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Thu, 14 Jun 2007 18:40:32 +0200 Subject: [PATCH 29/30] Bug #27640 backup id not displayed in the output of "ndb_mgm start backup wait completed" - correction, missing node id --- mysql-test/r/ndb_backup_print.result | 8 +- mysql-test/t/ndb_backup_print.test | 4 +- ndb/src/mgmclient/CommandInterpreter.cpp | 96 ++++++++++++++---------- 3 files changed, 64 insertions(+), 44 deletions(-) diff --git a/mysql-test/r/ndb_backup_print.result b/mysql-test/r/ndb_backup_print.result index 872ec9d2b72..fdd929802b2 100644 --- a/mysql-test/r/ndb_backup_print.result +++ b/mysql-test/r/ndb_backup_print.result @@ -2,8 +2,8 @@ use test; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; Connected to Management Server at: : Waiting for completed, this may take several minutes -Backup started from node -Backup started from node completed +Node : Backup started from node +Node : Backup started from node completed StartGCP: StopGCP: #Records: #LogRecords: Data: bytes Log: bytes @@ -57,8 +57,8 @@ insert into t1 values ); Connected to Management Server at: : Waiting for completed, this may take several minutes -Backup started from node -Backup started from node completed +Node : Backup started from node +Node : Backup started from node completed StartGCP: StopGCP: #Records: #LogRecords: Data: bytes Log: bytes diff --git a/mysql-test/t/ndb_backup_print.test b/mysql-test/t/ndb_backup_print.test index 34bdf519694..1e516f03ae6 100644 --- a/mysql-test/t/ndb_backup_print.test +++ b/mysql-test/t/ndb_backup_print.test @@ -8,7 +8,7 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; --enable_warnings #NO.1 test output of backup ---exec $NDB_TOOLS_DIR/../src/mgmclient/ndb_mgm -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g' +--exec $NDB_MGM --no-defaults -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g' create table t1 (pk int key @@ -63,4 +63,4 @@ insert into t1 values ); #NO.2 test output of backup after some simple SQL operations ---exec $NDB_TOOLS_DIR/../src/mgmclient/ndb_mgm -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g' +--exec $NDB_MGM --no-defaults -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g' diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index a9e3dd48d97..8abce4f9cc4 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -772,6 +772,12 @@ CommandInterpreter::printError() /* * print log event from mgmsrv to console screen */ +#define make_uint64(a,b) (((Uint64)(a)) + (((Uint64)(b)) << 32)) +#define Q64(a) make_uint64(event->EVENT.a ## _lo, event->EVENT.a ## _hi) +#define R event->source_nodeid +#define Q(a) event->EVENT.a +#define QVERSION getMajor(Q(version)), getMinor(Q(version)), getBuild(Q(version)) +#define NDB_LE_(a) NDB_LE_ ## a static void printLogEvent(struct ndb_logevent* event) { @@ -779,71 +785,83 @@ printLogEvent(struct ndb_logevent* event) /** * NDB_MGM_EVENT_CATEGORY_BACKUP */ - case NDB_LE_BackupStarted: - ndbout_c("Backup %d started from node %d", - event->BackupStarted.backup_id, event->BackupStarted.starting_node); +#undef EVENT +#define EVENT BackupStarted + case NDB_LE_BackupStarted: + ndbout_c("Node %u: Backup %d started from node %d", + R, Q(backup_id), Q(starting_node)); break; +#undef EVENT +#define EVENT BackupFailedToStart case NDB_LE_BackupFailedToStart: - ndbout_c("Backup request from %d failed to start. Error: %d", - event->BackupFailedToStart.starting_node, event->BackupFailedToStart.error); + ndbout_c("Node %u: Backup request from %d failed to start. Error: %d", + R, Q(starting_node), Q(error)); break; +#undef EVENT +#define EVENT BackupCompleted case NDB_LE_BackupCompleted: - ndbout_c("Backup %u started from node %u completed\n" + ndbout_c("Node %u: Backup %u started from node %u completed\n" " StartGCP: %u StopGCP: %u\n" " #Records: %u #LogRecords: %u\n" - " Data: %u bytes Log: %u bytes", - event->BackupCompleted.backup_id, event->BackupCompleted.starting_node, - event->BackupCompleted.start_gci, event->BackupCompleted.stop_gci, - event->BackupCompleted.n_records, event->BackupCompleted.n_log_records, - event->BackupCompleted.n_bytes, event->BackupCompleted.n_log_bytes); + " Data: %u bytes Log: %u bytes", R, + Q(backup_id), Q(starting_node), + Q(start_gci), Q(stop_gci), + Q(n_records), Q(n_log_records), + Q(n_bytes), Q(n_log_bytes)); break; +#undef EVENT +#define EVENT BackupAborted case NDB_LE_BackupAborted: - ndbout_c("Backup %d started from %d has been aborted. Error: %d", - event->BackupAborted.backup_id, event->BackupAborted.starting_node, - event->BackupAborted.error); + ndbout_c("Node %u: Backup %d started from %d has been aborted. Error: %d", + R, Q(backup_id), Q(starting_node), Q(error)); break; /** * NDB_MGM_EVENT_CATEGORY_STARTUP */ +#undef EVENT +#define EVENT NDBStartStarted case NDB_LE_NDBStartStarted: - ndbout_c("Start initiated (version %d.%d.%d)", - getMajor(event->NDBStartStarted.version), - getMinor(event->NDBStartStarted.version), - getBuild(event->NDBStartStarted.version)); + ndbout_c("Node %u: Start initiated (version %d.%d.%d)", + R, QVERSION); break; +#undef EVENT +#define EVENT NDBStartCompleted case NDB_LE_NDBStartCompleted: - ndbout_c("Started (version %d.%d.%d)", - getMajor(event->NDBStartCompleted.version), - getMinor(event->NDBStartCompleted.version), - getBuild(event->NDBStartCompleted.version)); + ndbout_c("Node %u: Started (version %d.%d.%d)", + R, QVERSION); break; +#undef EVENT +#define EVENT NDBStopStarted case NDB_LE_NDBStopStarted: - ndbout_c("%s shutdown initiated", - (event->NDBStopStarted.stoptype == 1 ? "Cluster" : "Node")); + ndbout_c("Node %u: %s shutdown initiated", R, + (Q(stoptype) == 1 ? "Cluster" : "Node")); break; +#undef EVENT +#define EVENT NDBStopCompleted case NDB_LE_NDBStopCompleted: { BaseString action_str(""); BaseString signum_str(""); - getRestartAction(event->NDBStopCompleted.action, action_str); - if (event->NDBStopCompleted.signum) + getRestartAction(Q(action), action_str); + if (Q(signum)) signum_str.appfmt(" Initiated by signal %d.", - event->NDBStopCompleted.signum); - ndbout_c("Node shutdown completed%s.%s", - action_str.c_str(), - signum_str.c_str()); + Q(signum)); + ndbout_c("Node %u: Node shutdown completed%s.%s", + R, action_str.c_str(), signum_str.c_str()); } break; +#undef EVENT +#define EVENT NDBStopForced case NDB_LE_NDBStopForced: { BaseString action_str(""); BaseString reason_str(""); BaseString sphase_str(""); - int signum = event->NDBStopForced.signum; - int error = event->NDBStopForced.error; - int sphase = event->NDBStopForced.sphase; - int extra = event->NDBStopForced.extra; - getRestartAction(event->NDBStopForced.action, action_str); + int signum = Q(signum); + int error = Q(error); + int sphase = Q(sphase); + int extra = Q(extra); + getRestartAction(Q(action), action_str); if (signum) reason_str.appfmt(" Initiated by signal %d.", signum); if (error) @@ -860,13 +878,15 @@ printLogEvent(struct ndb_logevent* event) } if (sphase < 255) sphase_str.appfmt(" Occured during startphase %u.", sphase); - ndbout_c("Forced node shutdown completed%s.%s%s", - action_str.c_str(), sphase_str.c_str(), + ndbout_c("Node %u: Forced node shutdown completed%s.%s%s", + R, action_str.c_str(), sphase_str.c_str(), reason_str.c_str()); } break; +#undef EVENT +#define EVENT StopAborted case NDB_LE_NDBStopAborted: - ndbout_c("Node shutdown aborted"); + ndbout_c("Node %u: Node shutdown aborted", R); break; /** * default nothing to print From 8d31148899a4f40aed58c7278c90e58a11cf1b86 Mon Sep 17 00:00:00 2001 From: "tomas@whalegate.ndb.mysql.com" <> Date: Sat, 16 Jun 2007 11:16:02 +0200 Subject: [PATCH 30/30] Bug #28949 - handler binlog's must be shutdoem before logger.cleanup_base --- sql/mysqld.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 672ae570c5b..f8a215a130e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1143,13 +1143,14 @@ void clean_up(bool print_message) if (cleanup_done++) return; /* purecov: inspected */ - logger.cleanup_base(); - /* make sure that handlers finish up what they have that is dependent on the binlog */ ha_binlog_end(current_thd); + + logger.cleanup_base(); + injector::free_instance(); mysql_bin_log.cleanup();