~vadim-tk/percona-server/flushing-algo

« back to all changes in this revision

Viewing changes to storage/ndb/test/ndbapi/acrt/NdbRepStress.cpp

  • Committer: root
  • Date: 2011-10-29 01:34:40 UTC
  • Revision ID: root@hppro1.office.percona.com-20111029013440-qhnf4jk8kdjcf4e0
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <NDBT_Test.hpp>
 
17
#include <NDBT_ReturnCodes.h>
 
18
#include <HugoTransactions.hpp>
 
19
#include <UtilTransactions.hpp>
 
20
#include <DbUtil.hpp>
 
21
#include <mysql.h>
 
22
 
 
23
/*
 
24
Will include restart testing in future phases
 
25
#include <NdbRestarter.hpp>
 
26
#include <NdbRestarts.hpp>
 
27
*/
 
28
 
 
29
/**** TOOL SECTION ****/
 
30
 
 
31
static uint
 
32
urandom()
 
33
{
 
34
  uint r = (uint)random();
 
35
  return r;
 
36
}
 
37
 
 
38
static uint
 
39
urandom(uint m)
 
40
{
 
41
  if (m == 0)
 
42
    return NDBT_OK;
 
43
  uint r = urandom();
 
44
  r = r % m;
 
45
  return r;
 
46
}
 
47
 
 
48
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
 
49
/*
 
50
*/
 
51
 
 
52
int 
 
53
syncSlaveWithMaster()
 
54
{
 
55
  /* 
 
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
 
59
  */
 
60
 
 
61
  SqlResultSet result;
 
62
  unsigned int masterEpoch = 0;
 
63
  unsigned int slaveEpoch = 0;
 
64
  unsigned int slaveEpochOld = 0;
 
65
  int maxLoops = 100;
 
66
  int loopCnt = 0;
 
67
  
 
68
  //Create a DbUtil object for the master
 
69
  DbUtil master("mysql","");
 
70
 
 
71
  //Login to Master
 
72
  if (!master.connect())
 
73
  {
 
74
    return NDBT_FAILED;
 
75
  } 
 
76
 
 
77
    //Get max epoch from master
 
78
  if(master.doQuery("SELECT MAX(epoch) FROM mysql.ndb_binlog_index", result))
 
79
  {
 
80
    return NDBT_FAILED;
 
81
  }
 
82
  masterEpoch = result.columnAsInt("epoch");
 
83
  
 
84
  /*
 
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
 
88
     allowed.
 
89
  */
 
90
 
 
91
  //Create a dbutil object for the slave
 
92
  DbUtil slave("mysql",".slave");
 
93
 
 
94
  //Login to slave
 
95
  if (!slave.connect())
 
96
  {
 
97
    return NDBT_FAILED;
 
98
  }
 
99
 
 
100
  while(slaveEpoch != masterEpoch && loopCnt < maxLoops)
 
101
  {
 
102
    if(slave.doQuery("SELECT epoch FROM mysql.ndb_apply_status",result))
 
103
    {
 
104
      return NDBT_FAILED;
 
105
    }
 
106
    slaveEpoch = result.columnAsInt("epoch");
 
107
   
 
108
    if(slaveEpoch != slaveEpochOld)
 
109
    {
 
110
      slaveEpochOld = slaveEpoch;
 
111
      if(loopCnt > 0)
 
112
        loopCnt--;
 
113
      sleep(3);
 
114
    }
 
115
    else
 
116
    {
 
117
      sleep(1);
 
118
      loopCnt++;
 
119
    }
 
120
  }
 
121
 
 
122
  if(slaveEpoch != masterEpoch)
 
123
  {
 
124
    g_err << "Slave not in sync with master!" << endl;
 
125
    return NDBT_FAILED;
 
126
  }
 
127
  return NDBT_OK;
 
128
}
 
129
 
 
130
int
 
131
verifySlaveLoad(BaseString &table)
 
132
{
 
133
  //BaseString  sqlStm;
 
134
  BaseString  db;
 
135
  unsigned int masterCount = 0;
 
136
  unsigned int slaveCount  = 0;
 
137
 
 
138
  db.assign("TEST_DB");
 
139
  //sqlStm.assfmt("SELECT COUNT(*) FROM %s", table);
 
140
 
 
141
  //First thing to do is sync slave
 
142
  if(syncSlaveWithMaster())
 
143
  {
 
144
    g_err << "Verify Load -> Syncing with slave failed" << endl;
 
145
    return NDBT_FAILED;
 
146
  }
 
147
 
 
148
  //Now that slave is sync we can verify load
 
149
  DbUtil master(db.c_str()," ");
 
150
 
 
151
  //Login to Master
 
152
  if (!master.connect())
 
153
  {
 
154
    return NDBT_FAILED;
 
155
  }
 
156
 
 
157
  if((masterCount = master.selectCountTable(table.c_str())) == 0 )
 
158
  {
 
159
    return NDBT_FAILED;
 
160
  }
 
161
  
 
162
  //Create a DB Object for slave
 
163
  DbUtil slave(db.c_str(),".slave");
 
164
 
 
165
  //Login to slave
 
166
  if (!slave.connect())
 
167
  {
 
168
    return NDBT_FAILED;
 
169
  }
 
170
 
 
171
  if((slaveCount = slave.selectCountTable(table.c_str())) == 0 )
 
172
  {
 
173
    return NDBT_FAILED;
 
174
  }
 
175
  
 
176
  if(slaveCount != masterCount)
 
177
  {
 
178
    g_err << "Verify Load -> Slave Count != Master Count "
 
179
          << endl;
 
180
    return NDBT_FAILED;
 
181
  }
 
182
  return NDBT_OK;
 
183
}
 
184
 
 
185
int
 
186
createTEST_DB(NDBT_Context* ctx, NDBT_Step* step)
 
187
{
 
188
  BaseString cdb;
 
189
  cdb.assign("TEST_DB");
 
190
 
 
191
  //Create a dbutil object
 
192
  DbUtil master("mysql","");
 
193
 
 
194
  if (master.connect())
 
195
  {
 
196
    if (master.createDb(cdb) == NDBT_OK)
 
197
    {
 
198
      return NDBT_OK;
 
199
    }
 
200
  }
 
201
  return NDBT_FAILED;
 
202
}
 
203
 
 
204
int
 
205
dropTEST_DB(NDBT_Context* ctx, NDBT_Step* step)
 
206
{
 
207
  //Create an SQL Object
 
208
  DbUtil master("mysql","");
 
209
 
 
210
  //Login to Master
 
211
  if (!master.connect())
 
212
  {
 
213
    return NDBT_FAILED;
 
214
  }
 
215
 
 
216
  if(master.doQuery("DROP DATABASE TEST_DB") != NDBT_OK)
 
217
  {
 
218
    return NDBT_FAILED;
 
219
  }
 
220
 
 
221
  if(syncSlaveWithMaster() != NDBT_OK)
 
222
  {
 
223
    g_err << "Drop DB -> Syncing with slave failed"
 
224
          << endl;
 
225
    return NDBT_FAILED;
 
226
  }
 
227
  return NDBT_OK;
 
228
}
 
229
 
 
230
int
 
231
verifySlave(BaseString& sqlStm, BaseString& db, BaseString& column)
 
232
{
 
233
  SqlResultSet result;
 
234
  float       masterSum;
 
235
  float       slaveSum;
 
236
 
 
237
  //Create SQL Objects
 
238
  DbUtil     master(db.c_str(),"");
 
239
  DbUtil     slave(db.c_str(),".slave");
 
240
 
 
241
  if(syncSlaveWithMaster() != NDBT_OK)
 
242
  {
 
243
    g_err << "Verify Slave rep1 -> Syncing with slave failed"
 
244
          << endl;
 
245
    return NDBT_FAILED;
 
246
  }
 
247
 
 
248
  //Login to Master
 
249
  if (!master.connect())
 
250
  {
 
251
    return NDBT_FAILED;
 
252
  }
 
253
 
 
254
  if(master.doQuery(sqlStm.c_str(),result) != NDBT_OK)
 
255
  {
 
256
    return NDBT_FAILED;
 
257
  }
 
258
  masterSum = result.columnAsInt(column.c_str());
 
259
  
 
260
  //Login to slave
 
261
  if (!slave.connect())
 
262
  {
 
263
    return NDBT_FAILED;
 
264
  }
 
265
 
 
266
  if(slave.doQuery(sqlStm.c_str(),result) != NDBT_OK)
 
267
  {
 
268
     return NDBT_FAILED;
 
269
  }
 
270
  slaveSum = result.columnAsInt(column.c_str());
 
271
  
 
272
  if(masterSum != slaveSum)
 
273
  {
 
274
    g_err << "VerifySlave -> masterSum != slaveSum..." << endl;
 
275
    return NDBT_FAILED;
 
276
  }
 
277
  return NDBT_OK;
 
278
}
 
279
 
 
280
 
 
281
/**** Test Section ****/
 
282
 
 
283
int 
 
284
createDB(NDBT_Context* ctx, NDBT_Step* step)
 
285
{
 
286
  BaseString cdb;
 
287
  cdb.assign("TEST_DB");
 
288
 
 
289
  //Create a dbutil object
 
290
  DbUtil master("mysql","");
 
291
 
 
292
  if (master.connect())
 
293
  {
 
294
    if (master.createDb(cdb) == NDBT_OK)
 
295
    {
 
296
      return NDBT_OK;
 
297
    }
 
298
  }
 
299
  return NDBT_FAILED;
 
300
}
 
301
 
 
302
int
 
303
createTable_rep1(NDBT_Context* ctx, NDBT_Step* step)
 
304
{
 
305
  BaseString table;
 
306
  BaseString db;
 
307
 
 
308
  table.assign("rep1");
 
309
  db.assign("TEST_DB");
 
310
 
 
311
  //Ensure slave is up and ready
 
312
  if(syncSlaveWithMaster() != NDBT_OK)
 
313
  {
 
314
    g_err << "Create Table -> Syncing with slave failed"
 
315
          << endl;
 
316
    return NDBT_FAILED;
 
317
  }
 
318
 
 
319
  //Create an SQL Object
 
320
  DbUtil master(db.c_str(),"");
 
321
 
 
322
  //Login to Master
 
323
  if (!master.connect())
 
324
  {
 
325
    return NDBT_FAILED;
 
326
  }
 
327
 
 
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"))
 
331
  {
 
332
    return NDBT_FAILED;
 
333
  }
 
334
  ctx->setProperty("TABLES",table.c_str());
 
335
  HugoTransactions hugoTrans(*ctx->getTab());
 
336
 
 
337
  if (hugoTrans.loadTable(GETNDB(step), ctx->getNumRecords(), 1, true, 0) != NDBT_OK)
 
338
  {
 
339
    g_err << "Create Table -> Load failed!" << endl;
 
340
    return NDBT_FAILED;
 
341
  }
 
342
 
 
343
  if(verifySlaveLoad(table)!= NDBT_OK)
 
344
  {
 
345
    g_err << "Create Table -> Failed on verify slave load!" 
 
346
          << endl;
 
347
    return NDBT_FAILED;
 
348
  }
 
349
  //else everything is okay  
 
350
  return NDBT_OK;
 
351
}
 
352
 
 
353
int
 
354
stressNDB_rep1(NDBT_Context* ctx, NDBT_Step* step)
 
355
{
 
356
  const NdbDictionary::Table * table= ctx->getTab();
 
357
  HugoTransactions hugoTrans(* table);
 
358
  while(!ctx->isTestStopped())
 
359
  {
 
360
    if (hugoTrans.pkUpdateRecords(GETNDB(step), ctx->getNumRecords(), 1, 30) != 0)
 
361
    {
 
362
      g_err << "pkUpdate Failed!" << endl;
 
363
      return NDBT_FAILED;
 
364
    }
 
365
    if (hugoTrans.scanUpdateRecords(GETNDB(step), ctx->getNumRecords(), 1, 30) != 0)
 
366
    {
 
367
      g_err << "scanUpdate Failed!" << endl;
 
368
      return NDBT_FAILED;
 
369
    }
 
370
  }
 
371
  return NDBT_OK;
 
372
}
 
373
 
 
374
int
 
375
stressSQL_rep1(NDBT_Context* ctx, NDBT_Step* step)
 
376
{
 
377
  BaseString sqlStm;
 
378
 
 
379
  DbUtil master("TEST_DB","");
 
380
  int loops = ctx->getNumLoops();
 
381
  uint record = 0;
 
382
 
 
383
  //Login to Master
 
384
  if (!master.connect())
 
385
  {
 
386
    ctx->stopTest();
 
387
    return NDBT_FAILED;
 
388
  }
 
389
 
 
390
  for (int j= 0; loops == 0 || j < loops; j++)
 
391
  {
 
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()))
 
395
    {
 
396
      return NDBT_FAILED;
 
397
    }
 
398
  }
 
399
  ctx->stopTest();
 
400
  return NDBT_OK;
 
401
}
 
402
 
 
403
int
 
404
verifySlave_rep1(NDBT_Context* ctx, NDBT_Step* step)
 
405
{
 
406
  BaseString sql;
 
407
  BaseString db;
 
408
  BaseString column;
 
409
 
 
410
  sql.assign("SELECT SUM(c3) FROM rep1");
 
411
  db.assign("TEST_DB");
 
412
  column.assign("c3");
 
413
 
 
414
  if (verifySlave(sql,db,column) != NDBT_OK)
 
415
    return NDBT_FAILED;
 
416
  return NDBT_OK;
 
417
}
 
418
 
 
419
/* TOOLS LIST
 
420
 
 
421
 syncSlaveWithMaster() 
 
422
 {ensures slave is at same epoch as master}
 
423
 
 
424
 verifySlaveLoad(BaseString *table) 
 
425
 {ensures slave table has same record count as master}
 
426
 
 
427
 createTEST_DB() 
 
428
 {Creates TEST_DB database on master}
 
429
 
 
430
 dropTEST_DB() 
 
431
 {Drops TEST_DB database on master} 
 
432
 
 
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}
 
436
*/
 
437
                     
 
438
 
 
439
NDBT_TESTSUITE(NdbRepStress);
 
440
TESTCASE("PHASE_I_Stress","Basic Replication Stressing") 
 
441
{
 
442
  INITIALIZER(createDB);
 
443
  INITIALIZER(createTable_rep1);
 
444
  STEP(stressNDB_rep1);
 
445
  STEP(stressSQL_rep1);
 
446
  FINALIZER(verifySlave_rep1);
 
447
  FINALIZER(dropTEST_DB);
 
448
}
 
449
NDBT_TESTSUITE_END(NdbRepStress);
 
450
 
 
451
int main(int argc, const char** argv){
 
452
  ndb_init();
 
453
  NdbRepStress.setCreateAllTables(true);
 
454
  return NdbRepStress.execute(argc, argv);
 
455
}
 
456