mariadb/ndb/test/ndbapi/testDict.cpp

1587 lines
43 KiB
C++
Raw Normal View History

2004-04-14 10:53:21 +02:00
/* 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; either version 2 of the License, or
(at your option) any later version.
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 <NDBT.hpp>
#include <NDBT_Test.hpp>
#include <HugoTransactions.hpp>
#include <UtilTransactions.hpp>
#include <NdbRestarter.hpp>
#include <Vector.hpp>
#include <signaldata/DumpStateOrd.hpp>
#include <../../include/kernel/ndb_limits.h>
#include <random.h>
#include <NdbAutoPtr.hpp>
#define CHECK(b) if (!(b)) { \
g_err << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
result = NDBT_FAILED; \
break; }
#define CHECK2(b, c) if (!(b)) { \
g_err << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << ": " << c << endl; \
result = NDBT_FAILED; \
goto end; }
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int records = ctx->getNumRecords();
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.loadTable(pNdb, records) != 0){
return NDBT_FAILED;
}
return NDBT_OK;
}
int runCreateInvalidTables(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int result = NDBT_OK;
char failTabName[256];
for (int i = 0; i < 10; i++){
BaseString::snprintf(failTabName, 256, "F%d", i);
2004-04-14 10:53:21 +02:00
const NdbDictionary::Table* pFailTab = NDBT_Tables::getTable(failTabName);
if (pFailTab != NULL){
ndbout << "|- " << failTabName << endl;
// Try to create table in db
if (pFailTab->createTableInDb(pNdb) == 0){
ndbout << failTabName << " created, this was not expected"<< endl;
result = NDBT_FAILED;
}
// Verify that table is not in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, failTabName) ;
if (pTab2 != NULL){
ndbout << failTabName << " was found in DB, this was not expected"<< endl;
result = NDBT_FAILED;
if (pFailTab->equal(*pTab2) == true){
ndbout << "It was equal" << endl;
} else {
ndbout << "It was not equal" << endl;
}
int records = 1000;
HugoTransactions hugoTrans(*pTab2);
if (hugoTrans.loadTable(pNdb, records) != 0){
ndbout << "It can NOT be loaded" << endl;
} else{
ndbout << "It can be loaded" << endl;
UtilTransactions utilTrans(*pTab2);
if (utilTrans.clearTable(pNdb, records, 64) != 0){
ndbout << "It can NOT be cleared" << endl;
} else{
ndbout << "It can be cleared" << endl;
}
}
if (pNdb->getDictionary()->dropTable(pTab2->getName()) == -1){
ndbout << "It can NOT be dropped" << endl;
} else {
ndbout << "It can be dropped" << endl;
}
}
}
}
return result;
}
int runCreateTheTable(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab = ctx->getTab();
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
ctx->setTab(pTab2);
return NDBT_OK;
}
int runCreateTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int result = NDBT_OK;
const char* tabName = "TRANSACTION"; //Use a util table
const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName);
if (pTab != NULL){
ndbout << "|- " << tabName << endl;
// Verify that table is not in db
if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){
ndbout << tabName << " was found in DB"<< endl;
return NDBT_FAILED;
}
// Try to create table in db
if (pTab->createTableInDb(pNdb) == 0){
result = NDBT_FAILED;
}
// Verify that table is in db
if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){
ndbout << tabName << " was found in DB"<< endl;
result = NDBT_FAILED;
}
}
return result;
}
int runDropTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int result = NDBT_OK;
const char* tabName = "TRANSACTION"; //Use a util table
const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(pNdb, tabName);
if (pTab != NULL){
ndbout << "|- TRANSACTION" << endl;
// Try to drop table in db
if (pNdb->getDictionary()->dropTable(pTab->getName()) == -1){
result = NDBT_FAILED;
}
// Verify that table is not in db
if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){
ndbout << tabName << " was found in DB"<< endl;
result = NDBT_FAILED;
}
}
return result;
}
int runCreateAndDrop(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int loops = ctx->getNumLoops();
int i = 0;
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << pTab->getName() << endl;
while (i < loops){
ndbout << i << ": ";
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
if (pNdb->getDictionary()->dropTable(pTab2->getName())){
ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl;
return NDBT_FAILED;
}
// Verify that table is not in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab3 != NULL){
ndbout << pTab3->getName() << " was found in DB"<< endl;
return NDBT_FAILED;
}
i++;
}
return NDBT_OK;
}
int runCreateAndDropWithData(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
int i = 0;
NdbRestarter restarter;
int val = DumpStateOrd::DihMinTimeBetweenLCP;
if(restarter.dumpStateAllNodes(&val, 1) != 0){
int result;
do { CHECK(0); } while (0);
g_err << "Unable to change timebetween LCP" << endl;
return NDBT_FAILED;
}
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << pTab->getName() << endl;
while (i < loops){
ndbout << i << ": ";
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
HugoTransactions hugoTrans(*pTab2);
if (hugoTrans.loadTable(pNdb, records) != 0){
return NDBT_FAILED;
}
int count = 0;
UtilTransactions utilTrans(*pTab2);
if (utilTrans.selectCount(pNdb, 64, &count) != 0){
return NDBT_FAILED;
}
if (count != records){
ndbout << count <<" != "<<records << endl;
return NDBT_FAILED;
}
if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){
ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl;
return NDBT_FAILED;
}
// Verify that table is not in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab3 != NULL){
ndbout << pTab3->getName() << " was found in DB"<< endl;
return NDBT_FAILED;
}
i++;
}
return NDBT_OK;
}
int runFillTable(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.fillTable(pNdb) != 0){
return NDBT_FAILED;
}
return NDBT_OK;
}
int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int records = ctx->getNumRecords();
UtilTransactions utilTrans(*ctx->getTab());
if (utilTrans.clearTable(pNdb, records) != 0){
return NDBT_FAILED;
}
return NDBT_OK;
}
int runCreateAndDropDuring(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
int i = 0;
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << pTab->getName() << endl;
while (i < loops && result == NDBT_OK){
ndbout << i << ": " << endl;
// Try to create table in db
Ndb* pNdb = GETNDB(step);
g_debug << "Creating table" << endl;
if (pTab->createTableInDb(pNdb) != 0){
g_err << "createTableInDb failed" << endl;
result = NDBT_FAILED;
continue;
}
g_debug << "Verifying creation of table" << endl;
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
g_err << pTab->getName() << " was not found in DB"<< endl;
result = NDBT_FAILED;
continue;
}
NdbSleep_MilliSleep(3000);
g_debug << "Dropping table" << endl;
if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){
g_err << "Failed to drop "<<pTab2->getName()<<" in db" << endl;
result = NDBT_FAILED;
continue;
}
g_debug << "Verifying dropping of table" << endl;
// Verify that table is not in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab3 != NULL){
g_err << pTab3->getName() << " was found in DB"<< endl;
result = NDBT_FAILED;
continue;
}
i++;
}
ctx->stopTest();
return result;
}
int runUseTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
const NdbDictionary::Table* pTab = ctx->getTab();
while (ctx->isTestStopped() == false) {
// g_info << i++ << ": ";
// Delete and recreate Ndb object
// Otherwise you always get Invalid Schema Version
// It would be a nice feature to remove this two lines
//step->tearDown();
//step->setUp();
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL)
continue;
int res;
HugoTransactions hugoTrans(*pTab2);
if ((res = hugoTrans.loadTable(pNdb, records)) != 0){
NdbError err = pNdb->getNdbError(res);
if(err.classification == NdbError::SchemaError){
pNdb->getDictionary()->invalidateTable(pTab->getName());
}
continue;
}
UtilTransactions utilTrans(*pTab2);
if ((res = utilTrans.clearTable(pNdb, records)) != 0){
NdbError err = pNdb->getNdbError(res);
if(err.classification == NdbError::SchemaError){
pNdb->getDictionary()->invalidateTable(pTab->getName());
}
continue;
}
}
g_info << endl;
return NDBT_OK;
}
int runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step){
int failures = 0;
char tabName[256];
int numTables = ctx->getProperty("tables", 1000);
Ndb* pNdb = GETNDB(step);
for (int i = 0; i < numTables && failures < 5; i++){
BaseString::snprintf(tabName, 256, "MAXTAB%d", i);
2004-04-14 10:53:21 +02:00
if (pNdb->waitUntilReady(30) != 0){
// Db is not ready, return with failure
return NDBT_FAILED;
}
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << tabName << endl;
// Set new name for T1
NdbDictionary::Table newTab(* pTab);
newTab.setName(tabName);
// Try to create table in db
if (newTab.createTableInDb(pNdb) != 0){
ndbout << tabName << " coult not be created"<< endl;
failures++;
continue;
}
// Verify that table exists in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, tabName) ;
if (pTab3 == NULL){
ndbout << tabName << " was not found in DB"<< endl;
failures++;
continue;
}
if (pTab->equal(*pTab3) == false){
ndbout << "It was not equal" << endl;
failures++;
}
int records = 1000;
HugoTransactions hugoTrans(*pTab3);
if (hugoTrans.loadTable(pNdb, records) != 0){
ndbout << "It can NOT be loaded" << endl;
} else{
ndbout << "It can be loaded" << endl;
UtilTransactions utilTrans(*pTab3);
if (utilTrans.clearTable(pNdb, records, 64) != 0){
ndbout << "It can NOT be cleared" << endl;
} else{
ndbout << "It can be cleared" << endl;
}
}
}
if (pNdb->waitUntilReady(30) != 0){
// Db is not ready, return with failure
return NDBT_FAILED;
}
// HURRAAA!
return NDBT_OK;
}
int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
char tabName[256];
int numTables = ctx->getProperty("tables", 1000);
Ndb* pNdb = GETNDB(step);
for (int i = 0; i < numTables; i++){
BaseString::snprintf(tabName, 256, "MAXTAB%d", i);
2004-04-14 10:53:21 +02:00
if (pNdb->waitUntilReady(30) != 0){
// Db is not ready, return with failure
return NDBT_FAILED;
}
// Verify that table exists in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, tabName) ;
if (pTab3 == NULL){
ndbout << tabName << " was not found in DB"<< endl;
continue;
}
// Try to drop table in db
if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){
ndbout << tabName << " coult not be dropped"<< endl;
result = NDBT_FAILED;
}
}
return result;
}
int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
int fragTtype = ctx->getProperty("FragmentType");
Ndb* pNdb = GETNDB(step);
int result = NDBT_OK;
NdbRestarter restarter;
// enum FragmentType {
// Unknown = 0,
// Single = 1, ///< Only one fragment
// All = 2, ///< Default value. One fragment per node group
// AllLarge = 3 ///< Sixten fragments per node group.
// };
if (pNdb->waitUntilReady(30) != 0){
// Db is not ready, return with failure
return NDBT_FAILED;
}
const NdbDictionary::Table* pTab = ctx->getTab();
pNdb->getDictionary()->dropTable(pTab->getName());
2004-04-14 10:53:21 +02:00
NdbDictionary::Table newTab(* pTab);
// Set fragment type for table
newTab.setFragmentType((NdbDictionary::Object::FragmentType)fragTtype);
// Try to create table in db
if (newTab.createTableInDb(pNdb) != 0){
ndbout << newTab.getName() << " could not be created"
<< ", fragmentType = "<<fragTtype <<endl;
return NDBT_FAILED;
}
// Verify that table exists in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()) ;
if (pTab3 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
if (pTab3->getFragmentType() != fragTtype){
ndbout << pTab->getName() << " fragmentType error "<< endl;
result = NDBT_FAILED;
goto drop_the_tab;
}
Merge NDB patches into 4.1-clone, below is list of changesets # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.1 # Removal of NDBT_Table # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.2 # Removal of NDBT_Table # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.3 # Fix for crashing AT # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.4 # Bug fixes in testIndex # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1866.1.5 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/tmp # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.1.5 # Fix for takeover when accessing indexes. # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1866.1.6 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/tmp # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.1 # Fixed error handling of fire_trigger_ord + lqhkeyref w.r.t indexes # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.2 # Simple retry mechanism in UTIL # Helps testIndex -n BuildDuring _a lot_ # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.3 # Misc fixes to test prg. # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.4 # Allow more retires on application errors # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.5 # Pass no of rows fetched in SUB_SYNC_CONTINUE_REQ # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1869 # wl1714 # Improve parallellism # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1870 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/wl1714 # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1866.1.7 # Merge # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1871 # Merge mysql.com:/home/jonas/src/wl1714 # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1872 # Fix for testScan -n ScanReadError5030 # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1873 # fix testDict -n FragmentType* # -------------------------------------------- # 04/04/14 johan@stingray.(none) 1.1866.2.1 # small fixes # -------------------------------------------- # 04/04/14 johan@stingray.(none) 1.1874 # Merge jandersson@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into stingray.(none):/space/bk/rep/mysql-4.1-ndb # -------------------------------------------- # 04/04/14 johan@stingray.(none) 1.1875 # handle rep node as an api node # -------------------------------------------- # 04/04/14 pekka@mysql.com 1.1873.1.1 # Fix for NDBT_Table removal # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1873.1.2 # Uninitialized var. # -------------------------------------------- # 04/04/15 johan@stingray.(none) 1.1876 # Merge jandersson@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into stingray.(none):/space/bk/rep/mysql-4.1-ndb # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1873.1.3 # Write pid before changing user # (as runas user probably doesn't have permissions on pid-dir) # -------------------------------------------- # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1862.1.3 # Fix printout of varchars # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1877 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mc03.ndb.mysql.com:/space/ndb/tmp # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1862.1.4 # Hmm.. don't print attr as many times as length of array # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1878 # Merge mc03.ndb.mysql.com:/space/ndb/mysql-4.1-ndb # into mc03.ndb.mysql.com:/space/ndb/tmp # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1876.1.1 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1877.1.1 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1879 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mc03.ndb.mysql.com:/space/ndb/tmp # -------------------------------------------- # 04/04/17 joreland@mysql.com 1.1880 # LCP bug when restarting ops take's longer than DIH sending a new lcp ord # Solution: # Send LCP_FRAG_REP after restarting all ops # -------------------------------------------- # 04/04/18 joreland@mysql.com 1.1881 # Missspelled ERROR_INSERT # -------------------------------------------- # 04/04/18 joreland@mysql.com 1.1882 # Added possibility to log only distributed signals # -------------------------------------------- # 04/04/22 joreland@mysql.com 1.1883 # Removed dependancy to libstdc++ # * pure virtual functions "__cxa_pure_virtual" is defined in libstd++ -> # remove all pure virtual functions # -------------------------------------------- # 04/04/23 joreland@mysql.com 1.1884 # Various minor bug fixes for problems found while compiling # with icc # -------------------------------------------- # -------------------------------------------- # 04/04/25 joreland@mysql.com 1.1885 # Removed debug code (joreland:1.1875) # -------------------------------------------- # 04/04/26 ejonore@mc03.ndb.mysql.com 1.1862.1.5 # Lock pages in memory _after_ daemon-mode (exec/fork) # -------------------------------------------- # 04/04/27 ejonore@mc03.ndb.mysql.com 1.1862.1.6 # 1) Trap abort() # 2) StopStart/StopAborted events # 3) warning if memlock fails # 4) use g_logger more often (instead of ndbout) # # -------------------------------------------- # 04/04/27 joreland@mysql.com 1.1886 # bug fix for a bug in wl1714 + software upgrade # -------------------------------------------- # 04/04/27 joreland@mysql.com 1.1887 # Cset exclude: joreland@mysql.com|ChangeSet|20040422160720|05374 # -------------------------------------------- # 04/04/27 joreland@mysql.com 1.1888 # removed libstc++ second try... # -------------------------------------------- # 04/04/28 ejonore@mc03.ndb.mysql.com 1.1862.1.7 # 1) Don't lock FUTURE pages but only current # 2) Do this when SIZEALT has completed # -------------------------------------------- # 04/04/30 joreland@mysql.com 1.1889 # Merge jonas@orca:/home/ndb/releases/mysql-4.1-ndb-3.4.x # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/05/03 ndb@mc03.ndb.mysql.com 1.1862.1.8 # Version update # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.3.1 # Changed restart behavior. # Use "angel" process which monitor "real" process # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.1.9 # Merge jonas@orca:/home/ndb/releases/mysql-4.1-ndb-3.4.x # into mysql.com:/home/jonas/src/mysql-4.1-ndb-3.4.x # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1890 # Merge B2 fixes # -------------------------------------------- # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.1.10 # Better handling of children terminations # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.1.11 # Fixes for angel-restarting # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1891 # Merge mysql.com:/home/jonas/src/mysql-4.1-ndb-3.4.x # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- #
2004-05-04 11:19:19 +02:00
if (newTab.equal(*pTab3) == false){
2004-04-14 10:53:21 +02:00
ndbout << "It was not equal" << endl;
result = NDBT_FAILED;
goto drop_the_tab;
}
do {
HugoTransactions hugoTrans(*pTab3);
UtilTransactions utilTrans(*pTab3);
int count;
CHECK(hugoTrans.loadTable(pNdb, records) == 0);
CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == records);
CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0);
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == (records/2));
// restart all
ndbout << "Restarting cluster" << endl;
CHECK(restarter.restartAll() == 0);
int timeout = 120;
CHECK(restarter.waitClusterStarted(timeout) == 0);
CHECK(pNdb->waitUntilReady(timeout) == 0);
// Verify content
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == (records/2));
CHECK(utilTrans.clearTable(pNdb, records) == 0);
CHECK(hugoTrans.loadTable(pNdb, records) == 0);
CHECK(utilTrans.clearTable(pNdb, records) == 0);
CHECK(hugoTrans.loadTable(pNdb, records) == 0);
CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
CHECK(utilTrans.clearTable(pNdb, records, 64) == 0);
} while(false);
drop_the_tab:
// Try to drop table in db
if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){
ndbout << pTab3->getName() << " could not be dropped"<< endl;
result = NDBT_FAILED;
}
return result;
}
int runTestTemporaryTables(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
Ndb* pNdb = GETNDB(step);
int i = 0;
NdbRestarter restarter;
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << pTab->getName() << endl;
NdbDictionary::Table newTab(* pTab);
// Set table as temporary
newTab.setStoredTable(false);
// Try to create table in db
if (newTab.createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
if (pTab2->getStoredTable() != false){
ndbout << pTab->getName() << " was not temporary in DB"<< endl;
result = NDBT_FAILED;
goto drop_the_tab;
}
while (i < loops && result == NDBT_OK){
ndbout << i << ": ";
HugoTransactions hugoTrans(*pTab2);
CHECK(hugoTrans.loadTable(pNdb, records) == 0);
int count = 0;
UtilTransactions utilTrans(*pTab2);
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == records);
// restart all
ndbout << "Restarting cluster" << endl;
CHECK(restarter.restartAll() == 0);
int timeout = 120;
CHECK(restarter.waitClusterStarted(timeout) == 0);
CHECK(pNdb->waitUntilReady(timeout) == 0);
ndbout << "Verifying records..." << endl;
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == 0);
i++;
}
drop_the_tab:
if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){
ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl;
result = NDBT_FAILED;
}
// Verify that table is not in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab3 != NULL){
ndbout << pTab3->getName() << " was found in DB"<< endl;
result = NDBT_FAILED;
}
return result;
}
int runPkSizes(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
char tabName[256];
int minPkSize = 1;
ndbout << "minPkSize=" <<minPkSize<<endl;
int maxPkSize = MAX_KEY_SIZE_IN_WORDS * 4;
ndbout << "maxPkSize=" <<maxPkSize<<endl;
Ndb* pNdb = GETNDB(step);
int numRecords = ctx->getNumRecords();
for (int i = minPkSize; i < maxPkSize; i++){
BaseString::snprintf(tabName, 256, "TPK_%d", i);
2004-04-14 10:53:21 +02:00
int records = numRecords;
int max = ~0;
// Limit num records for small PKs
if (i == 1)
max = 99;
if (i == 2)
max = 999;
if (i == 3)
max = 9999;
if (records > max)
records = max;
ndbout << "records =" << records << endl;
if (pNdb->waitUntilReady(30) != 0){
// Db is not ready, return with failure
return NDBT_FAILED;
}
ndbout << "|- " << tabName << endl;
if (NDBT_Tables::createTable(pNdb, tabName) != 0){
ndbout << tabName << " could not be created"<< endl;
return NDBT_FAILED;
}
// Verify that table exists in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, tabName) ;
if (pTab3 == NULL){
g_err << tabName << " was not found in DB"<< endl;
return NDBT_FAILED;
}
// ndbout << *pTab3 << endl;
if (pTab3->equal(*NDBT_Tables::getTable(tabName)) == false){
g_err << "It was not equal" << endl;
return NDBT_FAILED;
}
do {
// Do it all
HugoTransactions hugoTrans(*pTab3);
UtilTransactions utilTrans(*pTab3);
int count;
CHECK(hugoTrans.loadTable(pNdb, records) == 0);
CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == records);
CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0);
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == (records/2));
CHECK(utilTrans.clearTable(pNdb, records) == 0);
#if 0
// Fill table
CHECK(hugoTrans.fillTable(pNdb) == 0);
CHECK(utilTrans.clearTable2(pNdb, records) == 0);
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
CHECK(count == 0);
#endif
} while(false);
// Drop table
if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){
ndbout << "Failed to drop "<<pTab3->getName()<<" in db" << endl;
return NDBT_FAILED;
}
}
return result;
}
int runStoreFrm(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab = ctx->getTab();
int result = NDBT_OK;
int loops = ctx->getNumLoops();
for (int l = 0; l < loops && result == NDBT_OK ; l++){
Uint32 dataLen = (Uint32)myRandom48(MAX_FRM_DATA_SIZE);
// size_t dataLen = 10;
unsigned char data[MAX_FRM_DATA_SIZE];
char start = l + 248;
for(Uint32 i = 0; i < dataLen; i++){
data[i] = start;
start++;
}
#if 0
ndbout << "dataLen="<<dataLen<<endl;
for (Uint32 i = 0; i < dataLen; i++){
unsigned char c = data[i];
ndbout << hex << c << ", ";
}
ndbout << endl;
#endif
NdbDictionary::Table newTab(* pTab);
void* pData = &data;
newTab.setFrm(pData, dataLen);
// Try to create table in db
if (newTab.createTableInDb(pNdb) != 0){
result = NDBT_FAILED;
continue;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
g_err << pTab->getName() << " was not found in DB"<< endl;
result = NDBT_FAILED;
continue;
}
const void* pData2 = pTab2->getFrmData();
Uint32 resultLen = pTab2->getFrmLength();
if (dataLen != resultLen){
g_err << "Length of data failure" << endl
<< " expected = " << dataLen << endl
<< " got = " << resultLen << endl;
result = NDBT_FAILED;
}
// Verfiy the frm data
if (memcmp(pData, pData2, resultLen) != 0){
g_err << "Wrong data recieved" << endl;
for (size_t i = 0; i < dataLen; i++){
unsigned char c = ((unsigned char*)pData2)[i];
g_err << hex << c << ", ";
}
g_err << endl;
result = NDBT_FAILED;
}
if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){
g_err << "It can NOT be dropped" << endl;
result = NDBT_FAILED;
}
}
return result;
}
int runStoreFrmError(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab = ctx->getTab();
int result = NDBT_OK;
int loops = ctx->getNumLoops();
for (int l = 0; l < loops && result == NDBT_OK ; l++){
const Uint32 dataLen = MAX_FRM_DATA_SIZE + 10;
unsigned char data[dataLen];
char start = l + 248;
for(Uint32 i = 0; i < dataLen; i++){
data[i] = start;
start++;
}
#if 0
ndbout << "dataLen="<<dataLen<<endl;
for (Uint32 i = 0; i < dataLen; i++){
unsigned char c = data[i];
ndbout << hex << c << ", ";
}
ndbout << endl;
#endif
NdbDictionary::Table newTab(* pTab);
void* pData = &data;
newTab.setFrm(pData, dataLen);
// Try to create table in db
if (newTab.createTableInDb(pNdb) == 0){
result = NDBT_FAILED;
continue;
}
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 != NULL){
g_err << pTab->getName() << " was found in DB"<< endl;
result = NDBT_FAILED;
if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){
g_err << "It can NOT be dropped" << endl;
result = NDBT_FAILED;
}
continue;
}
}
return result;
}
int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary::Table* pTab2){
// Verify that getPrimaryKey only returned true for primary keys
for (int i = 0; i < pTab2->getNoOfColumns(); i++){
const NdbDictionary::Column* col = pTab->getColumn(i);
const NdbDictionary::Column* col2 = pTab2->getColumn(i);
if (col->getPrimaryKey() != col2->getPrimaryKey()){
g_err << "col->getPrimaryKey() != col2->getPrimaryKey()" << endl;
return NDBT_FAILED;
}
}
if (!pTab->equal(*pTab2)){
g_err << "equal failed" << endl;
g_info << *pTab;
g_info << *pTab2;
return NDBT_FAILED;
}
return NDBT_OK;
}
int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << pTab->getName() << endl;
g_info << *pTab;
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
int result = NDBT_OK;
if (verifyTablesAreEqual(pTab, pTab2) != NDBT_OK)
result = NDBT_FAILED;
#if 0
// Create an index on the table and see what
// the function returns now
char name[200];
sprintf(name, "%s_X007", pTab->getName());
NDBT_Index* pInd = new NDBT_Index(name);
pInd->setTable(pTab->getName());
pInd->setType(NdbDictionary::Index::UniqueHashIndex);
// pInd->setLogging(false);
for (int i = 0; i < 2; i++){
const NDBT_Attribute* pAttr = pTab->getAttribute(i);
pInd->addAttribute(*pAttr);
}
g_info << "Create index:" << endl << *pInd;
if (pInd->createIndexInDb(pNdb, false) != 0){
result = NDBT_FAILED;
}
delete pInd;
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab3 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
if (verifyTablesAreEqual(pTab, pTab3) != NDBT_OK)
result = NDBT_FAILED;
if (verifyTablesAreEqual(pTab2, pTab3) != NDBT_OK)
result = NDBT_FAILED;
#endif
#if 0
if (pTab2->getDictionary()->dropTable(pNdb) != 0){
ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl;
return NDBT_FAILED;
}
// Verify that table is not in db
const NdbDictionary::Table* pTab4 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab4 != NULL){
ndbout << pTab4->getName() << " was found in DB"<< endl;
return NDBT_FAILED;
}
#endif
return result;
}
struct ErrorCodes { int error_id; bool crash;};
ErrorCodes
2004-04-14 10:53:21 +02:00
NF_codes[] = {
{6003, true},
{6004, true},
//,6005, true,
{7173, false}
2004-04-14 10:53:21 +02:00
};
int
runNF1(NDBT_Context* ctx, NDBT_Step* step){
NdbRestarter restarter;
if(restarter.getNumDbNodes() < 2)
return NDBT_OK;
myRandom48Init(NdbTick_CurrentMillisecond());
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab = ctx->getTab();
NdbDictionary::Dictionary* dict = pNdb->getDictionary();
dict->dropTable(pTab->getName());
int result = NDBT_OK;
/**
* Need to run LCP at high rate otherwise
* packed replicas become "to many"
*/
int val = DumpStateOrd::DihMinTimeBetweenLCP;
if(restarter.dumpStateAllNodes(&val, 1) != 0){
do { CHECK(0); } while(0);
g_err << "Failed to set LCP to min value" << endl;
return NDBT_FAILED;
}
const int loops = ctx->getNumLoops();
for (int l = 0; l < loops && result == NDBT_OK ; l++){
const int sz = sizeof(NF_codes)/sizeof(NF_codes[0]);
for(int i = 0; i<sz; i++){
int rand = myRandom48(restarter.getNumDbNodes());
int nodeId = restarter.getRandomNotMasterNodeId(rand);
struct ErrorCodes err_struct = NF_codes[i];
int error = err_struct.error_id;
bool crash = err_struct.crash;
2004-04-14 10:53:21 +02:00
g_info << "NF1: node = " << nodeId << " error code = " << error << endl;
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 3};
CHECK2(restarter.dumpStateOneNode(nodeId, val2, 2) == 0,
"failed to set RestartOnErrorInsert");
CHECK2(restarter.insertErrorInNode(nodeId, error) == 0,
"failed to set error insert");
CHECK2(dict->createTable(* pTab) == 0,
"failed to create table");
if (crash) {
CHECK2(restarter.waitNodesNoStart(&nodeId, 1) == 0,
2004-04-14 10:53:21 +02:00
"waitNodesNoStart failed");
if(myRandom48(100) > 50){
CHECK2(restarter.startNodes(&nodeId, 1) == 0,
2004-04-14 10:53:21 +02:00
"failed to start node");
CHECK2(restarter.waitClusterStarted() == 0,
2004-04-14 10:53:21 +02:00
"waitClusterStarted failed");
CHECK2(dict->dropTable(pTab->getName()) == 0,
2004-04-14 10:53:21 +02:00
"drop table failed");
} else {
CHECK2(dict->dropTable(pTab->getName()) == 0,
2004-04-14 10:53:21 +02:00
"drop table failed");
CHECK2(restarter.startNodes(&nodeId, 1) == 0,
2004-04-14 10:53:21 +02:00
"failed to start node");
CHECK2(restarter.waitClusterStarted() == 0,
2004-04-14 10:53:21 +02:00
"waitClusterStarted failed");
}
2004-04-14 10:53:21 +02:00
CHECK2(restarter.dumpStateOneNode(nodeId, &val, 1) == 0,
2004-04-14 10:53:21 +02:00
"Failed to set LCP to min value");
}
2004-04-14 10:53:21 +02:00
}
}
end:
dict->dropTable(pTab->getName());
return result;
}
#define APIERROR(error) \
{ g_err << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \
<< error.code << ", msg: " << error.message << "." << endl; \
}
int
runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){
Uint32 startvalues[5] = {256-2, 0, 256*256-2, ~0, 256*256*256-2};
int ret = NDBT_OK;
for (int jj = 0; jj < 5 && ret == NDBT_OK; jj++) {
char tabname[] = "AUTOINCTAB";
Uint32 startvalue = startvalues[jj];
NdbDictionary::Table myTable;
NdbDictionary::Column myColumn;
Ndb* myNdb = GETNDB(step);
NdbDictionary::Dictionary* myDict = myNdb->getDictionary();
if (myDict->getTable(tabname) != NULL) {
g_err << "NDB already has example table: " << tabname << endl;
APIERROR(myNdb->getNdbError());
return NDBT_FAILED;
}
myTable.setName(tabname);
myColumn.setName("ATTR1");
myColumn.setType(NdbDictionary::Column::Unsigned);
myColumn.setLength(1);
myColumn.setPrimaryKey(true);
2004-04-14 10:53:21 +02:00
myColumn.setNullable(false);
myColumn.setAutoIncrement(true);
if (startvalue != ~0) // check that default value starts with 1
myColumn.setAutoIncrementInitialValue(startvalue);
myTable.addColumn(myColumn);
if (myDict->createTable(myTable) == -1) {
g_err << "Failed to create table " << tabname << endl;
APIERROR(myNdb->getNdbError());
return NDBT_FAILED;
}
if (startvalue == ~0) // check that default value starts with 1
startvalue = 1;
for (int i = 0; i < 16; i++) {
Uint64 value = myNdb->getAutoIncrementValue(tabname, 1);
if (value != (startvalue+i)) {
g_err << "value = " << value << " expected " << startvalue+i << endl;;
APIERROR(myNdb->getNdbError());
// ret = NDBT_FAILED;
// break;
}
}
if (myDict->dropTable(tabname) == -1) {
g_err << "Failed to drop table " << tabname << endl;
APIERROR(myNdb->getNdbError());
ret = NDBT_FAILED;
}
}
return ret;
}
int
runTableRename(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
Ndb* pNdb = GETNDB(step);
NdbDictionary::Dictionary* dict = pNdb->getDictionary();
int records = ctx->getNumRecords();
const int loops = ctx->getNumLoops();
ndbout << "|- " << ctx->getTab()->getName() << endl;
for (int l = 0; l < loops && result == NDBT_OK ; l++){
const NdbDictionary::Table* pTab = ctx->getTab();
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
ctx->setTab(pTab2);
// Load table
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.loadTable(pNdb, records) != 0){
return NDBT_FAILED;
}
// Rename table
BaseString pTabName(pTab->getName());
BaseString pTabNewName(pTabName);
pTabNewName.append("xx");
const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str());
if (oldTable) {
NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str());
newTable.setName(pTabNewName.c_str());
CHECK2(dict->alterTable(newTable) == 0,
"TableRename failed");
}
else {
result = NDBT_FAILED;
}
// Verify table contents
NdbDictionary::Table pNewTab(pTabNewName.c_str());
UtilTransactions utilTrans(pNewTab);
if (utilTrans.clearTable(pNdb, records) != 0){
continue;
}
// Drop table
dict->dropTable(pNewTab.getName());
}
end:
return result;
}
int
runTableRenameNF(NDBT_Context* ctx, NDBT_Step* step){
NdbRestarter restarter;
if(restarter.getNumDbNodes() < 2)
return NDBT_OK;
int result = NDBT_OK;
Ndb* pNdb = GETNDB(step);
NdbDictionary::Dictionary* dict = pNdb->getDictionary();
int records = ctx->getNumRecords();
const int loops = ctx->getNumLoops();
ndbout << "|- " << ctx->getTab()->getName() << endl;
for (int l = 0; l < loops && result == NDBT_OK ; l++){
const NdbDictionary::Table* pTab = ctx->getTab();
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
ctx->setTab(pTab2);
// Load table
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.loadTable(pNdb, records) != 0){
return NDBT_FAILED;
}
BaseString pTabName(pTab->getName());
BaseString pTabNewName(pTabName);
pTabNewName.append("xx");
const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str());
if (oldTable) {
NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str());
newTable.setName(pTabNewName.c_str());
CHECK2(dict->alterTable(newTable) == 0,
"TableRename failed");
}
else {
result = NDBT_FAILED;
}
// Restart one node at a time
/**
* Need to run LCP at high rate otherwise
* packed replicas become "to many"
*/
int val = DumpStateOrd::DihMinTimeBetweenLCP;
if(restarter.dumpStateAllNodes(&val, 1) != 0){
do { CHECK(0); } while(0);
g_err << "Failed to set LCP to min value" << endl;
return NDBT_FAILED;
}
const int numNodes = restarter.getNumDbNodes();
for(int i = 0; i<numNodes; i++){
int nodeId = restarter.getDbNodeId(i);
2004-08-27 13:48:27 +02:00
int error = NF_codes[i].error_id;
2004-04-14 10:53:21 +02:00
g_info << "NF1: node = " << nodeId << " error code = " << error << endl;
CHECK2(restarter.restartOneDbNode(nodeId) == 0,
"failed to set restartOneDbNode");
CHECK2(restarter.waitClusterStarted() == 0,
"waitClusterStarted failed");
}
// Verify table contents
NdbDictionary::Table pNewTab(pTabNewName.c_str());
UtilTransactions utilTrans(pNewTab);
if (utilTrans.clearTable(pNdb, records) != 0){
continue;
}
// Drop table
dict->dropTable(pTabNewName.c_str());
}
end:
return result;
}
int
runTableRenameSR(NDBT_Context* ctx, NDBT_Step* step){
NdbRestarter restarter;
if(restarter.getNumDbNodes() < 2)
return NDBT_OK;
int result = NDBT_OK;
Ndb* pNdb = GETNDB(step);
NdbDictionary::Dictionary* dict = pNdb->getDictionary();
int records = ctx->getNumRecords();
const int loops = ctx->getNumLoops();
ndbout << "|- " << ctx->getTab()->getName() << endl;
for (int l = 0; l < loops && result == NDBT_OK ; l++){
// Rename table
const NdbDictionary::Table* pTab = ctx->getTab();
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
}
// Verify that table is in db
const NdbDictionary::Table* pTab2 =
NDBT_Table::discoverTableFromDb(pNdb, pTab->getName());
if (pTab2 == NULL){
ndbout << pTab->getName() << " was not found in DB"<< endl;
return NDBT_FAILED;
}
ctx->setTab(pTab2);
// Load table
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.loadTable(pNdb, records) != 0){
return NDBT_FAILED;
}
BaseString pTabName(pTab->getName());
BaseString pTabNewName(pTabName);
pTabNewName.append("xx");
const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str());
if (oldTable) {
NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str());
newTable.setName(pTabNewName.c_str());
CHECK2(dict->alterTable(newTable) == 0,
"TableRename failed");
}
else {
result = NDBT_FAILED;
}
// Restart cluster
/**
* Need to run LCP at high rate otherwise
* packed replicas become "to many"
*/
int val = DumpStateOrd::DihMinTimeBetweenLCP;
if(restarter.dumpStateAllNodes(&val, 1) != 0){
do { CHECK(0); } while(0);
g_err << "Failed to set LCP to min value" << endl;
return NDBT_FAILED;
}
CHECK2(restarter.restartAll() == 0,
"failed to set restartOneDbNode");
CHECK2(restarter.waitClusterStarted() == 0,
"waitClusterStarted failed");
// Verify table contents
NdbDictionary::Table pNewTab(pTabNewName.c_str());
UtilTransactions utilTrans(pNewTab);
if (utilTrans.clearTable(pNdb, records) != 0){
continue;
}
// Drop table
dict->dropTable(pTabNewName.c_str());
}
end:
return result;
}
static void
f(const NdbDictionary::Column * col){
if(col == 0){
abort();
}
}
int
runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){
Vector<char*> cols;
Vector<const NdbDictionary::Table*> tabs;
Ndb* pNdb = GETNDB(step);
const Uint32 count = NDBT_Tables::getNumTables();
for (int i=0; i < count; i++){
const NdbDictionary::Table * tab = NDBT_Tables::getTable(i);
pNdb->getDictionary()->createTable(* tab);
const NdbDictionary::Table * tab2 = pNdb->getDictionary()->getTable(tab->getName());
for(size_t j = 0; j<tab->getNoOfColumns(); j++){
cols.push_back((char*)tab2);
cols.push_back(strdup(tab->getColumn(j)->getName()));
}
}
const Uint32 times = 10000000;
ndbout_c("%d tables and %d columns",
NDBT_Tables::getNumTables(), cols.size()/2);
char ** tcols = cols.getBase();
srand(time(0));
Uint32 size = cols.size() / 2;
char ** columns = &cols[0];
Uint64 start = NdbTick_CurrentMillisecond();
for(int i = 0; i<times; i++){
int j = 2 * (rand() % size);
const NdbDictionary::Table* tab = (const NdbDictionary::Table*)tcols[j];
const char * col = tcols[j+1];
const NdbDictionary::Column* column = tab->getColumn(col);
f(column);
}
Uint64 stop = NdbTick_CurrentMillisecond();
stop -= start;
Uint64 per = stop;
per *= 1000;
per /= times;
ndbout_c("%d random getColumn(name) in %Ld ms -> %d us/get",
times, stop, per);
return NDBT_OK;
}
NDBT_TESTSUITE(testDict);
TESTCASE("CreateAndDrop",
"Try to create and drop the table loop number of times\n"){
INITIALIZER(runCreateAndDrop);
}
TESTCASE("CreateAndDropWithData",
"Try to create and drop the table when it's filled with data\n"
"do this loop number of times\n"){
INITIALIZER(runCreateAndDropWithData);
}
TESTCASE("CreateAndDropDuring",
"Try to create and drop the table when other thread is using it\n"
"do this loop number of times\n"){
STEP(runCreateAndDropDuring);
STEP(runUseTableUntilStopped);
}
TESTCASE("CreateInvalidTables",
"Try to create the invalid tables we have defined\n"){
INITIALIZER(runCreateInvalidTables);
}
TESTCASE("CreateTableWhenDbIsFull",
"Try to create a new table when db already is full\n"){
INITIALIZER(runCreateTheTable);
INITIALIZER(runFillTable);
INITIALIZER(runCreateTableWhenDbIsFull);
INITIALIZER(runDropTableWhenDbIsFull);
FINALIZER(runClearTable);
}
TESTCASE("FragmentTypeSingle",
"Create the table with fragment type Single\n"){
TC_PROPERTY("FragmentType", 1);
INITIALIZER(runTestFragmentTypes);
}
TESTCASE("FragmentTypeAll",
"Create the table with fragment type All\n"){
TC_PROPERTY("FragmentType", 2);
INITIALIZER(runTestFragmentTypes);
}
TESTCASE("FragmentTypeAllLarge",
"Create the table with fragment type AllLarge\n"){
TC_PROPERTY("FragmentType", 3);
INITIALIZER(runTestFragmentTypes);
}
TESTCASE("TemporaryTables",
"Create the table as temporary and make sure it doesn't\n"
"contain any data when system is restarted\n"){
INITIALIZER(runTestTemporaryTables);
}
TESTCASE("CreateMaxTables",
"Create tables until db says that it can't create any more\n"){
TC_PROPERTY("tables", 1000);
INITIALIZER(runCreateMaxTables);
FINALIZER(runDropMaxTables);
}
TESTCASE("PkSizes",
"Create tables with all different primary key sizes.\n"\
"Test all data operations insert, update, delete etc.\n"\
"Drop table."){
INITIALIZER(runPkSizes);
}
TESTCASE("StoreFrm",
"Test that a frm file can be properly stored as part of the\n"
"data in Dict."){
INITIALIZER(runStoreFrm);
}
TESTCASE("GetPrimaryKey",
"Test the function NdbDictionary::Column::getPrimaryKey\n"
"It should return true only if the column is part of \n"
"the primary key in the table"){
INITIALIZER(runGetPrimaryKey);
}
TESTCASE("StoreFrmError",
"Test that a frm file with too long length can't be stored."){
INITIALIZER(runStoreFrmError);
}
TESTCASE("NF1",
"Test that create table can handle NF (not master)"){
INITIALIZER(runNF1);
}
TESTCASE("TableRename",
"Test basic table rename"){
INITIALIZER(runTableRename);
}
TESTCASE("TableRenameNF",
"Test that table rename can handle node failure"){
INITIALIZER(runTableRenameNF);
}
TESTCASE("TableRenameSR",
"Test that table rename can handle system restart"){
INITIALIZER(runTableRenameSR);
}
TESTCASE("DictionaryPerf",
""){
INITIALIZER(runTestDictionaryPerf);
}
NDBT_TESTSUITE_END(testDict);
int main(int argc, const char** argv){
2004-09-15 11:49:18 +02:00
ndb_init();
2004-04-14 10:53:21 +02:00
// Tables should not be auto created
testDict.setCreateTable(false);
myRandom48Init(NdbTick_CurrentMillisecond());
return testDict.execute(argc, argv);
}