1 /* Copyright (c) 2003, 2008 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <NDBT_Test.hpp>
17 #include <NDBT_ReturnCodes.h>
18 #include <HugoTransactions.hpp>
19 #include <UtilTransactions.hpp>
24 Will include restart testing in future phases
25 #include <NdbRestarter.hpp>
26 #include <NdbRestarts.hpp>
29 /**** TOOL SECTION ****/
34 uint r
= (uint
)random();
48 #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
56 We need to look at the MAX epoch of the
57 mysql.ndb_binlog_index table so we will
58 know when the slave has caught up
62 unsigned int masterEpoch
= 0;
63 unsigned int slaveEpoch
= 0;
64 unsigned int slaveEpochOld
= 0;
68 //Create a DbUtil object for the master
69 DbUtil
master("mysql","");
72 if (!master
.connect())
77 //Get max epoch from master
78 if(master
.doQuery("SELECT MAX(epoch) FROM mysql.ndb_binlog_index", result
))
82 masterEpoch
= result
.columnAsInt("epoch");
85 Now we will pull current epoch from slave. If not the
86 same as master, we will continue to retrieve the epoch
87 and compare until it matches or we reach the max loops
91 //Create a dbutil object for the slave
92 DbUtil
slave("mysql",".slave");
100 while(slaveEpoch
!= masterEpoch
&& loopCnt
< maxLoops
)
102 if(slave
.doQuery("SELECT epoch FROM mysql.ndb_apply_status",result
))
106 slaveEpoch
= result
.columnAsInt("epoch");
108 if(slaveEpoch
!= slaveEpochOld
)
110 slaveEpochOld
= slaveEpoch
;
122 if(slaveEpoch
!= masterEpoch
)
124 g_err
<< "Slave not in sync with master!" << endl
;
131 verifySlaveLoad(BaseString
&table
)
135 unsigned int masterCount
= 0;
136 unsigned int slaveCount
= 0;
138 db
.assign("TEST_DB");
139 //sqlStm.assfmt("SELECT COUNT(*) FROM %s", table);
141 //First thing to do is sync slave
142 if(syncSlaveWithMaster())
144 g_err
<< "Verify Load -> Syncing with slave failed" << endl
;
148 //Now that slave is sync we can verify load
149 DbUtil
master(db
.c_str()," ");
152 if (!master
.connect())
157 if((masterCount
= master
.selectCountTable(table
.c_str())) == 0 )
162 //Create a DB Object for slave
163 DbUtil
slave(db
.c_str(),".slave");
166 if (!slave
.connect())
171 if((slaveCount
= slave
.selectCountTable(table
.c_str())) == 0 )
176 if(slaveCount
!= masterCount
)
178 g_err
<< "Verify Load -> Slave Count != Master Count "
186 createTEST_DB(NDBT_Context
* ctx
, NDBT_Step
* step
)
189 cdb
.assign("TEST_DB");
191 //Create a dbutil object
192 DbUtil
master("mysql","");
194 if (master
.connect())
196 if (master
.createDb(cdb
) == NDBT_OK
)
205 dropTEST_DB(NDBT_Context
* ctx
, NDBT_Step
* step
)
207 //Create an SQL Object
208 DbUtil
master("mysql","");
211 if (!master
.connect())
216 if(master
.doQuery("DROP DATABASE TEST_DB") != NDBT_OK
)
221 if(syncSlaveWithMaster() != NDBT_OK
)
223 g_err
<< "Drop DB -> Syncing with slave failed"
231 verifySlave(BaseString
& sqlStm
, BaseString
& db
, BaseString
& column
)
238 DbUtil
master(db
.c_str(),"");
239 DbUtil
slave(db
.c_str(),".slave");
241 if(syncSlaveWithMaster() != NDBT_OK
)
243 g_err
<< "Verify Slave rep1 -> Syncing with slave failed"
249 if (!master
.connect())
254 if(master
.doQuery(sqlStm
.c_str(),result
) != NDBT_OK
)
258 masterSum
= result
.columnAsInt(column
.c_str());
261 if (!slave
.connect())
266 if(slave
.doQuery(sqlStm
.c_str(),result
) != NDBT_OK
)
270 slaveSum
= result
.columnAsInt(column
.c_str());
272 if(masterSum
!= slaveSum
)
274 g_err
<< "VerifySlave -> masterSum != slaveSum..." << endl
;
281 /**** Test Section ****/
284 createDB(NDBT_Context
* ctx
, NDBT_Step
* step
)
287 cdb
.assign("TEST_DB");
289 //Create a dbutil object
290 DbUtil
master("mysql","");
292 if (master
.connect())
294 if (master
.createDb(cdb
) == NDBT_OK
)
303 createTable_rep1(NDBT_Context
* ctx
, NDBT_Step
* step
)
308 table
.assign("rep1");
309 db
.assign("TEST_DB");
311 //Ensure slave is up and ready
312 if(syncSlaveWithMaster() != NDBT_OK
)
314 g_err
<< "Create Table -> Syncing with slave failed"
319 //Create an SQL Object
320 DbUtil
master(db
.c_str(),"");
323 if (!master
.connect())
328 if (master
.doQuery("CREATE TABLE rep1 (c1 MEDIUMINT NOT NULL AUTO_INCREMENT,"
329 " c2 FLOAT, c3 CHAR(5), c4 bit(8), c5 FLOAT, c6 INT,"
330 " c7 INT, PRIMARY KEY (c1))ENGINE=NDB"))
334 ctx
->setProperty("TABLES",table
.c_str());
335 HugoTransactions
hugoTrans(*ctx
->getTab());
337 if (hugoTrans
.loadTable(GETNDB(step
), ctx
->getNumRecords(), 1, true, 0) != NDBT_OK
)
339 g_err
<< "Create Table -> Load failed!" << endl
;
343 if(verifySlaveLoad(table
)!= NDBT_OK
)
345 g_err
<< "Create Table -> Failed on verify slave load!"
349 //else everything is okay
354 stressNDB_rep1(NDBT_Context
* ctx
, NDBT_Step
* step
)
356 const NdbDictionary::Table
* table
= ctx
->getTab();
357 HugoTransactions
hugoTrans(* table
);
358 while(!ctx
->isTestStopped())
360 if (hugoTrans
.pkUpdateRecords(GETNDB(step
), ctx
->getNumRecords(), 1, 30) != 0)
362 g_err
<< "pkUpdate Failed!" << endl
;
365 if (hugoTrans
.scanUpdateRecords(GETNDB(step
), ctx
->getNumRecords(), 1, 30) != 0)
367 g_err
<< "scanUpdate Failed!" << endl
;
375 stressSQL_rep1(NDBT_Context
* ctx
, NDBT_Step
* step
)
379 DbUtil
master("TEST_DB","");
380 int loops
= ctx
->getNumLoops();
384 if (!master
.connect())
390 for (int j
= 0; loops
== 0 || j
< loops
; j
++)
392 record
= urandom(ctx
->getNumRecords());
393 sqlStm
.assfmt("UPDATE TEST_DB.rep1 SET c2 = 33.3221 where c1 = %u", record
);
394 if(master
.doQuery(sqlStm
.c_str()))
404 verifySlave_rep1(NDBT_Context
* ctx
, NDBT_Step
* step
)
410 sql
.assign("SELECT SUM(c3) FROM rep1");
411 db
.assign("TEST_DB");
414 if (verifySlave(sql
,db
,column
) != NDBT_OK
)
421 syncSlaveWithMaster()
422 {ensures slave is at same epoch as master}
424 verifySlaveLoad(BaseString *table)
425 {ensures slave table has same record count as master}
428 {Creates TEST_DB database on master}
431 {Drops TEST_DB database on master}
433 verifySlave(BaseString& sql, BaseSting& db, BaseSting& column)
434 {The SQL statement must sum a column and will verify
435 that the sum of the column is equal on master & slave}
439 NDBT_TESTSUITE(NdbRepStress
);
440 TESTCASE("PHASE_I_Stress","Basic Replication Stressing")
442 INITIALIZER(createDB
);
443 INITIALIZER(createTable_rep1
);
444 STEP(stressNDB_rep1
);
445 STEP(stressSQL_rep1
);
446 FINALIZER(verifySlave_rep1
);
447 FINALIZER(dropTEST_DB
);
449 NDBT_TESTSUITE_END(NdbRepStress
);
451 int main(int argc
, const char** argv
){
453 NdbRepStress
.setCreateAllTables(true);
454 return NdbRepStress
.execute(argc
, argv
);