Bug #31804 drop table doesn't drop auto_increment data in cluster
Description:
Droppping an ndb table does not get rid of auto_increment data. When the table is dropped and recreated without an autoincrement column, the autoincrement column for that table can still be accessed by the NDB API.
When the database is dropped, the auto_increment does go away.
How to repeat:
first -
drop database TEST_DB_1;
create database TEST_DB_1;
CREATE TABLE `MYTABLENAME` (
`ATTR1` int(10) unsigned NOT NULL DEFAULT '0',
`ATTR2` int(10) unsigned NOT NULL,
PRIMARY KEY (`ATTR1`)
) ENGINE=ndbcluster ;
run the following snippet. You should get an error. This is expected.
Then:
drop table MYTABLENAME;
CREATE TABLE `MYTABLENAME` (
`ATTR1` int(10) unsigned NOT NULL auto_increment,
`ATTR2` int(10) unsigned NOT NULL,
PRIMARY KEY (`ATTR1`)
) ENGINE=ndbcluster ;
run the snippet. It should run successfully. This is expected.
Then:
drop table MYTABLENAME;
CREATE TABLE `MYTABLENAME` (
`ATTR1` int(10) unsigned NOT NULL DEFAULT '0',
`ATTR2` int(10) unsigned NOT NULL,
PRIMARY KEY (`ATTR1`)
) ENGINE=ndbcluster ;
run the snippet. It will run successfully. This is the error.
Then:
drop database TEST_DB_1;
CREATE TABLE `MYTABLENAME` (
`ATTR1` int(10) unsigned NOT NULL DEFAULT '0',
`ATTR2` int(10) unsigned NOT NULL,
PRIMARY KEY (`ATTR1`)
) ENGINE=ndbcluster ;
run the snippet. It will error. This is correct.
/**************************************************************
* Connect to ndb cluster *
**************************************************************/
Ndb_cluster_connection *cluster_connection=
new Ndb_cluster_connection(); // Object representing the cluster
if (cluster_connection->connect(5,3,1))
{
std::cout << "Connect to cluster management server failed.\n";
exit(-1);
}
if (cluster_connection->wait_until_ready(30,30))
{
std::cout << "Cluster was not ready within 30 secs.\n";
exit(-1);
}
Ndb* myNdb = new Ndb( cluster_connection,
"TEST_DB_1" ); // Object representing the database
if (myNdb->init() == -1) {
APIERROR(myNdb->getNdbError());
exit(-1);
}
const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME");
if (myTable == NULL)
APIERROR(myDict->getNdbError());
/**************************************************************************
* Fill table with tuples, using auto_increment IDs *
**************************************************************************/
{
std::time_t before_t = std::time(0);
for (int i = 0; i < INSERT_NUM; i++) {
NdbTransaction *myTransaction= myNdb->startTransaction();
if (myTransaction == NULL) APIERROR(myNdb->getNdbError());
NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
if (myOperation == NULL) APIERROR(myTransaction->getNdbError());
myOperation->insertTuple();
if (myNdb->initAutoIncrement() == -1)
APIERROR(myNdb->getNdbError());
Uint64 auto_id = 0;
if (myNdb->getAutoIncrementValue(myTable,auto_id,0) == -1)
APIERROR(myNdb->getNdbError());
if (myOperation->equal("ATTR1",(int)auto_id)==-1)
APIERROR(myTransaction->getNdbError());
if (myOperation->setValue("ATTR2", i)==-1)
APIERROR(myTransaction->getNdbError());
if (myTransaction->execute( NdbTransaction::Commit ) == -1)
APIERROR(myTransaction->getNdbError());
myNdb->closeTransaction(myTransaction);
}
std::time_t after_t = std::time(0);
std::cout << "Insert time for " << INSERT_NUM << " ";
std::cout << after_t << " -- " << before_t;
std::cout << " = " << after_t - before_t << std::endl;
}
Suggested fix:
Drop the auto_increment information when a table is dropped, otherwise the cluster metadata will be inconsistent with expectations.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.052 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: Droppping an ndb table does not get rid of auto_increment data. When the table is dropped and recreated without an autoincrement column, the autoincrement column for that table can still be accessed by the NDB API. When the database is dropped, the auto_increment does go away. How to repeat: first - drop database TEST_DB_1; create database TEST_DB_1; CREATE TABLE `MYTABLENAME` ( `ATTR1` int(10) unsigned NOT NULL DEFAULT '0', `ATTR2` int(10) unsigned NOT NULL, PRIMARY KEY (`ATTR1`) ) ENGINE=ndbcluster ; run the following snippet. You should get an error. This is expected. Then: drop table MYTABLENAME; CREATE TABLE `MYTABLENAME` ( `ATTR1` int(10) unsigned NOT NULL auto_increment, `ATTR2` int(10) unsigned NOT NULL, PRIMARY KEY (`ATTR1`) ) ENGINE=ndbcluster ; run the snippet. It should run successfully. This is expected. Then: drop table MYTABLENAME; CREATE TABLE `MYTABLENAME` ( `ATTR1` int(10) unsigned NOT NULL DEFAULT '0', `ATTR2` int(10) unsigned NOT NULL, PRIMARY KEY (`ATTR1`) ) ENGINE=ndbcluster ; run the snippet. It will run successfully. This is the error. Then: drop database TEST_DB_1; CREATE TABLE `MYTABLENAME` ( `ATTR1` int(10) unsigned NOT NULL DEFAULT '0', `ATTR2` int(10) unsigned NOT NULL, PRIMARY KEY (`ATTR1`) ) ENGINE=ndbcluster ; run the snippet. It will error. This is correct. /************************************************************** * Connect to ndb cluster * **************************************************************/ Ndb_cluster_connection *cluster_connection= new Ndb_cluster_connection(); // Object representing the cluster if (cluster_connection->connect(5,3,1)) { std::cout << "Connect to cluster management server failed.\n"; exit(-1); } if (cluster_connection->wait_until_ready(30,30)) { std::cout << "Cluster was not ready within 30 secs.\n"; exit(-1); } Ndb* myNdb = new Ndb( cluster_connection, "TEST_DB_1" ); // Object representing the database if (myNdb->init() == -1) { APIERROR(myNdb->getNdbError()); exit(-1); } const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME"); if (myTable == NULL) APIERROR(myDict->getNdbError()); /************************************************************************** * Fill table with tuples, using auto_increment IDs * **************************************************************************/ { std::time_t before_t = std::time(0); for (int i = 0; i < INSERT_NUM; i++) { NdbTransaction *myTransaction= myNdb->startTransaction(); if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); NdbOperation *myOperation= myTransaction->getNdbOperation(myTable); if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); myOperation->insertTuple(); if (myNdb->initAutoIncrement() == -1) APIERROR(myNdb->getNdbError()); Uint64 auto_id = 0; if (myNdb->getAutoIncrementValue(myTable,auto_id,0) == -1) APIERROR(myNdb->getNdbError()); if (myOperation->equal("ATTR1",(int)auto_id)==-1) APIERROR(myTransaction->getNdbError()); if (myOperation->setValue("ATTR2", i)==-1) APIERROR(myTransaction->getNdbError()); if (myTransaction->execute( NdbTransaction::Commit ) == -1) APIERROR(myTransaction->getNdbError()); myNdb->closeTransaction(myTransaction); } std::time_t after_t = std::time(0); std::cout << "Insert time for " << INSERT_NUM << " "; std::cout << after_t << " -- " << before_t; std::cout << " = " << after_t - before_t << std::endl; } Suggested fix: Drop the auto_increment information when a table is dropped, otherwise the cluster metadata will be inconsistent with expectations.