diff options
author | unknown <pekka@mysql.com> | 2006-05-16 09:37:11 +0200 |
---|---|---|
committer | unknown <pekka@mysql.com> | 2006-05-16 09:37:11 +0200 |
commit | e60119f8a56ca42c35734c39af43ce2b2eb3de3f (patch) | |
tree | eb3a72c44d66386d09f55da106bd605909231f66 | |
parent | 44de69cfdd696552bd396195b2e9e6cc9335993e (diff) | |
parent | cda752e3cf14345456dd5b8c4b5ca1ffc51a863f (diff) | |
download | mariadb-git-e60119f8a56ca42c35734c39af43ce2b2eb3de3f.tar.gz |
Merge mysql.com:/space/pekka/ndb/version/my50-bug14509
into mysql.com:/space/pekka/ndb/version/my51-bug14509
mysql-test/t/ndb_alter_table.test:
Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
Auto merged
storage/ndb/src/ndbapi/DictCache.cpp:
Auto merged
storage/ndb/src/ndbapi/DictCache.hpp:
Auto merged
mysql-test/r/ndb_alter_table.result:
manual merge
storage/ndb/include/ndbapi/Ndb.hpp:
manual merge
storage/ndb/src/ndbapi/Ndb.cpp:
manual merge [needs more fixes]
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp:
SCCS merged
storage/ndb/src/ndbapi/Ndbinit.cpp:
SCCS merged
-rw-r--r-- | mysql-test/r/ndb_alter_table.result | 23 | ||||
-rw-r--r-- | mysql-test/t/ndb_alter_table.test | 17 | ||||
-rw-r--r-- | storage/ndb/include/ndbapi/Ndb.hpp | 22 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp | 10 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/DictCache.cpp | 2 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/DictCache.hpp | 5 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/Ndb.cpp | 182 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/Ndbinit.cpp | 4 |
8 files changed, 166 insertions, 99 deletions
diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 7c687ff33a1..e506973f347 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -1,4 +1,4 @@ -DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t1, t2; drop database if exists mysqltest; CREATE TABLE t1 ( a INT NOT NULL, @@ -328,3 +328,24 @@ select 'no_copy' from ndb_show_tables where id = @t1_id and name like '%t1%'; no_copy no_copy DROP TABLE t1, ndb_show_tables; +create table t1 (a int primary key auto_increment, b int) engine=ndb; +insert into t1 (b) values (101),(102),(103); +select * from t1 where a = 3; +a b +3 103 +alter table t1 rename t2; +insert into t2 (b) values (201),(202),(203); +select * from t2 where a = 6; +a b +6 203 +alter table t2 add c int; +insert into t2 (b) values (301),(302),(303); +select * from t2 where a = 9; +a b c +9 303 NULL +alter table t2 rename t1; +insert into t1 (b) values (401),(402),(403); +select * from t1 where a = 12; +a b c +12 403 NULL +drop table t1; diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index 29deea4aa0d..cd5c4819c51 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -3,7 +3,7 @@ -- source include/not_embedded.inc --disable_warnings -DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t1, t2; drop database if exists mysqltest; --enable_warnings @@ -325,6 +325,21 @@ on t1 (c010, c011, c012, c013); drop table t1; +# simple test that auto incr is not lost at rename or alter +create table t1 (a int primary key auto_increment, b int) engine=ndb; +insert into t1 (b) values (101),(102),(103); +select * from t1 where a = 3; +alter table t1 rename t2; +insert into t2 (b) values (201),(202),(203); +select * from t2 where a = 6; +alter table t2 add c int; +insert into t2 (b) values (301),(302),(303); +select * from t2 where a = 9; +alter table t2 rename t1; +insert into t1 (b) values (401),(402),(403); +select * from t1 where a = 12; +drop table t1; + # End of 4.1 tests # On-line alter table diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp index 010b85b03a9..812d276bf12 100644 --- a/storage/ndb/include/ndbapi/Ndb.hpp +++ b/storage/ndb/include/ndbapi/Ndb.hpp @@ -986,6 +986,7 @@ class NdbBlob; class NdbReceiver; class TransporterFacade; class PollGuard; +class Ndb_local_table_info; template <class T> struct Ndb_free_list_t; typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*); @@ -1482,15 +1483,12 @@ public: bool increase = false); bool setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val, bool increase = false); - Uint64 getTupleIdFromNdb(const char* aTableName, - Uint32 cacheSize = 1000); - Uint64 getTupleIdFromNdb(Uint32 aTableId, - Uint32 cacheSize = 1000); - Uint64 readTupleIdFromNdb(Uint32 aTableId); - bool setTupleIdInNdb(const char* aTableName, Uint64 val, - bool increase); - bool setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase); - Uint64 opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op); +private: + Uint64 getTupleIdFromNdb(Ndb_local_table_info* info, Uint32 cacheSize); + Uint64 readTupleIdFromNdb(Ndb_local_table_info* info); + bool setTupleIdInNdb(Ndb_local_table_info* info, Uint64 val, bool increase); + Uint64 opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 opValue, Uint32 op); +public: /** */ @@ -1693,12 +1691,8 @@ private: Uint64 the_last_check_time; Uint64 theFirstTransId; - - // The tupleId is retreived from DB the - // tupleId is unique for each tableid. + // The tupleId is retrieved from DB const NdbDictionary::Table *m_sys_tab_0; - Uint64 theFirstTupleId[2048]; - Uint64 theLastTupleId[2048]; Uint32 theRestartGCI; // the Restart GCI used by DIHNDBTAMPER diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index b0372ec89a2..7c48ebb5e8b 100644 --- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -1645,10 +1645,9 @@ void Ndbcntr::systemErrorLab(Signal* signal, int line) /* |-2048| # 1 00000001 | */ /* | : | : | */ /* | -1 | # 1 00000001 | */ -/* | 0 | 0 | */ -/* | 1 | 0 | */ -/* | : | : | */ -/* | 2047| 0 | */ +/* | 1 | 0 | tupleid sequence now created on first use */ +/* | : | : | v */ +/* | 2048| 0 | v */ /*---------------------------------------------------------------------------*/ void Ndbcntr::createSystableLab(Signal* signal, unsigned index) { @@ -1859,8 +1858,7 @@ void Ndbcntr::crSystab8Lab(Signal* signal) jam(); ckey = 1; ctransidPhase = ZFALSE; - crSystab7Lab(signal); - return; + // skip 2nd loop - tupleid sequence now created on first use }//if signal->theData[0] = ctcConnectionP; signal->theData[1] = reference(); diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp index 43913d6c5be..280b4210feb 100644 --- a/storage/ndb/src/ndbapi/DictCache.cpp +++ b/storage/ndb/src/ndbapi/DictCache.cpp @@ -47,6 +47,8 @@ Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl) { assert(! is_ndb_blob_table(table_impl)); m_table_impl= table_impl; + m_first_tuple_id = ~(Uint64)0; + m_last_tuple_id = ~(Uint64)0; } Ndb_local_table_info::~Ndb_local_table_info() diff --git a/storage/ndb/src/ndbapi/DictCache.hpp b/storage/ndb/src/ndbapi/DictCache.hpp index f134e6b348e..5bdaef88b94 100644 --- a/storage/ndb/src/ndbapi/DictCache.hpp +++ b/storage/ndb/src/ndbapi/DictCache.hpp @@ -33,6 +33,11 @@ public: static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0); static void destroy(Ndb_local_table_info *); NdbTableImpl *m_table_impl; + + // range of cached tuple ids per thread + Uint64 m_first_tuple_id; + Uint64 m_last_tuple_id; + Uint64 m_local_data[1]; // Must be last member. Used to access extra space. private: Ndb_local_table_info(NdbTableImpl *table_impl); diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp index b963aeeff84..2ef2c42265c 100644 --- a/storage/ndb/src/ndbapi/Ndb.cpp +++ b/storage/ndb/src/ndbapi/Ndb.cpp @@ -755,11 +755,12 @@ Ndb::getAutoIncrementValue(const char* aTableName, Uint32 cacheSize) Ndb_local_table_info *info= theDictionary->get_local_table_info(internal_tabname); - if (info == 0) + if (info == 0) { + theError.code = theDictionary->getNdbError().code; DBUG_RETURN(~(Uint64)0); - const NdbTableImpl *table= info->m_table_impl; - Uint64 tupleId = getTupleIdFromNdb(table->m_id, cacheSize); - DBUG_PRINT("info", ("value %ul", (ulong) tupleId)); + } + Uint64 tupleId = getTupleIdFromNdb(info, cacheSize); + DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId)); DBUG_RETURN(tupleId); } @@ -770,50 +771,58 @@ Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, Uint32 cacheSize if (aTable == 0) DBUG_RETURN(~(Uint64)0); const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable); - Uint64 tupleId = getTupleIdFromNdb(table->m_id, cacheSize); - DBUG_PRINT("info", ("value %ul", (ulong) tupleId)); - DBUG_RETURN(tupleId); -} + const BaseString& internal_tabname = table->m_internalName; -Uint64 -Ndb::getTupleIdFromNdb(const char* aTableName, Uint32 cacheSize) -{ - const NdbTableImpl* table = theDictionary->getTable(aTableName); - if (table == 0) - return ~(Uint64)0; - return getTupleIdFromNdb(table->m_id, cacheSize); + Ndb_local_table_info *info= + theDictionary->get_local_table_info(internal_tabname, false); + if (info == 0) { + theError.code = theDictionary->getNdbError().code; + DBUG_RETURN(~(Uint64)0); + } + Uint64 tupleId = getTupleIdFromNdb(info, cacheSize); + DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId)); + DBUG_RETURN(tupleId); } Uint64 -Ndb::getTupleIdFromNdb(Uint32 aTableId, Uint32 cacheSize) +Ndb::getTupleIdFromNdb(Ndb_local_table_info* info, Uint32 cacheSize) { DBUG_ENTER("getTupleIdFromNdb"); - if ( theFirstTupleId[aTableId] != theLastTupleId[aTableId] ) + Uint64 tupleId; + if (info->m_first_tuple_id != info->m_last_tuple_id) { - theFirstTupleId[aTableId]++; - DBUG_PRINT("info", ("next cached value %ul", - (ulong) theFirstTupleId[aTableId])); - DBUG_RETURN(theFirstTupleId[aTableId]); + assert(info->m_first_tuple_id < info->m_last_tuple_id); + tupleId = ++info->m_first_tuple_id; + DBUG_PRINT("info", ("next cached value %llu", (ulonglong)tupleId)); } - else // theFirstTupleId == theLastTupleId + else { - DBUG_PRINT("info",("reading %u values from database", - (cacheSize == 0) ? 1 : cacheSize)); - DBUG_RETURN(opTupleIdOnNdb(aTableId, (cacheSize == 0) ? 1 : cacheSize, 0)); + 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. + */ + tupleId = opTupleIdOnNdb(info, cacheSize, 0); } + DBUG_RETURN(tupleId); } Uint64 Ndb::readAutoIncrementValue(const char* aTableName) { DBUG_ENTER("readAutoIncrementValue"); - const NdbTableImpl* table = theDictionary->getTable(aTableName); - if (table == 0) { - theError= theDictionary->getNdbError(); + BaseString internal_tabname(internalize_table_name(aTableName)); + + Ndb_local_table_info *info= + theDictionary->get_local_table_info(internal_tabname, false); + if (info == 0) { + theError.code = theDictionary->getNdbError().code; DBUG_RETURN(~(Uint64)0); } - Uint64 tupleId = readTupleIdFromNdb(table->m_id); - DBUG_PRINT("info", ("value %ul", (ulong) tupleId)); + Uint64 tupleId = readTupleIdFromNdb(info); + DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId)); DBUG_RETURN(tupleId); } @@ -824,19 +833,38 @@ Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable) if (aTable == 0) DBUG_RETURN(~(Uint64)0); const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable); - Uint64 tupleId = readTupleIdFromNdb(table->m_id); - DBUG_PRINT("info", ("value %ul", (ulong) tupleId)); + const BaseString& internal_tabname = table->m_internalName; + + Ndb_local_table_info *info= + theDictionary->get_local_table_info(internal_tabname, false); + if (info == 0) { + theError.code = theDictionary->getNdbError().code; + DBUG_RETURN(~(Uint64)0); + } + Uint64 tupleId = readTupleIdFromNdb(info); + DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId)); DBUG_RETURN(tupleId); } Uint64 -Ndb::readTupleIdFromNdb(Uint32 aTableId) +Ndb::readTupleIdFromNdb(Ndb_local_table_info* info) { - if ( theFirstTupleId[aTableId] == theLastTupleId[aTableId] ) - // Cache is empty, check next in database - return opTupleIdOnNdb(aTableId, 0, 3); - - return theFirstTupleId[aTableId] + 1; + DBUG_ENTER("Ndb::readTupleIdFromNdb"); + Uint64 tupleId; + if (info->m_first_tuple_id != info->m_last_tuple_id) + { + assert(info->m_first_tuple_id < info->m_last_tuple_id); + tupleId = info->m_first_tuple_id + 1; + } + else + { + /* + * peek at NEXTID. does not reserve it so the value is valid + * only if no other transactions are allowed. + */ + tupleId = opTupleIdOnNdb(info, 0, 3); + } + DBUG_RETURN(tupleId); } bool @@ -848,11 +876,10 @@ Ndb::setAutoIncrementValue(const char* aTableName, Uint64 val, bool increase) Ndb_local_table_info *info= theDictionary->get_local_table_info(internal_tabname); if (info == 0) { - theError= theDictionary->getNdbError(); + theError.code = theDictionary->getNdbError().code; DBUG_RETURN(false); } - const NdbTableImpl* table= info->m_table_impl; - DBUG_RETURN(setTupleIdInNdb(table->m_id, val, increase)); + DBUG_RETURN(setTupleIdInNdb(info, val, increase)); } bool @@ -860,45 +887,47 @@ Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val, bool { DBUG_ENTER("setAutoIncrementValue"); if (aTable == 0) - DBUG_RETURN(~(Uint64)0); + DBUG_RETURN(false); const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable); - DBUG_RETURN(setTupleIdInNdb(table->m_id, val, increase)); -} + const BaseString& internal_tabname = table->m_internalName; -bool -Ndb::setTupleIdInNdb(const char* aTableName, Uint64 val, bool increase ) -{ - DBUG_ENTER("setTupleIdInNdb(const char*, ...)"); - const NdbTableImpl* table = theDictionary->getTable(aTableName); - if (table == 0) { - theError= theDictionary->getNdbError(); + Ndb_local_table_info *info= + theDictionary->get_local_table_info(internal_tabname, false); + if (info == 0) { + theError.code = theDictionary->getNdbError().code; DBUG_RETURN(false); } - DBUG_RETURN(setTupleIdInNdb(table->m_id, val, increase)); + DBUG_RETURN(setTupleIdInNdb(info, val, increase)); } bool -Ndb::setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase ) +Ndb::setTupleIdInNdb(Ndb_local_table_info* info, Uint64 val, bool increase) { - DBUG_ENTER("setTupleIdInNdb(Uint32, ...)"); + DBUG_ENTER("setTupleIdInNdb"); if (increase) { - if (theFirstTupleId[aTableId] != theLastTupleId[aTableId]) + if (info->m_first_tuple_id != info->m_last_tuple_id) { - // We have a cache sequence - if (val <= theFirstTupleId[aTableId]+1) + assert(info->m_first_tuple_id < info->m_last_tuple_id); + if (val <= info->m_first_tuple_id + 1) DBUG_RETURN(false); - if (val <= theLastTupleId[aTableId]) + if (val <= info->m_last_tuple_id) { - theFirstTupleId[aTableId] = val - 1; + info->m_first_tuple_id = val - 1; DBUG_RETURN(true); } - // else continue; } - DBUG_RETURN((opTupleIdOnNdb(aTableId, val, 2) == val)); + /* + * if value <= NEXTID, do nothing. otherwise update NEXTID to + * value and set cached range to first = last = value - 1. + */ + DBUG_RETURN((opTupleIdOnNdb(info, val, 2) == val)); } else - DBUG_RETURN((opTupleIdOnNdb(aTableId, val, 1) == val)); + /* + * update NEXTID to given value. reset cached range. + */ + DBUG_RETURN((opTupleIdOnNdb(info, val, 1) == val)); } int Ndb::initAutoIncrement() @@ -923,9 +952,10 @@ int Ndb::initAutoIncrement() } Uint64 -Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) +Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 opValue, Uint32 op) { DBUG_ENTER("Ndb::opTupleIdOnNdb"); + Uint32 aTableId = info->m_table_impl->m_tableId; DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op)); NdbTransaction* tConnection; @@ -961,20 +991,21 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) tValue = tRecAttrResult->u_64_value(); - theFirstTupleId[aTableId] = tValue - opValue; - theLastTupleId[aTableId] = tValue - 1; - ret = theFirstTupleId[aTableId]; + info->m_first_tuple_id = tValue - opValue; + info->m_last_tuple_id = tValue - 1; + ret = info->m_first_tuple_id; break; case 1: - tOperation->updateTuple(); + // create on first use + tOperation->writeTuple(); tOperation->equal("SYSKEY_0", aTableId ); tOperation->setValue("NEXTID", opValue); if (tConnection->execute( Commit ) == -1 ) goto error_handler; - theFirstTupleId[aTableId] = ~(Uint64)0; - theLastTupleId[aTableId] = ~(Uint64)0; + info->m_first_tuple_id = ~(Uint64)0; + info->m_last_tuple_id = ~(Uint64)0; ret = opValue; break; case 2: @@ -982,6 +1013,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) tOperation->equal("SYSKEY_0", aTableId ); tOperation->load_const_u64(1, opValue); tOperation->read_attr("NEXTID", 2); + // compare NEXTID >= opValue tOperation->branch_le(2, 1, 0); tOperation->write_attr("NEXTID", 1); tOperation->interpret_exit_ok(); @@ -989,13 +1021,17 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) tOperation->interpret_exit_nok(9999); if ( (result = tConnection->execute( Commit )) == -1 ) - goto error_handler; - - if (result == 9999) + { + if (tConnection->theError.code != 9999) + goto error_handler; + + // NEXTID >= opValue, return ~(Uint64)0 for now since + // there is no error check... ret = ~(Uint64)0; + } else { - theFirstTupleId[aTableId] = theLastTupleId[aTableId] = opValue - 1; + info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1; ret = opValue; } break; diff --git a/storage/ndb/src/ndbapi/Ndbinit.cpp b/storage/ndb/src/ndbapi/Ndbinit.cpp index e41380e6484..91567e99c01 100644 --- a/storage/ndb/src/ndbapi/Ndbinit.cpp +++ b/storage/ndb/src/ndbapi/Ndbinit.cpp @@ -100,10 +100,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, theConnectionArray[i] = NULL; }//forg m_sys_tab_0 = NULL; - for (i = 0; i < 2048 ; i++) { - theFirstTupleId[i] = 0; - theLastTupleId[i] = 0; - }//for theImpl->m_dbname.assign(aDataBase); theImpl->m_schemaname.assign(aSchema); |