summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pekka@mysql.com>2006-05-16 09:37:11 +0200
committerunknown <pekka@mysql.com>2006-05-16 09:37:11 +0200
commite60119f8a56ca42c35734c39af43ce2b2eb3de3f (patch)
treeeb3a72c44d66386d09f55da106bd605909231f66
parent44de69cfdd696552bd396195b2e9e6cc9335993e (diff)
parentcda752e3cf14345456dd5b8c4b5ca1ffc51a863f (diff)
downloadmariadb-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.result23
-rw-r--r--mysql-test/t/ndb_alter_table.test17
-rw-r--r--storage/ndb/include/ndbapi/Ndb.hpp22
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp10
-rw-r--r--storage/ndb/src/ndbapi/DictCache.cpp2
-rw-r--r--storage/ndb/src/ndbapi/DictCache.hpp5
-rw-r--r--storage/ndb/src/ndbapi/Ndb.cpp182
-rw-r--r--storage/ndb/src/ndbapi/Ndbinit.cpp4
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);