1 /*
2 Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include <NDBT_Test.hpp>
26 #include <NDBT_ReturnCodes.h>
27 #include <HugoTransactions.hpp>
28 #include <UtilTransactions.hpp>
29 #include <NdbRestarter.hpp>
30 #include <signaldata/DictTabInfo.hpp>
31 #include <Bitmask.hpp>
32 #include <random.h>
33 #include <signaldata/DumpStateOrd.hpp>
34
35 /**
36 * TODO
37 * dirtyWrite, write, dirtyUpdate
38 * delete should be visible to same transaction
39 *
40 */
runLoadTable2(NDBT_Context * ctx,NDBT_Step * step)41 int runLoadTable2(NDBT_Context* ctx, NDBT_Step* step)
42 {
43 int records = ctx->getNumRecords();
44 HugoTransactions hugoTrans(*ctx->getTab());
45 if (hugoTrans.loadTable(GETNDB(step), records, 512, false, 0, true) != 0){
46 return NDBT_FAILED;
47 }
48 return NDBT_OK;
49 }
50
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)51 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
52 {
53 int records = ctx->getNumRecords();
54 HugoTransactions hugoTrans(*ctx->getTab());
55 if (hugoTrans.loadTable(GETNDB(step), records) != 0){
56 return NDBT_FAILED;
57 }
58 return NDBT_OK;
59 }
60
runInsert(NDBT_Context * ctx,NDBT_Step * step)61 int runInsert(NDBT_Context* ctx, NDBT_Step* step){
62
63 int records = ctx->getNumRecords();
64 HugoTransactions hugoTrans(*ctx->getTab());
65 // Insert records, dont allow any
66 // errors(except temporary) while inserting
67 if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 0){
68 return NDBT_FAILED;
69 }
70 return NDBT_OK;
71 }
72
runInsertTwice(NDBT_Context * ctx,NDBT_Step * step)73 int runInsertTwice(NDBT_Context* ctx, NDBT_Step* step){
74
75 int records = ctx->getNumRecords();
76 HugoTransactions hugoTrans(*ctx->getTab());
77 // Insert records, expect primary key violation 630
78 if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 630){
79 return NDBT_FAILED;
80 }
81 return NDBT_OK;
82 }
83
runVerifyInsert(NDBT_Context * ctx,NDBT_Step * step)84 int runVerifyInsert(NDBT_Context* ctx, NDBT_Step* step){
85 int records = ctx->getNumRecords();
86
87 HugoTransactions hugoTrans(*ctx->getTab());
88 if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, false) != 0){
89 return NDBT_FAILED;
90 }
91 return NDBT_OK;
92 }
93
runInsertUntilStopped(NDBT_Context * ctx,NDBT_Step * step)94 int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
95 int records = ctx->getNumRecords();
96 int i = 0;
97 HugoTransactions hugoTrans(*ctx->getTab());
98 while (ctx->isTestStopped() == false) {
99 g_info << i << ": ";
100 if (hugoTrans.loadTable(GETNDB(step), records) != 0){
101 g_info << endl;
102 return NDBT_FAILED;
103 }
104 i++;
105 }
106 g_info << endl;
107 return NDBT_OK;
108 }
109
runClearTable(NDBT_Context * ctx,NDBT_Step * step)110 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
111 int records = ctx->getNumRecords();
112 int batchSize = ctx->getProperty("BatchSize", 1);
113
114 HugoTransactions hugoTrans(*ctx->getTab());
115 if (hugoTrans.pkDelRecords(GETNDB(step), records, batchSize) != 0){
116 return NDBT_FAILED;
117 }
118 return NDBT_OK;
119 }
120
runPkDelete(NDBT_Context * ctx,NDBT_Step * step)121 int runPkDelete(NDBT_Context* ctx, NDBT_Step* step){
122 int loops = ctx->getNumLoops();
123 int records = ctx->getNumRecords();
124
125 int i = 0;
126 HugoTransactions hugoTrans(*ctx->getTab());
127 while (i<loops) {
128 g_info << i << ": ";
129 if (hugoTrans.pkDelRecords(GETNDB(step), records) != 0){
130 g_info << endl;
131 return NDBT_FAILED;
132 }
133 // Load table, don't allow any primary key violations
134 if (hugoTrans.loadTable(GETNDB(step), records, 512, false) != 0){
135 g_info << endl;
136 return NDBT_FAILED;
137 }
138 i++;
139 }
140 g_info << endl;
141 return NDBT_OK;
142 }
143
144
runPkRead(NDBT_Context * ctx,NDBT_Step * step)145 int runPkRead(NDBT_Context* ctx, NDBT_Step* step){
146 int loops = ctx->getNumLoops();
147 int records = ctx->getNumRecords();
148 int batchSize = ctx->getProperty("BatchSize", 1);
149 int lm = ctx->getProperty("LockMode", NdbOperation::LM_Read);
150 int i = 0;
151 HugoTransactions hugoTrans(*ctx->getTab());
152 while (i<loops) {
153 g_info << i << ": ";
154 if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize,
155 (NdbOperation::LockMode)lm) != NDBT_OK){
156 g_info << endl;
157 return NDBT_FAILED;
158 }
159 i++;
160 }
161 g_info << endl;
162 return NDBT_OK;
163 }
164
runPkReadUntilStopped(NDBT_Context * ctx,NDBT_Step * step)165 int runPkReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
166 int records = ctx->getNumRecords();
167 int batchSize = ctx->getProperty("BatchSize", 1);
168 int i = 0;
169 HugoTransactions hugoTrans(*ctx->getTab());
170 while (ctx->isTestStopped() == false) {
171 g_info << i << ": ";
172 if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize) != 0){
173 g_info << endl;
174 return NDBT_FAILED;
175 }
176 i++;
177 }
178 g_info << endl;
179 return NDBT_OK;
180 }
181
runPkUpdate(NDBT_Context * ctx,NDBT_Step * step)182 int runPkUpdate(NDBT_Context* ctx, NDBT_Step* step){
183 int loops = ctx->getNumLoops();
184 int records = ctx->getNumRecords();
185 int batchSize = ctx->getProperty("BatchSize", 1);
186 int i = 0;
187 HugoTransactions hugoTrans(*ctx->getTab());
188 while (i<loops) {
189 g_info << "|- " << i << ": ";
190 if (hugoTrans.pkUpdateRecords(GETNDB(step), records, batchSize) != 0){
191 g_info << endl;
192 return NDBT_FAILED;
193 }
194 i++;
195 }
196 g_info << endl;
197 return NDBT_OK;
198 }
199
runPkUpdateUntilStopped(NDBT_Context * ctx,NDBT_Step * step)200 int runPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
201 int records = ctx->getNumRecords();
202 int batchSize = ctx->getProperty("BatchSize", 1);
203 int i = 0;
204 HugoTransactions hugoTrans(*ctx->getTab());
205 while (ctx->isTestStopped()) {
206 g_info << i << ": ";
207 if (hugoTrans.pkUpdateRecords(GETNDB(step), records, batchSize) != 0){
208 g_info << endl;
209 return NDBT_FAILED;
210 }
211 i++;
212 }
213 g_info << endl;
214 return NDBT_OK;
215 }
216
runLocker(NDBT_Context * ctx,NDBT_Step * step)217 int runLocker(NDBT_Context* ctx, NDBT_Step* step){
218 int result = NDBT_OK;
219 int records = ctx->getNumRecords();
220 HugoTransactions hugoTrans(*ctx->getTab());
221
222 if (hugoTrans.lockRecords(GETNDB(step), records, 10, 500) != 0){
223 result = NDBT_FAILED;
224 }
225 ctx->stopTest();
226
227 return result;
228 }
229
230 int
runInsertOne(NDBT_Context * ctx,NDBT_Step * step)231 runInsertOne(NDBT_Context* ctx, NDBT_Step* step){
232
233 if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){
234 abort();
235 }
236
237 while(ctx->getProperty("Read1Performed", (Uint32)0) == 0){
238 NdbSleep_MilliSleep(20);
239 }
240
241 HugoTransactions hugoTrans(*ctx->getTab());
242
243 if (hugoTrans.loadTable(GETNDB(step), 1, 1) != 0){
244 return NDBT_FAILED;
245 }
246
247 ctx->setProperty("InsertCommitted", 1);
248
249 NdbSleep_SecSleep(2);
250
251 return NDBT_OK;
252 }
253
254 static
255 int
readOneNoCommit(Ndb * pNdb,NdbConnection * pTrans,const NdbDictionary::Table * tab,NDBT_ResultRow * row)256 readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans,
257 const NdbDictionary::Table* tab,NDBT_ResultRow * row){
258 int a;
259 NdbOperation * pOp = pTrans->getNdbOperation(tab->getName());
260 if (pOp == NULL){
261 ERR(pTrans->getNdbError());
262 return NDBT_FAILED;
263 }
264
265 HugoTransactions tmp(*tab);
266
267 int check = pOp->readTuple();
268 if( check == -1 ) {
269 ERR(pTrans->getNdbError());
270 return NDBT_FAILED;
271 }
272
273 // Define primary keys
274 for(a = 0; a<tab->getNoOfColumns(); a++){
275 if (tab->getColumn(a)->getPrimaryKey() == true){
276 if(tmp.equalForAttr(pOp, a, 0) != 0){
277 ERR(pTrans->getNdbError());
278 return NDBT_FAILED;
279 }
280 }
281 }
282
283 // Define attributes to read
284 for(a = 0; a<tab->getNoOfColumns(); a++){
285 if((row->attributeStore(a) =
286 pOp->getValue(tab->getColumn(a)->getName())) == 0) {
287 ERR(pTrans->getNdbError());
288 return NDBT_FAILED;
289 }
290 }
291
292 check = pTrans->execute(NoCommit);
293 if( check == -1 ) {
294 const NdbError err = pTrans->getNdbError();
295 ERR(err);
296 return err.code;
297 }
298 return NDBT_OK;
299 }
300
301 int
runReadOne(NDBT_Context * ctx,NDBT_Step * step)302 runReadOne(NDBT_Context* ctx, NDBT_Step* step){
303
304 Ndb* pNdb = GETNDB(step);
305 const NdbDictionary::Table* tab = ctx->getTab();
306 NDBT_ResultRow row1(*tab);
307 NDBT_ResultRow row2(*tab);
308
309 if(ctx->getProperty("Read1Performed", (Uint32)0) != 0){
310 abort();
311 }
312
313 if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){
314 abort();
315 }
316
317 NdbConnection * pTrans = pNdb->startTransaction();
318 if (pTrans == NULL) {
319 abort();
320 }
321
322 // Read a record with NoCommit
323 // Since the record isn't inserted yet it wil return 626
324 const int res1 = readOneNoCommit(pNdb, pTrans, tab, &row1);
325 g_info << "|- res1 = " << res1 << endl;
326
327 ctx->setProperty("Read1Performed", 1);
328
329 while(ctx->getProperty("InsertCommitted", (Uint32)0) == 0 &&
330 !ctx->isTestStopped()){
331 g_info << "|- Waiting for insert" << endl;
332 NdbSleep_MilliSleep(20);
333 }
334
335 if(ctx->isTestStopped()){
336 abort();
337 }
338
339 // Now the record should have been inserted
340 // Read it once again in the same transaction
341 // Should also reutrn 626 if reads are consistent
342
343 // NOTE! Currently it's not possible to start a new operation
344 // on a transaction that has returned an error code
345 // This is wat fail in this test
346 // MASV 20030624
347 const int res2 = readOneNoCommit(pNdb, pTrans, tab, &row2);
348
349 pTrans->execute(Commit);
350 pNdb->closeTransaction(pTrans);
351 g_info << "|- res2 = " << res2 << endl;
352
353 if (res2 == 626 && res1 == res2)
354 return NDBT_OK;
355 else
356 return NDBT_FAILED;
357 }
358
runFillTable(NDBT_Context * ctx,NDBT_Step * step)359 int runFillTable(NDBT_Context* ctx, NDBT_Step* step){
360 int batch = 512; //4096;
361 HugoTransactions hugoTrans(*ctx->getTab());
362 if (hugoTrans.fillTable(GETNDB(step), batch ) != 0){
363 return NDBT_FAILED;
364 }
365 return NDBT_OK;
366 }
367
runClearTable2(NDBT_Context * ctx,NDBT_Step * step)368 int runClearTable2(NDBT_Context* ctx, NDBT_Step* step){
369 int records = ctx->getNumRecords();
370
371 UtilTransactions utilTrans(*ctx->getTab());
372 if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){
373 return NDBT_FAILED;
374 }
375 return NDBT_OK;
376 }
377
378 #define CHECK(b) if (!(b)) { \
379 ndbout << "ERR: "<< step->getName() \
380 << " failed on line " << __LINE__ << endl; \
381 result = NDBT_FAILED; \
382 break; }
383
runNoCommitSleep(NDBT_Context * ctx,NDBT_Step * step)384 int runNoCommitSleep(NDBT_Context* ctx, NDBT_Step* step){
385 int result = NDBT_OK;
386 HugoOperations hugoOps(*ctx->getTab());
387 Ndb* pNdb = GETNDB(step);
388 int sleepTime = 100; // ms
389 for (int i = 2; i < 8; i++){
390
391 CHECK(hugoOps.startTransaction(pNdb) == 0);
392 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
393 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
394
395 ndbout << i <<": Sleeping for " << sleepTime << " ms" << endl;
396 NdbSleep_MilliSleep(sleepTime);
397
398 // Dont care about result of these ops
399 hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive);
400 hugoOps.closeTransaction(pNdb);
401
402 sleepTime = sleepTime *i;
403 }
404
405 hugoOps.closeTransaction(pNdb);
406
407 return result;
408 }
409
runCommit626(NDBT_Context * ctx,NDBT_Step * step)410 int runCommit626(NDBT_Context* ctx, NDBT_Step* step){
411 int result = NDBT_OK;
412 HugoOperations hugoOps(*ctx->getTab());
413 Ndb* pNdb = GETNDB(step);
414
415 do{
416 // Commit transaction
417 CHECK(hugoOps.startTransaction(pNdb) == 0);
418 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
419 CHECK(hugoOps.execute_Commit(pNdb) == 626);
420 CHECK(hugoOps.closeTransaction(pNdb) == 0);
421
422 // Commit transaction
423 // Multiple operations
424 CHECK(hugoOps.startTransaction(pNdb) == 0);
425 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
426 CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
427 CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
428 CHECK(hugoOps.execute_Commit(pNdb) == 626);
429 }while(false);
430
431 hugoOps.closeTransaction(pNdb);
432
433 return result;
434 }
435
runCommit630(NDBT_Context * ctx,NDBT_Step * step)436 int runCommit630(NDBT_Context* ctx, NDBT_Step* step){
437 int result = NDBT_OK;
438 HugoOperations hugoOps(*ctx->getTab());
439 Ndb* pNdb = GETNDB(step);
440
441 do{
442 // Commit transaction
443 CHECK(hugoOps.startTransaction(pNdb) == 0);
444 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
445 CHECK(hugoOps.execute_Commit(pNdb) == 630);
446 }while(false);
447
448 hugoOps.closeTransaction(pNdb);
449
450 return result;
451 }
452
runCommit_TryCommit626(NDBT_Context * ctx,NDBT_Step * step)453 int runCommit_TryCommit626(NDBT_Context* ctx, NDBT_Step* step){
454 int result = NDBT_OK;
455 HugoOperations hugoOps(*ctx->getTab());
456 Ndb* pNdb = GETNDB(step);
457
458 do{
459 // Commit transaction, TryCommit
460 CHECK(hugoOps.startTransaction(pNdb) == 0);
461 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
462 CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626);
463 CHECK(hugoOps.closeTransaction(pNdb) == 0);
464
465 // Commit transaction, TryCommit
466 // Several operations in one transaction
467 // The insert is OK
468 CHECK(hugoOps.startTransaction(pNdb) == 0);
469 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
470 CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
471 CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
472 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
473 CHECK(hugoOps.pkReadRecord(pNdb, 4, 1, NdbOperation::LM_Exclusive) == 0);
474 CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626);
475 }while(false);
476
477 hugoOps.closeTransaction(pNdb);
478
479 return result;
480 }
481
runCommit_TryCommit630(NDBT_Context * ctx,NDBT_Step * step)482 int runCommit_TryCommit630(NDBT_Context* ctx, NDBT_Step* step){
483 int result = NDBT_OK;
484 HugoOperations hugoOps(*ctx->getTab());
485 Ndb* pNdb = GETNDB(step);
486
487 do{
488 // Commit transaction, TryCommit
489 CHECK(hugoOps.startTransaction(pNdb) == 0);
490 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
491 CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 630);
492 }while(false);
493
494 hugoOps.closeTransaction(pNdb);
495
496 return result;
497 }
498
runCommit_CommitAsMuchAsPossible626(NDBT_Context * ctx,NDBT_Step * step)499 int runCommit_CommitAsMuchAsPossible626(NDBT_Context* ctx, NDBT_Step* step){
500 int result = NDBT_OK;
501 HugoOperations hugoOps(*ctx->getTab());
502 Ndb* pNdb = GETNDB(step);
503
504 do{
505 // Commit transaction, CommitAsMuchAsPossible
506 CHECK(hugoOps.startTransaction(pNdb) == 0);
507 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
508 CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626);
509 CHECK(hugoOps.closeTransaction(pNdb) == 0);
510
511 // Commit transaction, CommitAsMuchAsPossible
512 CHECK(hugoOps.startTransaction(pNdb) == 0);
513 CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
514 CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
515 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
516 CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626);
517 CHECK(hugoOps.closeTransaction(pNdb) == 0);
518
519 CHECK(hugoOps.startTransaction(pNdb) == 0);
520 CHECK(hugoOps.pkReadRecord(pNdb, 1) == 0);
521 CHECK(hugoOps.execute_Commit(pNdb) == 0);
522 CHECK(hugoOps.closeTransaction(pNdb) == 0);
523 } while(false);
524
525 hugoOps.closeTransaction(pNdb);
526
527 return result;
528 }
529
runCommit_CommitAsMuchAsPossible630(NDBT_Context * ctx,NDBT_Step * step)530 int runCommit_CommitAsMuchAsPossible630(NDBT_Context* ctx, NDBT_Step* step){
531 int result = NDBT_OK;
532 HugoOperations hugoOps(*ctx->getTab());
533 Ndb* pNdb = GETNDB(step);
534
535 do{
536 // Commit transaction, CommitAsMuchAsPossible
537 CHECK(hugoOps.startTransaction(pNdb) == 0);
538 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
539 CHECK(hugoOps.pkDeleteRecord(pNdb, 2) == 0);
540 CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 630);
541 CHECK(hugoOps.closeTransaction(pNdb) == 0);
542
543 CHECK(hugoOps.startTransaction(pNdb) == 0);
544 CHECK(hugoOps.pkReadRecord(pNdb, 2) == 0);
545 CHECK(hugoOps.execute_Commit(pNdb) == 626);
546 } while(false);
547
548 hugoOps.closeTransaction(pNdb);
549
550 return result;
551 }
552
runNoCommit626(NDBT_Context * ctx,NDBT_Step * step)553 int runNoCommit626(NDBT_Context* ctx, NDBT_Step* step){
554 int result = NDBT_OK;
555 HugoOperations hugoOps(*ctx->getTab());
556 Ndb* pNdb = GETNDB(step);
557
558 do{
559 // No commit transaction, readTuple
560 CHECK(hugoOps.startTransaction(pNdb) == 0);
561 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
562 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
563 CHECK(hugoOps.closeTransaction(pNdb) == 0);
564
565 // No commit transaction, readTupleExcluive
566 CHECK(hugoOps.startTransaction(pNdb) == 0);
567 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
568 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
569 }while(false);
570
571 hugoOps.closeTransaction(pNdb);
572
573 return result;
574 }
575
runNoCommit630(NDBT_Context * ctx,NDBT_Step * step)576 int runNoCommit630(NDBT_Context* ctx, NDBT_Step* step){
577 int result = NDBT_OK;
578 HugoOperations hugoOps(*ctx->getTab());
579 Ndb* pNdb = GETNDB(step);
580
581 do{
582 // No commit transaction
583 CHECK(hugoOps.startTransaction(pNdb) == 0);
584 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
585 CHECK(hugoOps.execute_NoCommit(pNdb) == 630);
586 }while(false);
587
588 hugoOps.closeTransaction(pNdb);
589
590 return result;
591 }
592
runNoCommitRollback626(NDBT_Context * ctx,NDBT_Step * step)593 int runNoCommitRollback626(NDBT_Context* ctx, NDBT_Step* step){
594 int result = NDBT_OK;
595 HugoOperations hugoOps(*ctx->getTab());
596 Ndb* pNdb = GETNDB(step);
597
598 do{
599 // No commit transaction, rollback
600 CHECK(hugoOps.startTransaction(pNdb) == 0);
601 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
602 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
603 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
604 CHECK(hugoOps.closeTransaction(pNdb) == 0);
605
606 // No commit transaction, rollback
607 // Multiple operations
608 CHECK(hugoOps.startTransaction(pNdb) == 0);
609 CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
610 CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
611 CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
612 CHECK(hugoOps.pkReadRecord(pNdb, 4, 1, NdbOperation::LM_Exclusive) == 0);
613 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
614 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
615 }while(false);
616
617 hugoOps.closeTransaction(pNdb);
618
619 return result;
620 }
621
runNoCommitRollback630(NDBT_Context * ctx,NDBT_Step * step)622 int runNoCommitRollback630(NDBT_Context* ctx, NDBT_Step* step){
623 int result = NDBT_OK;
624 HugoOperations hugoOps(*ctx->getTab());
625 Ndb* pNdb = GETNDB(step);
626
627 do{
628 // No commit transaction, rollback
629 CHECK(hugoOps.startTransaction(pNdb) == 0);
630 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
631 CHECK(hugoOps.execute_NoCommit(pNdb) == 630);
632 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
633 }while(false);
634
635 hugoOps.closeTransaction(pNdb);
636
637 return result;
638 }
639
640
runNoCommitAndClose(NDBT_Context * ctx,NDBT_Step * step)641 int runNoCommitAndClose(NDBT_Context* ctx, NDBT_Step* step){
642 int i, result = NDBT_OK;
643 HugoOperations hugoOps(*ctx->getTab());
644 Ndb* pNdb = GETNDB(step);
645
646 do{
647 // Read
648 CHECK(hugoOps.startTransaction(pNdb) == 0);
649 for (i = 0; i < 10; i++)
650 CHECK(hugoOps.pkReadRecord(pNdb, i, 1, NdbOperation::LM_Exclusive) == 0);
651 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
652 CHECK(hugoOps.closeTransaction(pNdb) == 0);
653
654 // Update
655 CHECK(hugoOps.startTransaction(pNdb) == 0);
656 for (i = 0; i < 10; i++)
657 CHECK(hugoOps.pkUpdateRecord(pNdb, i) == 0);
658 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
659 CHECK(hugoOps.closeTransaction(pNdb) == 0);
660
661 // Delete
662 CHECK(hugoOps.startTransaction(pNdb) == 0);
663 for (i = 0; i < 10; i++)
664 CHECK(hugoOps.pkDeleteRecord(pNdb, i) == 0);
665 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
666 CHECK(hugoOps.closeTransaction(pNdb) == 0);
667
668 // Try to insert, record should already exist
669 CHECK(hugoOps.startTransaction(pNdb) == 0);
670 for (i = 0; i < 10; i++)
671 CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0);
672 CHECK(hugoOps.execute_Commit(pNdb) == 630);
673 CHECK(hugoOps.closeTransaction(pNdb) == 0);
674
675 }while(false);
676
677 hugoOps.closeTransaction(pNdb);
678
679 return result;
680 }
681
682
683
runCheckRollbackDelete(NDBT_Context * ctx,NDBT_Step * step)684 int runCheckRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){
685 int result = NDBT_OK;
686 HugoOperations hugoOps(*ctx->getTab());
687 Ndb* pNdb = GETNDB(step);
688
689 do{
690
691 // Read value and save it for later
692 CHECK(hugoOps.startTransaction(pNdb) == 0);
693 CHECK(hugoOps.pkReadRecord(pNdb, 5) == 0);
694 CHECK(hugoOps.execute_Commit(pNdb) == 0);
695 CHECK(hugoOps.saveCopyOfRecord() == NDBT_OK);
696 CHECK(hugoOps.closeTransaction(pNdb) == 0);
697
698 // Delete record 5
699 CHECK(hugoOps.startTransaction(pNdb) == 0);
700 CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0);
701 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
702
703 // Check record is deleted
704 CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
705 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
706 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
707
708 CHECK(hugoOps.closeTransaction(pNdb) == 0);
709
710 // Check record is not deleted
711 CHECK(hugoOps.startTransaction(pNdb) == 0);
712 CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
713 CHECK(hugoOps.execute_Commit(pNdb) == 0);
714 CHECK(hugoOps.closeTransaction(pNdb) == 0);
715
716 // Check record is back to original value
717 CHECK(hugoOps.startTransaction(pNdb) == 0);
718 CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
719 CHECK(hugoOps.execute_Commit(pNdb) == 0);
720 CHECK(hugoOps.compareRecordToCopy() == NDBT_OK);
721
722
723 }while(false);
724
725 hugoOps.closeTransaction(pNdb);
726
727 return result;
728 }
729
runCheckRollbackUpdate(NDBT_Context * ctx,NDBT_Step * step)730 int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){
731 int result = NDBT_OK;
732 HugoOperations hugoOps(*ctx->getTab());
733 Ndb* pNdb = GETNDB(step);
734 int numRecords = 5;
735 do{
736
737 // Read value and save it for later
738 CHECK(hugoOps.startTransaction(pNdb) == 0);
739 CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords) == 0);
740 CHECK(hugoOps.execute_Commit(pNdb) == 0);
741 CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Update value 0
742 CHECK(hugoOps.closeTransaction(pNdb) == 0);
743
744 // Update record 5
745 CHECK(hugoOps.startTransaction(pNdb) == 0);
746 CHECK(hugoOps.pkUpdateRecord(pNdb, 1, numRecords, 5) == 0);// Updates value 5
747 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
748
749 // Check record is updated
750 CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords, NdbOperation::LM_Exclusive) == 0);
751 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
752 CHECK(hugoOps.verifyUpdatesValue(5) == NDBT_OK); // Updates value 5
753 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
754
755 CHECK(hugoOps.closeTransaction(pNdb) == 0);
756
757 // Check record is back to original value
758 CHECK(hugoOps.startTransaction(pNdb) == 0);
759 CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords, NdbOperation::LM_Exclusive) == 0);
760 CHECK(hugoOps.execute_Commit(pNdb) == 0);
761 CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Updates value 0
762
763 }while(false);
764
765 hugoOps.closeTransaction(pNdb);
766
767 return result;
768 }
769
runCheckRollbackDeleteMultiple(NDBT_Context * ctx,NDBT_Step * step)770 int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){
771 int result = NDBT_OK;
772 HugoOperations hugoOps(*ctx->getTab());
773 Ndb* pNdb = GETNDB(step);
774
775 do{
776 // Read value and save it for later
777 CHECK(hugoOps.startTransaction(pNdb) == 0);
778 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10) == 0);
779 CHECK(hugoOps.execute_Commit(pNdb) == 0);
780 CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK);
781 CHECK(hugoOps.closeTransaction(pNdb) == 0);
782
783 Uint32 updatesValue = 0;
784 Uint32 j;
785 for(Uint32 i = 0; i<1; i++){
786 // Read record 5 - 10
787 CHECK(hugoOps.startTransaction(pNdb) == 0);
788 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
789 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
790
791 for(j = 0; j<10; j++){
792 // Update record 5 - 10
793 updatesValue++;
794 CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10, updatesValue) == 0);
795 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
796
797 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
798 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
799 CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0);
800 }
801
802 for(j = 0; j<10; j++){
803 // Delete record 5 - 10 times
804 CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
805 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
806
807 #if 0
808 // Check records are deleted
809 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
810 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
811 #endif
812
813 updatesValue++;
814 CHECK(hugoOps.pkInsertRecord(pNdb, 5, 10, updatesValue) == 0);
815 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
816
817 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
818 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
819 CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0);
820 }
821
822 CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
823 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
824
825 // Check records are deleted
826 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
827 CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
828 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
829
830 CHECK(hugoOps.closeTransaction(pNdb) == 0);
831 }
832
833 // Check records are not deleted
834 // after rollback
835 CHECK(hugoOps.startTransaction(pNdb) == 0);
836 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
837 CHECK(hugoOps.execute_Commit(pNdb) == 0);
838 CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK);
839
840 }while(false);
841
842 hugoOps.closeTransaction(pNdb);
843
844 return result;
845 }
846
847
runCheckImplicitRollbackDelete(NDBT_Context * ctx,NDBT_Step * step)848 int runCheckImplicitRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){
849 int result = NDBT_OK;
850 HugoOperations hugoOps(*ctx->getTab());
851 Ndb* pNdb = GETNDB(step);
852
853 do{
854 // Read record 5
855 CHECK(hugoOps.startTransaction(pNdb) == 0);
856 CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
857 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
858 CHECK(hugoOps.closeTransaction(pNdb) == 0);
859
860 // Update record 5
861 CHECK(hugoOps.startTransaction(pNdb) == 0);
862 CHECK(hugoOps.pkUpdateRecord(pNdb, 5) == 0);
863 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
864 CHECK(hugoOps.closeTransaction(pNdb) == 0);
865
866 // Delete record 5
867 CHECK(hugoOps.startTransaction(pNdb) == 0);
868 CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0);
869 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
870 CHECK(hugoOps.closeTransaction(pNdb) == 0);
871
872 // Check record is not deleted
873 // Close transaction should have rollbacked
874 CHECK(hugoOps.startTransaction(pNdb) == 0);
875 CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
876 CHECK(hugoOps.execute_Commit(pNdb) == 0);
877 }while(false);
878
879 hugoOps.closeTransaction(pNdb);
880
881 return result;
882 }
883
runCheckCommitDelete(NDBT_Context * ctx,NDBT_Step * step)884 int runCheckCommitDelete(NDBT_Context* ctx, NDBT_Step* step){
885 int result = NDBT_OK;
886 HugoOperations hugoOps(*ctx->getTab());
887 Ndb* pNdb = GETNDB(step);
888
889 do{
890 // Read 10 records
891 CHECK(hugoOps.startTransaction(pNdb) == 0);
892 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
893 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
894
895 // Update 10 records
896 CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10) == 0);
897 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
898
899 // Delete 10 records
900 CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
901 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
902
903 CHECK(hugoOps.execute_Commit(pNdb) == 0);
904 CHECK(hugoOps.closeTransaction(pNdb) == 0);
905
906 // Check record's are deleted
907 CHECK(hugoOps.startTransaction(pNdb) == 0);
908 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
909 CHECK(hugoOps.execute_Commit(pNdb) == 626);
910
911 }while(false);
912
913 hugoOps.closeTransaction(pNdb);
914
915 return result;
916 }
917
runRollbackNothing(NDBT_Context * ctx,NDBT_Step * step)918 int runRollbackNothing(NDBT_Context* ctx, NDBT_Step* step){
919 int result = NDBT_OK;
920 HugoOperations hugoOps(*ctx->getTab());
921 Ndb* pNdb = GETNDB(step);
922
923 do{
924 // Delete record 5 - 15
925 CHECK(hugoOps.startTransaction(pNdb) == 0);
926 CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
927 // Rollback
928 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
929 CHECK(hugoOps.closeTransaction(pNdb) == 0);
930
931 // Check records are not deleted
932 CHECK(hugoOps.startTransaction(pNdb) == 0);
933 CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
934 CHECK(hugoOps.execute_Commit(pNdb) == 0);
935 CHECK(hugoOps.closeTransaction(pNdb) == 0);
936
937 CHECK(hugoOps.startTransaction(pNdb) == 0);
938 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
939
940 }while(false);
941
942 hugoOps.closeTransaction(pNdb);
943
944 return result;
945 }
946
runMassiveRollback(NDBT_Context * ctx,NDBT_Step * step)947 int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){
948
949 NdbRestarter restarter;
950 const int records = 4 * restarter.getNumDbNodes();
951
952 HugoTransactions hugoTrans(*ctx->getTab());
953 if (hugoTrans.loadTable(GETNDB(step), records) != 0){
954 return NDBT_FAILED;
955 }
956
957 int result = NDBT_OK;
958 HugoOperations hugoOps(*ctx->getTab());
959 Ndb* pNdb = GETNDB(step);
960
961 const Uint32 OPS_PER_TRANS = 256;
962 const Uint32 OPS_TOTAL = 4096;
963
964 for(int row = 0; row < records; row++){
965 int res;
966 CHECK(hugoOps.startTransaction(pNdb) == 0);
967 for(Uint32 i = 0; i<OPS_TOTAL; i += OPS_PER_TRANS){
968 for(Uint32 j = 0; j<OPS_PER_TRANS; j++){
969 CHECK(hugoOps.pkUpdateRecord(pNdb, row, 1, i) == 0);
970 }
971 g_info << "Performed " << (i+OPS_PER_TRANS) << " updates on row: " << row
972 << endl;
973 if(result != NDBT_OK){
974 break;
975 }
976 res = hugoOps.execute_NoCommit(pNdb);
977 if(res != 0){
978 NdbError err = pNdb->getNdbError(res);
979 CHECK(err.classification == NdbError::TimeoutExpired);
980 break;
981 }
982 }
983 if(result != NDBT_OK){
984 break;
985 }
986 g_info << "executeRollback" << endl;
987 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
988 CHECK(hugoOps.closeTransaction(pNdb) == 0);
989 }
990
991 hugoOps.closeTransaction(pNdb);
992 return result;
993 }
994
995 int
runMassiveRollback2(NDBT_Context * ctx,NDBT_Step * step)996 runMassiveRollback2(NDBT_Context* ctx, NDBT_Step* step){
997
998 HugoTransactions hugoTrans(*ctx->getTab());
999 if (hugoTrans.loadTable(GETNDB(step), 1) != 0){
1000 return NDBT_FAILED;
1001 }
1002
1003 int result = NDBT_OK;
1004 HugoOperations hugoOps(*ctx->getTab());
1005 Ndb* pNdb = GETNDB(step);
1006
1007 const Uint32 OPS_TOTAL = 4096;
1008 const Uint32 LOOPS = 10;
1009
1010 for(Uint32 loop = 0; loop<LOOPS; loop++){
1011 CHECK(hugoOps.startTransaction(pNdb) == 0);
1012 for(Uint32 i = 0; i<OPS_TOTAL-1; i ++){
1013 if((i & 1) == 0){
1014 CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, loop) == 0);
1015 } else {
1016 CHECK(hugoOps.pkUpdateRecord(pNdb, 1, 1, loop) == 0);
1017 }
1018 }
1019 CHECK(hugoOps.execute_Commit(pNdb) == 626);
1020 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
1021 CHECK(hugoOps.closeTransaction(pNdb) == 0);
1022 }
1023
1024 hugoOps.closeTransaction(pNdb);
1025 return result;
1026 }
1027
1028 int
runMassiveRollback3(NDBT_Context * ctx,NDBT_Step * step)1029 runMassiveRollback3(NDBT_Context* ctx, NDBT_Step* step){
1030
1031 int result = NDBT_OK;
1032 HugoOperations hugoOps(*ctx->getTab());
1033 Ndb* pNdb = GETNDB(step);
1034
1035 const Uint32 BATCH = 10;
1036 const Uint32 OPS_TOTAL = 50;
1037 const Uint32 LOOPS = 100;
1038
1039 for(Uint32 loop = 0; loop<LOOPS; loop++)
1040 {
1041 CHECK(hugoOps.startTransaction(pNdb) == 0);
1042 bool ok = true;
1043 for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
1044 {
1045 CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
1046 if (hugoOps.execute_NoCommit(pNdb) != 0)
1047 {
1048 ok = false;
1049 break;
1050 }
1051 }
1052 hugoOps.execute_Rollback(pNdb);
1053 CHECK(hugoOps.closeTransaction(pNdb) == 0);
1054 }
1055
1056 hugoOps.closeTransaction(pNdb);
1057 return result;
1058 }
1059
1060 int
runMassiveRollback4(NDBT_Context * ctx,NDBT_Step * step)1061 runMassiveRollback4(NDBT_Context* ctx, NDBT_Step* step){
1062
1063 int result = NDBT_OK;
1064 HugoOperations hugoOps(*ctx->getTab());
1065 Ndb* pNdb = GETNDB(step);
1066
1067 const Uint32 BATCH = 10;
1068 const Uint32 OPS_TOTAL = 20;
1069 const Uint32 LOOPS = 100;
1070
1071 for(Uint32 loop = 0; loop<LOOPS; loop++)
1072 {
1073 CHECK(hugoOps.startTransaction(pNdb) == 0);
1074 bool ok = true;
1075 for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
1076 {
1077 CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
1078 CHECK(hugoOps.pkDeleteRecord(pNdb, i, BATCH) == 0);
1079 if (hugoOps.execute_NoCommit(pNdb) != 0)
1080 {
1081 ok = false;
1082 break;
1083 }
1084 }
1085 hugoOps.execute_Rollback(pNdb);
1086 CHECK(hugoOps.closeTransaction(pNdb) == 0);
1087 }
1088
1089 hugoOps.closeTransaction(pNdb);
1090 return result;
1091 }
1092
1093 /**
1094 * TUP errors
1095 */
1096 struct TupError
1097 {
1098 enum Bits {
1099 TE_VARSIZE = 0x1,
1100 TE_MULTI_OP = 0x2,
1101 TE_DISK = 0x4,
1102 TE_REPLICA = 0x8,
1103 TE_OI = 0x10, // Ordered index
1104 TE_UI = 0x20 // Unique hash index
1105 };
1106 int op;
1107 int error;
1108 int bits;
1109 };
1110
1111 static
1112 TupError
1113 f_tup_errors[] =
1114 {
1115 { NdbOperation::InsertRequest, 4014, 0 }, // Out of undo buffer
1116 { NdbOperation::InsertRequest, 4015, TupError::TE_DISK }, // Out of log space
1117 { NdbOperation::InsertRequest, 4016, 0 }, // AI Inconsistency
1118 { NdbOperation::InsertRequest, 4017, 0 }, // Out of memory
1119 { NdbOperation::InsertRequest, 4018, 0 }, // Null check error
1120 { NdbOperation::InsertRequest, 4019, TupError::TE_REPLICA }, //Alloc rowid error
1121 { NdbOperation::InsertRequest, 4020, TupError::TE_MULTI_OP }, // Size change error
1122 { NdbOperation::InsertRequest, 4021, TupError::TE_DISK }, // Out of disk space
1123 { NdbOperation::InsertRequest, 4022, TupError::TE_OI },
1124 { NdbOperation::InsertRequest, 4023, TupError::TE_OI },
1125 { NdbOperation::UpdateRequest, 4030, TupError::TE_UI },
1126 { -1, 0, 0 }
1127 };
1128
1129 int
runTupErrors(NDBT_Context * ctx,NDBT_Step * step)1130 runTupErrors(NDBT_Context* ctx, NDBT_Step* step){
1131
1132 NdbRestarter restarter;
1133 HugoTransactions hugoTrans(*ctx->getTab());
1134 HugoOperations hugoOps(*ctx->getTab());
1135 Ndb* pNdb = GETNDB(step);
1136
1137 const NdbDictionary::Table * tab = ctx->getTab();
1138 int i;
1139 int bits = TupError::TE_MULTI_OP;
1140 for(i = 0; i<tab->getNoOfColumns(); i++)
1141 {
1142 if (tab->getColumn(i)->getArrayType() != NdbDictionary::Column::ArrayTypeFixed)
1143 bits |= TupError::TE_VARSIZE;
1144 if (tab->getColumn(i)->getStorageType()!= NdbDictionary::Column::StorageTypeMemory)
1145 bits |= TupError::TE_DISK;
1146 }
1147
1148 if (restarter.getNumDbNodes() >= 2)
1149 {
1150 bits |= TupError::TE_REPLICA;
1151 }
1152
1153 NdbDictionary::Dictionary::List l;
1154 pNdb->getDictionary()->listIndexes(l, tab->getName());
1155 for (i = 0; i<(int)l.count; i++)
1156 {
1157 if (DictTabInfo::isOrderedIndex(l.elements[i].type))
1158 bits |= TupError::TE_OI;
1159 if (DictTabInfo::isUniqueIndex(l.elements[i].type))
1160 bits |= TupError::TE_UI;
1161 }
1162
1163 /**
1164 * Insert
1165 */
1166 for(i = 0; f_tup_errors[i].op != -1; i++)
1167 {
1168 if (f_tup_errors[i].op != NdbOperation::InsertRequest)
1169 {
1170 continue;
1171 }
1172
1173 if ((f_tup_errors[i].bits & bits) != f_tup_errors[i].bits)
1174 {
1175 g_err << "Skipping " << f_tup_errors[i].error
1176 << " - req bits: " << hex << f_tup_errors[i].bits
1177 << " bits: " << hex << bits << endl;
1178 continue;
1179 }
1180
1181 g_err << "Testing error insert: " << f_tup_errors[i].error << endl;
1182 restarter.insertErrorInAllNodes(f_tup_errors[i].error);
1183 if (f_tup_errors[i].bits & TupError::TE_MULTI_OP)
1184 {
1185
1186 }
1187 else
1188 {
1189 hugoTrans.loadTable(pNdb, 5);
1190 }
1191 restarter.insertErrorInAllNodes(0);
1192 if (hugoTrans.clearTable(pNdb, 5) != 0)
1193 {
1194 return NDBT_FAILED;
1195 }
1196 }
1197
1198 /**
1199 * update
1200 */
1201 hugoTrans.loadTable(pNdb, 5);
1202 for(i = 0; f_tup_errors[i].op != -1; i++)
1203 {
1204 if (f_tup_errors[i].op != NdbOperation::UpdateRequest)
1205 {
1206 continue;
1207 }
1208
1209 if ((f_tup_errors[i].bits & bits) != f_tup_errors[i].bits)
1210 {
1211 g_err << "Skipping " << f_tup_errors[i].error
1212 << " - req bits: " << hex << f_tup_errors[i].bits
1213 << " bits: " << hex << bits << endl;
1214 continue;
1215 }
1216
1217 g_err << "Testing error insert: " << f_tup_errors[i].error << endl;
1218 restarter.insertErrorInAllNodes(f_tup_errors[i].error);
1219 if (f_tup_errors[i].bits & TupError::TE_MULTI_OP)
1220 {
1221
1222 }
1223 else
1224 {
1225 hugoTrans.scanUpdateRecords(pNdb, 5);
1226 }
1227 restarter.insertErrorInAllNodes(0);
1228 if (hugoTrans.scanUpdateRecords(pNdb, 5) != 0)
1229 {
1230 return NDBT_FAILED;
1231 }
1232 }
1233
1234 return NDBT_OK;
1235 }
1236
1237 int
runInsertError(NDBT_Context * ctx,NDBT_Step * step)1238 runInsertError(NDBT_Context* ctx, NDBT_Step* step){
1239
1240 int result = NDBT_OK;
1241 HugoOperations hugoOp1(*ctx->getTab());
1242 HugoOperations hugoOp2(*ctx->getTab());
1243 Ndb* pNdb = GETNDB(step);
1244
1245 NdbRestarter restarter;
1246 restarter.insertErrorInAllNodes(4017);
1247 const Uint32 LOOPS = 10;
1248 for (Uint32 i = 0; i<LOOPS; i++)
1249 {
1250 CHECK(hugoOp1.startTransaction(pNdb) == 0);
1251 CHECK(hugoOp1.pkInsertRecord(pNdb, 1) == 0);
1252
1253 CHECK(hugoOp2.startTransaction(pNdb) == 0);
1254 CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1) == 0);
1255
1256 CHECK(hugoOp1.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1257 CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1258 hugoOp1.wait_async(pNdb);
1259 hugoOp2.wait_async(pNdb);
1260 CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1261 CHECK(hugoOp2.closeTransaction(pNdb) == 0);
1262 }
1263
1264 restarter.insertErrorInAllNodes(0);
1265
1266 return result;
1267 }
1268
1269 int
runInsertError2(NDBT_Context * ctx,NDBT_Step * step)1270 runInsertError2(NDBT_Context* ctx, NDBT_Step* step){
1271 int result = NDBT_OK;
1272 HugoOperations hugoOp1(*ctx->getTab());
1273 Ndb* pNdb = GETNDB(step);
1274
1275 NdbRestarter restarter;
1276 restarter.insertErrorInAllNodes(4017);
1277
1278 const Uint32 LOOPS = 1;
1279 for (Uint32 i = 0; i<LOOPS; i++)
1280 {
1281 CHECK(hugoOp1.startTransaction(pNdb) == 0);
1282 CHECK(hugoOp1.pkInsertRecord(pNdb, 1) == 0);
1283 CHECK(hugoOp1.pkDeleteRecord(pNdb, 1) == 0);
1284
1285 hugoOp1.execute_NoCommit(pNdb);
1286 CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1287 }
1288
1289 restarter.insertErrorInAllNodes(0);
1290 return NDBT_OK;
1291 }
1292
1293 int
runBug25090(NDBT_Context * ctx,NDBT_Step * step)1294 runBug25090(NDBT_Context* ctx, NDBT_Step* step){
1295
1296 Ndb* pNdb = GETNDB(step);
1297 //NdbDictionary::Dictionary * dict = pNdb->getDictionary();
1298
1299 HugoOperations ops(*ctx->getTab());
1300
1301 int loops = ctx->getNumLoops();
1302 //const int rows = ctx->getNumRecords();
1303
1304 while (loops--)
1305 {
1306 ops.startTransaction(pNdb);
1307 ops.pkReadRecord(pNdb, 1, 1);
1308 ops.execute_Commit(pNdb, AO_IgnoreError);
1309 sleep(10);
1310 ops.closeTransaction(pNdb);
1311 }
1312
1313 return NDBT_OK;
1314 }
1315
1316 int
runDeleteRead(NDBT_Context * ctx,NDBT_Step * step)1317 runDeleteRead(NDBT_Context* ctx, NDBT_Step* step){
1318
1319 Ndb* pNdb = GETNDB(step);
1320
1321 const NdbDictionary::Table* tab = ctx->getTab();
1322 NDBT_ResultRow row(*ctx->getTab());
1323 HugoTransactions tmp(*ctx->getTab());
1324
1325 int a;
1326 int loops = ctx->getNumLoops();
1327 //const int rows = ctx->getNumRecords();
1328
1329 while (loops--)
1330 {
1331 NdbTransaction* pTrans = pNdb->startTransaction();
1332 NdbOperation* pOp = pTrans->getNdbOperation(tab->getName());
1333 pOp->deleteTuple();
1334 tmp.equalForRow(pOp, loops);
1335
1336 // Define attributes to read
1337 for(a = 0; a<tab->getNoOfColumns(); a++)
1338 {
1339 if((row.attributeStore(a) = pOp->getValue(tab->getColumn(a)->getName())) == 0) {
1340 ERR(pTrans->getNdbError());
1341 return NDBT_FAILED;
1342 }
1343 }
1344
1345 pTrans->execute(Commit);
1346 pTrans->close();
1347
1348 pTrans = pNdb->startTransaction();
1349 pOp = pTrans->getNdbOperation(tab->getName());
1350 pOp->insertTuple();
1351 tmp.setValues(pOp, loops, 0);
1352
1353 pOp = pTrans->getNdbOperation(tab->getName());
1354 pOp->deleteTuple();
1355 tmp.equalForRow(pOp, loops);
1356 for(a = 0; a<tab->getNoOfColumns(); a++)
1357 {
1358 if((row.attributeStore(a) = pOp->getValue(tab->getColumn(a)->getName())) == 0)
1359 {
1360 ERR(pTrans->getNdbError());
1361 return NDBT_FAILED;
1362 }
1363 }
1364 if (pTrans->execute(Commit) != 0)
1365 {
1366 ERR(pTrans->getNdbError());
1367 return NDBT_FAILED;
1368 }
1369
1370 pTrans->close();
1371 }
1372
1373 return NDBT_OK;
1374 }
1375
1376 int
runBug27756(NDBT_Context * ctx,NDBT_Step * step)1377 runBug27756(NDBT_Context* ctx, NDBT_Step* step)
1378 {
1379
1380 Ndb* pNdb = GETNDB(step);
1381 //NdbDictionary::Dictionary * dict = pNdb->getDictionary();
1382
1383 HugoOperations ops(*ctx->getTab());
1384
1385 int loops = ctx->getNumLoops();
1386 //const int rows = ctx->getNumRecords();
1387
1388 Vector<Uint64> copies;
1389 while (loops--)
1390 {
1391 ops.startTransaction(pNdb);
1392 ops.pkInsertRecord(pNdb, 1, 1);
1393 ops.execute_NoCommit(pNdb);
1394
1395 NdbTransaction* pTrans = ops.getTransaction();
1396 NdbOperation* op = pTrans->getNdbOperation(ctx->getTab()->getName());
1397 op->interpretedUpdateTuple();
1398 ops.equalForRow(op, 1);
1399 NdbRecAttr* attr = op->getValue(NdbDictionary::Column::COPY_ROWID);
1400 ops.execute_NoCommit(pNdb);
1401
1402 copies.push_back(attr->u_64_value());
1403 ndbout_c("copy at: %llx", copies.back());
1404 ops.execute_NoCommit(pNdb);
1405
1406 ops.pkDeleteRecord(pNdb, 1, 1);
1407 ops.execute_NoCommit(pNdb);
1408
1409 if (loops & 1)
1410 {
1411 ops.execute_Rollback(pNdb);
1412 ops.closeTransaction(pNdb);
1413 }
1414 else
1415 {
1416 ops.execute_Commit(pNdb);
1417 ops.closeTransaction(pNdb);
1418 ops.clearTable(pNdb, 100);
1419 }
1420 }
1421
1422 for (Uint32 i = 0; i<copies.size(); i++)
1423 if (copies[i] != copies.back())
1424 {
1425 ndbout_c("Memleak detected");
1426 return NDBT_FAILED;
1427 }
1428
1429 return NDBT_OK;
1430 }
1431
1432 int
runBug28073(NDBT_Context * ctx,NDBT_Step * step)1433 runBug28073(NDBT_Context *ctx, NDBT_Step* step)
1434 {
1435 int result = NDBT_OK;
1436 const NdbDictionary::Table *table= ctx->getTab();
1437 HugoOperations hugoOp1(*table);
1438 HugoOperations hugoOp2(*table);
1439 Ndb* pNdb = GETNDB(step);
1440 int loops = ctx->getNumLoops();
1441 bool inserted= false;
1442
1443 while (loops--)
1444 {
1445 if (!inserted)
1446 {
1447 CHECK(hugoOp1.startTransaction(pNdb) == 0);
1448 CHECK(hugoOp1.pkInsertRecord(pNdb, 1, 1) == 0);
1449 CHECK(hugoOp1.execute_Commit(pNdb) == 0);
1450 CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1451 inserted= 1;
1452 }
1453
1454 // Use TC hint to hit the same node in both transactions.
1455 Uint32 key_val= 0;
1456 const char *key= (const char *)(&key_val);
1457 CHECK(hugoOp1.startTransaction(pNdb, table, key, 4) == 0);
1458 CHECK(hugoOp2.startTransaction(pNdb, table, key, 4) == 0);
1459
1460 // First take 2*read lock on the tuple in transaction 1.
1461 for (Uint32 i= 0; i < 2; i++)
1462 {
1463 CHECK(hugoOp1.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1464 CHECK(hugoOp1.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1465 }
1466 CHECK(hugoOp1.execute_NoCommit(pNdb) == 0);
1467
1468 // Now send ops in two transactions, one batch.
1469 // First 2*read in transaction 2.
1470 for (Uint32 i= 0; i < 2; i++)
1471 {
1472 CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1473 CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1474 }
1475 CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::NoCommit) == 0);
1476
1477 // Second op an update in transaction 1.
1478 CHECK(hugoOp1.pkUpdateRecord(pNdb, 1, 1) == 0);
1479 CHECK(hugoOp1.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1480
1481 // Transaction 1 will now hang waiting on transaction 2 to commit before it
1482 // can upgrade its read lock to a write lock.
1483 // With the bug, we get a node failure due to watchdog timeout here.
1484 CHECK(hugoOp2.wait_async(pNdb) == 0);
1485
1486 // Now commit transaction 2, we should see transaction 1 finish with the
1487 // update.
1488 CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1489 CHECK(hugoOp2.wait_async(pNdb) == 0);
1490 // No error check, as transaction 1 may have terminated already.
1491 hugoOp1.wait_async(pNdb);
1492
1493 CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1494 CHECK(hugoOp2.closeTransaction(pNdb) == 0);
1495 }
1496
1497 return result;
1498 }
1499
1500 int
runBug20535(NDBT_Context * ctx,NDBT_Step * step)1501 runBug20535(NDBT_Context* ctx, NDBT_Step* step)
1502 {
1503 Ndb* pNdb = GETNDB(step);
1504 const NdbDictionary::Table * tab = ctx->getTab();
1505
1506 bool hasDefault = false;
1507 for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
1508 {
1509 if (tab->getColumn(i)->getNullable() ||
1510 tab->getColumn(i)->getDefaultValue())
1511 {
1512 hasDefault = true;
1513 break;
1514 }
1515 }
1516
1517 if (!hasDefault)
1518 return NDBT_OK;
1519
1520 HugoTransactions hugoTrans(* tab);
1521 hugoTrans.loadTable(pNdb, 1);
1522
1523 NdbTransaction* pTrans = pNdb->startTransaction();
1524 NdbOperation* pOp = pTrans->getNdbOperation(tab->getName());
1525 pOp->deleteTuple();
1526 hugoTrans.equalForRow(pOp, 0);
1527 if (pTrans->execute(NoCommit) != 0)
1528 return NDBT_FAILED;
1529
1530 pOp = pTrans->getNdbOperation(tab->getName());
1531 pOp->insertTuple();
1532 hugoTrans.equalForRow(pOp, 0);
1533 for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
1534 {
1535 if (!tab->getColumn(i)->getPrimaryKey() &&
1536 !tab->getColumn(i)->getNullable() &&
1537 !tab->getColumn(i)->getDefaultValue())
1538 {
1539 hugoTrans.setValueForAttr(pOp, i, 0, 1);
1540 }
1541 }
1542
1543 if (pTrans->execute(Commit) != 0)
1544 return NDBT_FAILED;
1545
1546 pTrans->close();
1547
1548 pTrans = pNdb->startTransaction();
1549 pOp = pTrans->getNdbOperation(tab->getName());
1550 pOp->readTuple();
1551 hugoTrans.equalForRow(pOp, 0);
1552 Vector<NdbRecAttr*> values;
1553 for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
1554 {
1555 if (!tab->getColumn(i)->getPrimaryKey() &&
1556 (tab->getColumn(i)->getNullable() ||
1557 tab->getColumn(i)->getDefaultValue()))
1558 {
1559 values.push_back(pOp->getValue(i));
1560 }
1561 }
1562
1563 if (pTrans->execute(Commit) != 0)
1564 return NDBT_FAILED;
1565
1566 bool defaultOk = true;
1567 for (unsigned int i = 0; i<values.size(); i++)
1568 {
1569 const NdbRecAttr* recAttr = values[i];
1570 const NdbDictionary::Column* col = recAttr->getColumn();
1571 unsigned int defaultLen = 0;
1572 const char* def = (const char*) col->getDefaultValue(&defaultLen);
1573
1574 if (def)
1575 {
1576 /* Column has a native default, check that it was set */
1577
1578 if (!recAttr->isNULL())
1579 {
1580 if (memcmp(def, recAttr->aRef(), defaultLen) != 0)
1581 {
1582 defaultOk = false;
1583 ndbout_c("column %s does not have correct default value",
1584 recAttr->getColumn()->getName());
1585 }
1586 }
1587 else
1588 {
1589 defaultOk = false;
1590 ndbout_c("column %s is null, should have default value",
1591 recAttr->getColumn()->getName());
1592 }
1593 }
1594 else
1595 {
1596 /* Column has Null as its default */
1597 if (!recAttr->isNULL())
1598 {
1599 defaultOk = false;
1600 ndbout_c("column %s is not NULL", recAttr->getColumn()->getName());
1601 }
1602 }
1603 }
1604
1605 pTrans->close();
1606
1607 if (defaultOk)
1608 return NDBT_OK;
1609 else
1610 return NDBT_FAILED;
1611 }
1612
1613
1614 int
runDDInsertFailUpdateBatch(NDBT_Context * ctx,NDBT_Step * step)1615 runDDInsertFailUpdateBatch(NDBT_Context* ctx, NDBT_Step* step)
1616 {
1617 Ndb* pNdb = GETNDB(step);
1618 NdbRestarter restarter;
1619
1620 const NdbDictionary::Table * tab = ctx->getTab();
1621
1622 int errCode = 0;
1623 int expectedError = 0;
1624 {
1625 bool tabHasDD = false;
1626 for(int i = 0; i<tab->getNoOfColumns(); i++)
1627 {
1628 tabHasDD |= (tab->getColumn(i)->getStorageType() ==
1629 NdbDictionary::Column::StorageTypeDisk);
1630 }
1631
1632 if (tabHasDD)
1633 {
1634 errCode = 4021;
1635 expectedError = 1601;
1636 }
1637 else
1638 {
1639 NdbDictionary::Dictionary::List l;
1640 pNdb->getDictionary()->listIndexes(l, tab->getName());
1641 for (Uint32 i = 0; i<l.count; i++)
1642 {
1643 if (DictTabInfo::isOrderedIndex(l.elements[i].type))
1644 {
1645 errCode = 4023;
1646 expectedError = 9999;
1647 break;
1648 }
1649 }
1650 }
1651
1652 if (errCode == 0)
1653 {
1654 ndbout_c("Table %s has no disk attributes or ordered indexes, skipping",
1655 tab->getName());
1656 return NDBT_OK;
1657 }
1658 }
1659
1660 HugoOperations hugoOps(*ctx->getTab());
1661
1662 int result = NDBT_OK;
1663
1664 for (Uint32 loop = 0; loop < 100; loop ++)
1665 {
1666 restarter.insertErrorInAllNodes(errCode);
1667 CHECK(hugoOps.startTransaction(pNdb) == 0);
1668
1669 /* Create batch with insert op (which will fail due to disk allocation issue)
1670 * followed by update op on same pk
1671 * Transaction will abort due to insert failure, and reason should be
1672 * disk space exhaustion, not any issue with the update.
1673 */
1674 CHECK(hugoOps.pkInsertRecord(pNdb, loop, 1, 0) == 0);
1675
1676 /* Add up to 16 updates after the insert */
1677 Uint32 numUpdates = 1 + (loop % 15);
1678 for (Uint32 updateCnt = 0; updateCnt < numUpdates; updateCnt++)
1679 CHECK(hugoOps.pkUpdateRecord(pNdb, loop, 1, 1+updateCnt) == 0);
1680
1681 CHECK(hugoOps.execute_Commit(pNdb) != 0); /* Expect failure */
1682
1683 NdbError err= hugoOps.getTransaction()->getNdbError();
1684
1685 CHECK(err.code == expectedError);
1686
1687 hugoOps.closeTransaction(pNdb);
1688 }
1689
1690 restarter.insertErrorInAllNodes(0);
1691
1692 return result;
1693 }
1694
1695 // Bug34348
1696
1697 #define chk1(b) \
1698 if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << endl; result = NDBT_FAILED; continue; }
1699 #define chk2(b, e) \
1700 if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e << endl; result = NDBT_FAILED; continue; }
1701
1702 const char* tabname_bug34348 = "TBug34348";
1703
1704 int
runBug34348insert(NDBT_Context * ctx,NDBT_Step * step,HugoOperations & ops,int i,bool * rangeFull)1705 runBug34348insert(NDBT_Context* ctx, NDBT_Step* step,
1706 HugoOperations& ops, int i, bool* rangeFull)
1707 {
1708 const int rangeFullError = 633;
1709 Ndb* pNdb = GETNDB(step);
1710 int result = NDBT_OK;
1711 while (result == NDBT_OK)
1712 {
1713 int code = 0;
1714 chk2(ops.startTransaction(pNdb) == 0, ops.getNdbError());
1715 chk2(ops.pkInsertRecord(pNdb, i, 1) == 0, ops.getNdbError());
1716 chk2(ops.execute_Commit(pNdb) == 0 || (code = ops.getNdbError().code) == rangeFullError, ops.getNdbError());
1717 ops.closeTransaction(pNdb);
1718 *rangeFull = (code == rangeFullError);
1719 break;
1720 }
1721 return result;
1722 }
1723
1724 int
runBug34348delete(NDBT_Context * ctx,NDBT_Step * step,HugoOperations & ops,int i)1725 runBug34348delete(NDBT_Context* ctx, NDBT_Step* step,
1726 HugoOperations& ops, int i)
1727 {
1728 Ndb* pNdb = GETNDB(step);
1729 int result = NDBT_OK;
1730 while (result == NDBT_OK)
1731 {
1732 chk2(ops.startTransaction(pNdb) == 0, ops.getNdbError());
1733 chk2(ops.pkDeleteRecord(pNdb, i, 1) == 0, ops.getNdbError());
1734 chk2(ops.execute_Commit(pNdb) == 0, ops.getNdbError());
1735 ops.closeTransaction(pNdb);
1736 break;
1737 }
1738 return result;
1739 }
1740
1741 int
runBug34348(NDBT_Context * ctx,NDBT_Step * step)1742 runBug34348(NDBT_Context* ctx, NDBT_Step* step)
1743 {
1744 myRandom48Init((long)NdbTick_CurrentMillisecond());
1745 Ndb* pNdb = GETNDB(step);
1746 NdbDictionary::Dictionary* pDict = pNdb->getDictionary();
1747 NdbRestarter restarter;
1748 int result = NDBT_OK;
1749 const int loops = ctx->getNumLoops();
1750 const int errInsDBACC = 3002;
1751 const int errInsCLEAR = 0;
1752 Uint32* rowmask = 0;
1753
1754 while (result == NDBT_OK)
1755 {
1756 chk1(restarter.insertErrorInAllNodes(errInsDBACC) == 0);
1757 ndbout << "error insert " << errInsDBACC << " done" << endl;
1758
1759 const NdbDictionary::Table* pTab = 0;
1760 while (result == NDBT_OK)
1761 {
1762 (void)pDict->dropTable(tabname_bug34348);
1763 NdbDictionary::Table tab(tabname_bug34348);
1764 {
1765 NdbDictionary::Column col("a");
1766 col.setType(NdbDictionary::Column::Unsigned);
1767 col.setPrimaryKey(true);
1768 tab.addColumn(col);
1769 }
1770 {
1771 NdbDictionary::Column col("b");
1772 col.setType(NdbDictionary::Column::Unsigned);
1773 col.setNullable(false);
1774 tab.addColumn(col);
1775 }
1776 chk2(pDict->createTable(tab) == 0, pDict->getNdbError());
1777 chk2((pTab = pDict->getTable(tabname_bug34348)) != 0, pDict->getNdbError());
1778 break;
1779 }
1780
1781 HugoOperations ops(*pTab);
1782 ops.setQuiet();
1783
1784 int rowmaxprev = 0;
1785 int loop = 0;
1786 while (result == NDBT_OK && loop < loops)
1787 {
1788 ndbout << "loop:" << loop << endl;
1789 int rowcnt = 0;
1790
1791 // fill up
1792 while (result == NDBT_OK)
1793 {
1794 bool rangeFull;
1795 chk1(runBug34348insert(ctx, step, ops, rowcnt, &rangeFull) == NDBT_OK);
1796 if (rangeFull)
1797 {
1798 // 360449 (1 fragment)
1799 ndbout << "dir range full at " << rowcnt << endl;
1800 break;
1801 }
1802 rowcnt++;
1803 }
1804 chk1(result == NDBT_OK);
1805 const int rowmax = rowcnt;
1806
1807 if (loop == 0)
1808 rowmaxprev = rowmax;
1809 else
1810 chk2(rowmaxprev == rowmax, "rowmaxprev:" << rowmaxprev << " rowmax:" << rowmax);
1811
1812 const int sz = (rowmax + 31) / 32;
1813 delete [] rowmask;
1814 rowmask = new Uint32 [sz];
1815 BitmaskImpl::clear(sz, rowmask);
1816 {
1817 int i;
1818 for (i = 0; i < rowmax; i++)
1819 BitmaskImpl::set(sz, rowmask, i);
1820 }
1821
1822 // random delete until insert succeeds
1823 while (result == NDBT_OK)
1824 {
1825 int i = myRandom48(rowmax);
1826 if (!BitmaskImpl::get(sz, rowmask, i))
1827 continue;
1828 chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK);
1829 BitmaskImpl::clear(sz, rowmask, i);
1830 rowcnt--;
1831 bool rangeFull;
1832 chk1(runBug34348insert(ctx, step, ops, rowmax, &rangeFull) == NDBT_OK);
1833 if (!rangeFull)
1834 {
1835 chk1(runBug34348delete(ctx, step, ops, rowmax) == NDBT_OK);
1836 // 344063 (1 fragment)
1837 ndbout << "dir range released at " << rowcnt << endl;
1838 break;
1839 }
1840 }
1841 chk1(result == NDBT_OK);
1842 assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1843
1844 // delete about 1/2 remaining
1845 while (result == NDBT_OK)
1846 {
1847 int i;
1848 for (i = 0; result == NDBT_OK && i < rowmax; i++)
1849 {
1850 if (!BitmaskImpl::get(sz, rowmask, i))
1851 continue;
1852 if (myRandom48(100) < 50)
1853 continue;
1854 chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK);
1855 BitmaskImpl::clear(sz, rowmask, i);
1856 rowcnt--;
1857 }
1858 ndbout << "deleted down to " << rowcnt << endl;
1859 break;
1860 }
1861 chk1(result == NDBT_OK);
1862 assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1863
1864 // insert until full again
1865 while (result == NDBT_OK)
1866 {
1867 int i;
1868 for (i = 0; result == NDBT_OK && i < rowmax; i++)
1869 {
1870 if (BitmaskImpl::get(sz, rowmask, i))
1871 continue;
1872 bool rangeFull;
1873 chk1(runBug34348insert(ctx, step, ops, i, &rangeFull) == NDBT_OK);
1874 // assume all can be inserted back
1875 chk2(!rangeFull, "dir range full too early at " << rowcnt);
1876 BitmaskImpl::set(sz, rowmask, i);
1877 rowcnt++;
1878 }
1879 chk1(result == NDBT_OK);
1880 ndbout << "inserted all back to " << rowcnt << endl;
1881 break;
1882 }
1883 chk1(result == NDBT_OK);
1884 assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1885
1886 // delete all
1887 while (result == NDBT_OK)
1888 {
1889 int i;
1890 for (i = 0; result == NDBT_OK && i < rowmax; i++)
1891 {
1892 if (!BitmaskImpl::get(sz, rowmask, i))
1893 continue;
1894 chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK);
1895 BitmaskImpl::clear(sz, rowmask, i);
1896 rowcnt--;
1897 }
1898 ndbout << "deleted all" << endl;
1899 break;
1900 }
1901 chk1(result == NDBT_OK);
1902 assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1903 assert(rowcnt == 0);
1904
1905 loop++;
1906 }
1907
1908 chk2(pDict->dropTable(tabname_bug34348) == 0, pDict->getNdbError());
1909
1910 chk1(restarter.insertErrorInAllNodes(errInsCLEAR) == 0);
1911 ndbout << "error insert clear done" << endl;
1912 break;
1913 }
1914
1915 if (result != NDBT_OK && restarter.insertErrorInAllNodes(errInsCLEAR) != 0)
1916 g_err << "error insert clear failed" << endl;
1917
1918 delete [] rowmask;
1919 rowmask = 0;
1920 return result;
1921 }
1922
1923 #define check(b, e) \
1924 if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e.getNdbError() << endl; return NDBT_FAILED; }
1925
runUnlocker(NDBT_Context * ctx,NDBT_Step * step)1926 int runUnlocker(NDBT_Context* ctx, NDBT_Step* step){
1927 int loops = ctx->getNumLoops();
1928 int records = ctx->getNumRecords();
1929 int batchSize = ctx->getProperty("Batchsize", 1);
1930 int doubleUnlock = ctx->getProperty("DoubleUnlock", (Uint32)0);
1931 int lm = ctx->getProperty("LockMode", NdbOperation::LM_Read);
1932 int i = 0;
1933 HugoOperations hugoOps(*ctx->getTab());
1934 Ndb* ndb = GETNDB(step);
1935
1936 g_err << "Unlocker : ";
1937 g_err << "Loops = " << loops << " Records = " << records << " Batchsize = "
1938 << batchSize << endl;
1939
1940 while(i++ < loops)
1941 {
1942 g_err << i << " ";
1943
1944 check(hugoOps.startTransaction(ndb) == 0, (*ndb));
1945
1946 const int maxRetries = 10;
1947 int retryAttempt = 0;
1948 int r = records;
1949 Vector<const NdbLockHandle*> lockHandles;
1950
1951 while(r > 0)
1952 {
1953 int batchContents = MIN(r, batchSize);
1954
1955 check(hugoOps.pkReadRecordLockHandle(ndb,
1956 lockHandles,
1957 records - r,
1958 batchContents,
1959 (NdbOperation::LockMode)lm) == 0,
1960 hugoOps);
1961
1962 r-= batchContents;
1963
1964 if (hugoOps.execute_NoCommit(ndb) != 0)
1965 {
1966 NdbError err = hugoOps.getNdbError();
1967 if ((err.status == NdbError::TemporaryError) &&
1968 retryAttempt < maxRetries){
1969 ERR(err);
1970 NdbSleep_MilliSleep(50);
1971 retryAttempt++;
1972 lockHandles.clear();
1973 check(hugoOps.closeTransaction(ndb) == 0,
1974 hugoOps);
1975 check(hugoOps.startTransaction(ndb) == 0, (*ndb));
1976 continue;
1977 }
1978 ERR(err);
1979 return NDBT_FAILED;
1980 }
1981
1982 check(hugoOps.pkUnlockRecord(ndb,
1983 lockHandles) == 0,
1984 hugoOps);
1985
1986 check(hugoOps.execute_NoCommit(ndb) == 0,
1987 hugoOps);
1988
1989 if (doubleUnlock)
1990 {
1991 NdbOperation::AbortOption ao;
1992 switch(rand() % 2)
1993 {
1994 case 0:
1995 ao = NdbOperation::AbortOnError;
1996 break;
1997 case 1:
1998 default:
1999 ao = NdbOperation::AO_IgnoreError;
2000 break;
2001 }
2002
2003 g_err << "Double unlock, abort option is "
2004 << ao << endl;
2005
2006 /* Failure scenario */
2007 check(hugoOps.pkUnlockRecord(ndb,
2008 lockHandles,
2009 0, // offset
2010 ~(0), // NumRecords
2011 ao) == 0,
2012 hugoOps);
2013
2014 check(hugoOps.execute_NoCommit(ndb,
2015 DefaultAbortOption) != 0,
2016 hugoOps);
2017
2018 /* 417 = Bad operation reference */
2019 check(hugoOps.getNdbError().code == 417,
2020 hugoOps);
2021
2022
2023 if (ao == NdbOperation::AbortOnError)
2024 {
2025 /* Restart transaction and continue with next loop iteration */
2026 r = 0;
2027 lockHandles.clear();
2028 check(hugoOps.closeTransaction(ndb) == 0,
2029 hugoOps);
2030 check(hugoOps.startTransaction(ndb) == 0, (*ndb));
2031
2032 continue;
2033 }
2034 /* Otherwise, IgnoreError, so let's attempt to
2035 * continue
2036 */
2037 }
2038
2039 check(hugoOps.releaseLockHandles(ndb,
2040 lockHandles) == 0,
2041 hugoOps);
2042
2043 lockHandles.clear();
2044 }
2045
2046 switch(rand() % 3)
2047 {
2048 case 0:
2049 check(hugoOps.execute_Commit(ndb) == 0,
2050 hugoOps);
2051 break;
2052 case 1:
2053 check(hugoOps.execute_Rollback(ndb) == 0,
2054 hugoOps);
2055 break;
2056 default:
2057 /* Do nothing, just close */
2058 break;
2059 }
2060
2061 check(hugoOps.closeTransaction(ndb) == 0,
2062 hugoOps);
2063
2064 }
2065
2066 g_err << endl;
2067
2068 return NDBT_OK;
2069 }
2070
2071 template class Vector<NdbRecAttr*>;
2072
2073 int
runBug54986(NDBT_Context * ctx,NDBT_Step * step)2074 runBug54986(NDBT_Context* ctx, NDBT_Step* step)
2075 {
2076 NdbRestarter restarter;
2077 Ndb* pNdb = GETNDB(step);
2078 NdbDictionary::Dictionary* pDict = pNdb->getDictionary();
2079 const NdbDictionary::Table * pTab = ctx->getTab();
2080 NdbDictionary::Table copy = *pTab;
2081
2082 BaseString name;
2083 name.assfmt("%s_COPY", copy.getName());
2084 copy.setName(name.c_str());
2085 pDict->createTable(copy);
2086 const NdbDictionary::Table * copyTab = pDict->getTable(copy.getName());
2087
2088 HugoTransactions hugoTrans(*pTab);
2089 hugoTrans.loadTable(pNdb, 20);
2090 hugoTrans.clearTable(pNdb);
2091
2092 const Uint32 rows = 5000;
2093
2094 HugoTransactions hugoTransCopy(*copyTab);
2095 hugoTransCopy.loadTable(pNdb, rows);
2096
2097 {
2098 restarter.getNumDbNodes(); // connect
2099 int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT, 0 };
2100 NdbLogEventHandle handle =
2101 ndb_mgm_create_logevent_handle(restarter.handle, filter);
2102 for (Uint32 i = 0; i<3; i++)
2103 {
2104 int dump[] = { DumpStateOrd::DihStartLcpImmediately };
2105
2106 struct ndb_logevent event;
2107
2108 restarter.dumpStateAllNodes(dump, 1);
2109 while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
2110 event.type != NDB_LE_LocalCheckpointStarted);
2111 while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
2112 event.type != NDB_LE_LocalCheckpointCompleted);
2113 }
2114 ndb_mgm_destroy_logevent_handle(&handle);
2115 }
2116
2117 for (int i = 0; i<5; i++)
2118 {
2119 int val1 = DumpStateOrd::DihMaxTimeBetweenLCP;
2120 int val2 = 7099; // Force start
2121
2122 restarter.dumpStateAllNodes(&val1, 1);
2123 int val[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2124 restarter.dumpStateAllNodes(val, 2);
2125
2126 restarter.insertErrorInAllNodes(932); // prevent arbit shutdown
2127
2128 HugoTransactions hugoTrans(*pTab);
2129 hugoTrans.loadTable(pNdb, 20);
2130
2131 restarter.dumpStateAllNodes(&val2, 1);
2132
2133 NdbSleep_SecSleep(15);
2134 hugoTrans.clearTable(pNdb);
2135
2136 hugoTransCopy.pkReadRecords(pNdb, rows);
2137
2138 HugoOperations hugoOps(*pTab);
2139 hugoOps.startTransaction(pNdb);
2140 hugoOps.pkInsertRecord(pNdb, 1);
2141 hugoOps.execute_NoCommit(pNdb);
2142
2143 restarter.insertErrorInAllNodes(5056);
2144 restarter.dumpStateAllNodes(&val2, 1);
2145 restarter.waitClusterNoStart();
2146 int vall = 11009;
2147 restarter.dumpStateAllNodes(&vall, 1);
2148 restarter.startAll();
2149 restarter.waitClusterStarted();
2150 }
2151
2152 pDict->dropTable(copy.getName());
2153
2154 // remove 25-page pgman
2155 restarter.restartAll(false, true, true);
2156 restarter.waitClusterNoStart();
2157 restarter.startAll();
2158 restarter.waitClusterStarted();
2159 return NDBT_OK;
2160 }
2161
2162 int
runBug54944(NDBT_Context * ctx,NDBT_Step * step)2163 runBug54944(NDBT_Context* ctx, NDBT_Step* step)
2164 {
2165 Ndb* pNdb = GETNDB(step);
2166 const NdbDictionary::Table * pTab = ctx->getTab();
2167 NdbRestarter res;
2168
2169 for (Uint32 i = 0; i<5; i++)
2170 {
2171 Uint32 rows = 5000 + i * 2000;
2172 HugoOperations hugoOps(*pTab);
2173 hugoOps.startTransaction(pNdb);
2174
2175 for (Uint32 r = 0; r < rows; r++)
2176 {
2177 for (Uint32 b = 0; b<100; b++, r++)
2178 {
2179 hugoOps.pkInsertRecord(pNdb, r);
2180 }
2181 hugoOps.execute_NoCommit(pNdb);
2182 }
2183
2184 res.insertErrorInAllNodes(8087);
2185
2186 HugoTransactions hugoTrans(*pTab);
2187 hugoTrans.loadTableStartFrom(pNdb, 50000, 100);
2188
2189 hugoOps.execute_Rollback(pNdb);
2190 hugoTrans.clearTable(pNdb);
2191
2192 res.insertErrorInAllNodes(0);
2193 }
2194 return NDBT_OK;
2195 }
2196
2197 int
runBug59496_scan(NDBT_Context * ctx,NDBT_Step * step)2198 runBug59496_scan(NDBT_Context* ctx, NDBT_Step* step)
2199 {
2200 Ndb* pNdb = GETNDB(step);
2201 const NdbDictionary::Table * pTab = ctx->getTab();
2202 NdbRestarter res;
2203 int rowcount = ctx->getProperty("CHECK_ROWCOUNT", Uint32(0));
2204 int records = ctx->getNumRecords();
2205 if (rowcount == 0)
2206 records = 0;
2207
2208 HugoTransactions hugoTrans(*pTab);
2209 while (!ctx->isTestStopped())
2210 {
2211 if (hugoTrans.scanReadRecords(pNdb,
2212 records, 0, 0,
2213 NdbOperation::LM_CommittedRead,
2214 (int)NdbScanOperation::SF_TupScan) != NDBT_OK)
2215 return NDBT_FAILED;
2216 }
2217 return NDBT_OK;
2218 }
2219
2220 int
runBug59496_case1(NDBT_Context * ctx,NDBT_Step * step)2221 runBug59496_case1(NDBT_Context* ctx, NDBT_Step* step)
2222 {
2223 Ndb* pNdb = GETNDB(step);
2224 NdbRestarter res;
2225
2226 int loops = ctx->getNumLoops();
2227 int records = ctx->getNumRecords();
2228
2229 HugoOperations hugoOps(*ctx->getTab());
2230 for (int i = 0; i < loops; i++)
2231 {
2232 hugoOps.startTransaction(pNdb);
2233 hugoOps.pkInsertRecord(pNdb, 0, records, 0);
2234 hugoOps.execute_NoCommit(pNdb);
2235 hugoOps.pkUpdateRecord(pNdb, 0, records, rand());
2236 hugoOps.execute_NoCommit(pNdb);
2237 hugoOps.pkUpdateRecord(pNdb, 0, records, rand());
2238 hugoOps.execute_NoCommit(pNdb);
2239 res.insertErrorInAllNodes(8089);
2240 hugoOps.execute_Commit(pNdb);
2241 res.insertErrorInAllNodes(0);
2242 hugoOps.closeTransaction(pNdb);
2243 hugoOps.clearTable(pNdb);
2244 }
2245 ctx->stopTest();
2246 return NDBT_OK;
2247 }
2248
2249 int
runBug59496_case2(NDBT_Context * ctx,NDBT_Step * step)2250 runBug59496_case2(NDBT_Context* ctx, NDBT_Step* step)
2251 {
2252 Ndb* pNdb = GETNDB(step);
2253 NdbRestarter res;
2254
2255 int loops = ctx->getNumLoops();
2256 int records = ctx->getNumRecords();
2257
2258 HugoOperations hugoOps(*ctx->getTab());
2259 for (int i = 0; i < loops; i++)
2260 {
2261 hugoOps.startTransaction(pNdb);
2262 hugoOps.pkDeleteRecord(pNdb, 0, records);
2263 hugoOps.execute_NoCommit(pNdb);
2264 hugoOps.pkInsertRecord(pNdb, 0, records, 0);
2265 hugoOps.execute_NoCommit(pNdb);
2266
2267 res.insertErrorInAllNodes(8089);
2268 hugoOps.execute_Rollback(pNdb);
2269 res.insertErrorInAllNodes(0);
2270
2271 hugoOps.closeTransaction(pNdb);
2272 }
2273 ctx->stopTest();
2274 return NDBT_OK;
2275 }
2276
2277 #define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
2278
2279 int
runTest899(NDBT_Context * ctx,NDBT_Step * step)2280 runTest899(NDBT_Context* ctx, NDBT_Step* step)
2281 {
2282 Ndb* pNdb = GETNDB(step);
2283 const NdbDictionary::Table* pTab = ctx->getTab();
2284
2285 const int rows = ctx->getNumRecords();
2286 const int loops = ctx->getNumLoops();
2287 const int batch = ctx->getProperty("Batch", Uint32(50));
2288 const int until_stopped = ctx->getProperty("UntilStopped");
2289
2290 const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2291 CHK_RET_FAILED(pRowRecord != 0);
2292
2293 const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2294 Uint8 * pRow = new Uint8[len];
2295
2296 int count_ok = 0;
2297 int count_failed = 0;
2298 int count_899 = 0;
2299 for (int i = 0; i < loops || (until_stopped && !ctx->isTestStopped()); i++)
2300 {
2301 ndbout_c("loop: %d",i);
2302 int result = 0;
2303 for (int rowNo = 0; rowNo < rows;)
2304 {
2305 NdbTransaction* pTrans = pNdb->startTransaction();
2306 CHK_RET_FAILED(pTrans != 0);
2307
2308 for (int b = 0; rowNo < rows && b < batch; rowNo++, b++)
2309 {
2310 bzero(pRow, len);
2311
2312 HugoCalculator calc(* pTab);
2313
2314 NdbOperation::OperationOptions opts;
2315 bzero(&opts, sizeof(opts));
2316
2317 const NdbOperation* pOp = 0;
2318 switch(i % 2){
2319 case 0:
2320 calc.setValues(pRow, pRowRecord, rowNo, rand());
2321 pOp = pTrans->writeTuple(pRowRecord, (char*)pRow,
2322 pRowRecord, (char*)pRow,
2323 0,
2324 &opts,
2325 sizeof(opts));
2326 result = pTrans->execute(NoCommit);
2327 break;
2328 case 1:
2329 calc.setValues(pRow, pRowRecord, rowNo, rand());
2330 pOp = pTrans->deleteTuple(pRowRecord, (char*)pRow,
2331 pRowRecord, (char*)pRow,
2332 0,
2333 &opts,
2334 sizeof(opts));
2335 result = pTrans->execute(NoCommit, AO_IgnoreError);
2336 break;
2337 }
2338
2339 CHK_RET_FAILED(pOp != 0);
2340
2341 if (result != 0)
2342 {
2343 goto found_error;
2344 }
2345 }
2346 result = pTrans->execute(Commit);
2347
2348 if (result != 0)
2349 {
2350 found_error:
2351 count_failed++;
2352 NdbError err = pTrans->getNdbError();
2353 if (! (err.status == NdbError::TemporaryError ||
2354 err.classification == NdbError::NoDataFound ||
2355 err.classification == NdbError::ConstraintViolation))
2356 {
2357 ndbout << err << endl;
2358 }
2359 CHK_RET_FAILED(err.status == NdbError::TemporaryError ||
2360 err.classification == NdbError::NoDataFound ||
2361 err.classification == NdbError::ConstraintViolation);
2362 if (err.code == 899)
2363 {
2364 count_899++;
2365 ndbout << err << endl;
2366 }
2367 }
2368 else
2369 {
2370 count_ok++;
2371 }
2372 pTrans->close();
2373 }
2374 }
2375
2376 ndbout_c("count_ok: %d count_failed: %d (899: %d)",
2377 count_ok, count_failed, count_899);
2378 delete [] pRow;
2379
2380 return count_899 == 0 ? NDBT_OK : NDBT_FAILED;
2381 }
2382
2383 int
runInit899(NDBT_Context * ctx,NDBT_Step * step)2384 runInit899(NDBT_Context* ctx, NDBT_Step* step)
2385 {
2386 NdbRestarter restarter;
2387 int val = DumpStateOrd::DihMinTimeBetweenLCP;
2388 restarter.dumpStateAllNodes(&val, 1);
2389
2390 Ndb* pNdb = GETNDB(step);
2391 const NdbDictionary::Table* pTab = ctx->getTab();
2392 const NdbDictionary::Table * pTab2 = pNdb->getDictionary()->
2393 getTable(pTab->getName());
2394
2395 int tableId = pTab2->getObjectId();
2396 int val2[] = { DumpStateOrd::BackupErrorInsert, 10042, tableId };
2397
2398 for (int i = 0; i < restarter.getNumDbNodes(); i++)
2399 {
2400 if (i & 1)
2401 {
2402 int nodeId = restarter.getDbNodeId(i);
2403 ndbout_c("Setting slow LCP of table %d on node %d",
2404 tableId, nodeId);
2405 restarter.dumpStateOneNode(nodeId, val2, 3);
2406 }
2407 }
2408
2409 return NDBT_OK;
2410 }
2411
2412 int
runEnd899(NDBT_Context * ctx,NDBT_Step * step)2413 runEnd899(NDBT_Context* ctx, NDBT_Step* step)
2414 {
2415 // reset LCP speed
2416 NdbRestarter restarter;
2417 int val[] = { DumpStateOrd::DihMinTimeBetweenLCP, 0 };
2418 restarter.dumpStateAllNodes(val, 2);
2419
2420 restarter.insertErrorInAllNodes(0);
2421 return NDBT_OK;
2422 }
2423
2424
initSubscription(NDBT_Context * ctx,NDBT_Step * step)2425 int initSubscription(NDBT_Context* ctx, NDBT_Step* step){
2426 /* Subscribe to events on the table, and put access
2427 * to the subscription somewhere handy
2428 */
2429 Ndb* pNdb = GETNDB(step);
2430 const NdbDictionary::Table& tab = *ctx->getTab();
2431 bool merge_events = false;
2432 bool report = false;
2433
2434 char eventName[1024];
2435 sprintf(eventName,"%s_EVENT",tab.getName());
2436
2437 NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
2438
2439 if (!myDict) {
2440 g_err << "Dictionary not found "
2441 << pNdb->getNdbError().code << " "
2442 << pNdb->getNdbError().message << endl;
2443 return NDBT_FAILED;
2444 }
2445
2446 myDict->dropEvent(eventName);
2447
2448 NdbDictionary::Event myEvent(eventName);
2449 myEvent.setTable(tab.getName());
2450 myEvent.addTableEvent(NdbDictionary::Event::TE_ALL);
2451 for(int a = 0; a < tab.getNoOfColumns(); a++){
2452 myEvent.addEventColumn(a);
2453 }
2454 myEvent.mergeEvents(merge_events);
2455
2456 if (report)
2457 myEvent.setReport(NdbDictionary::Event::ER_SUBSCRIBE);
2458
2459 int res = myDict->createEvent(myEvent); // Add event to database
2460
2461 if (res == 0)
2462 myEvent.print();
2463 else if (myDict->getNdbError().classification ==
2464 NdbError::SchemaObjectExists)
2465 {
2466 g_info << "Event creation failed event exists\n";
2467 res = myDict->dropEvent(eventName);
2468 if (res) {
2469 g_err << "Failed to drop event: "
2470 << myDict->getNdbError().code << " : "
2471 << myDict->getNdbError().message << endl;
2472 return NDBT_FAILED;
2473 }
2474 // try again
2475 res = myDict->createEvent(myEvent); // Add event to database
2476 if (res) {
2477 g_err << "Failed to create event (1): "
2478 << myDict->getNdbError().code << " : "
2479 << myDict->getNdbError().message << endl;
2480 return NDBT_FAILED;
2481 }
2482 }
2483 else
2484 {
2485 g_err << "Failed to create event (2): "
2486 << myDict->getNdbError().code << " : "
2487 << myDict->getNdbError().message << endl;
2488 return NDBT_FAILED;
2489 }
2490
2491 return NDBT_OK;
2492 }
2493
removeSubscription(NDBT_Context * ctx,NDBT_Step * step)2494 int removeSubscription(NDBT_Context* ctx, NDBT_Step* step){
2495 /* Remove subscription created above */
2496 Ndb* pNdb = GETNDB(step);
2497 const NdbDictionary::Table& tab = *ctx->getTab();
2498
2499 char eventName[1024];
2500 sprintf(eventName,"%s_EVENT",tab.getName());
2501
2502 NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
2503
2504 if (!myDict) {
2505 g_err << "Dictionary not found "
2506 << pNdb->getNdbError().code << " "
2507 << pNdb->getNdbError().message << endl;
2508 return NDBT_FAILED;
2509 }
2510
2511 myDict->dropEvent(eventName);
2512
2513 return NDBT_OK;
2514 }
2515
runVerifyRowCount(NDBT_Context * ctx,NDBT_Step * step)2516 int runVerifyRowCount(NDBT_Context* ctx, NDBT_Step* step)
2517 {
2518 Ndb* ndb = GETNDB(step);
2519
2520 /* Check that number of results returned by a normal scan
2521 * and per-fragment rowcount sum are equal
2522 */
2523 Uint32 rowCountSum = 0;
2524 Uint32 rowScanCount = 0;
2525
2526 int result = NDBT_OK;
2527 do
2528 {
2529 NdbTransaction* trans = ndb->startTransaction();
2530 CHECK(trans != NULL);
2531
2532 NdbScanOperation* scan = trans->getNdbScanOperation(ctx->getTab());
2533 CHECK(scan != NULL);
2534
2535 CHECK(scan->readTuples(NdbScanOperation::LM_CommittedRead) == 0);
2536
2537 NdbInterpretedCode code;
2538
2539 CHECK(code.interpret_exit_last_row() == 0);
2540 CHECK(code.finalise() == 0);
2541
2542 NdbRecAttr* rowCountRA = scan->getValue(NdbDictionary::Column::ROW_COUNT);
2543 CHECK(rowCountRA != NULL);
2544 CHECK(scan->setInterpretedCode(&code) == 0);
2545
2546 CHECK(trans->execute(NoCommit) == 0);
2547
2548 while (scan->nextResult() == 0)
2549 rowCountSum+= rowCountRA->u_32_value();
2550
2551 trans->close();
2552
2553 trans = ndb->startTransaction();
2554 CHECK(trans != NULL);
2555
2556 scan = trans->getNdbScanOperation(ctx->getTab());
2557 CHECK(scan != NULL);
2558
2559 CHECK(scan->readTuples(NdbScanOperation::LM_CommittedRead) == 0);
2560
2561 rowCountRA = scan->getValue(NdbDictionary::Column::ROW_COUNT);
2562 CHECK(rowCountRA != NULL);
2563
2564 CHECK(trans->execute(NoCommit) == 0);
2565
2566 while (scan->nextResult() == 0)
2567 rowScanCount++;
2568
2569 trans->close();
2570 }
2571 while(0);
2572
2573 if (result == NDBT_OK)
2574 {
2575 ndbout_c("Sum of fragment row counts : %u Number rows scanned : %u",
2576 rowCountSum,
2577 rowScanCount);
2578
2579 if (rowCountSum != rowScanCount)
2580 {
2581 ndbout_c("MISMATCH");
2582 result = NDBT_FAILED;
2583 }
2584 }
2585
2586 return result;
2587 }
2588
2589 enum ApiEventType { Insert, Update, Delete };
2590
2591 template class Vector<ApiEventType>;
2592
2593 struct EventInfo
2594 {
2595 ApiEventType type;
2596 int id;
2597 Uint64 gci;
2598 };
2599 template class Vector<EventInfo>;
2600
collectEvents(Ndb * ndb,HugoCalculator & calc,const NdbDictionary::Table & tab,Vector<EventInfo> & receivedEvents,int idCol,int updateCol,Vector<NdbRecAttr * > * beforeAttrs,Vector<NdbRecAttr * > * afterAttrs)2601 int collectEvents(Ndb* ndb,
2602 HugoCalculator& calc,
2603 const NdbDictionary::Table& tab,
2604 Vector<EventInfo>& receivedEvents,
2605 int idCol,
2606 int updateCol,
2607 Vector<NdbRecAttr*>* beforeAttrs,
2608 Vector<NdbRecAttr*>* afterAttrs)
2609 {
2610 int MaxTimeouts = 5;
2611 while (true)
2612 {
2613 int res = ndb->pollEvents(1000);
2614
2615 if (res > 0)
2616 {
2617 NdbEventOperation* pOp;
2618 while ((pOp = ndb->nextEvent()))
2619 {
2620 bool isDelete = (pOp->getEventType() == NdbDictionary::Event::TE_DELETE);
2621 Vector<NdbRecAttr*>* whichVersion =
2622 isDelete?
2623 beforeAttrs :
2624 afterAttrs;
2625 int id = (*whichVersion)[idCol]->u_32_value();
2626 Uint64 gci = pOp->getGCI();
2627 Uint32 anyValue = pOp->getAnyValue();
2628 Uint32 scenario = ((anyValue >> 24) & 0xff) -1;
2629 Uint32 optype = ((anyValue >> 16) & 0xff);
2630 Uint32 recNum = (anyValue & 0xffff);
2631
2632 g_err << "# " << receivedEvents.size()
2633 << " GCI : " << (gci >> 32)
2634 << "/"
2635 << (gci & 0xffffffff)
2636 << " id : "
2637 << id
2638 << " scenario : " << scenario
2639 << " optype : " << optype
2640 << " record : " << recNum
2641 << " ";
2642
2643 /* Check event has self-consistent data */
2644 int updatesValue = (*whichVersion)[updateCol]->u_32_value();
2645
2646 if ((*whichVersion)[updateCol]->isNULL() ||
2647 (*whichVersion)[idCol]->isNULL())
2648 {
2649 g_err << "Null update/id cols : REFRESH of !EXISTS ";
2650 }
2651
2652 g_err << "(Updates val = " << updatesValue << ")";
2653
2654 for (int i=0; i < (int) whichVersion->size(); i++)
2655 {
2656 /* Check PK columns and also other columns for non-delete */
2657 if (!isDelete ||
2658 tab.getColumn(i)->getPrimaryKey())
2659 {
2660 NdbRecAttr* ra = (*whichVersion)[i];
2661 if (calc.verifyRecAttr(recNum, updatesValue, ra) != 0)
2662 {
2663 g_err << "Verify failed on recNum : " << recNum << " with updates value "
2664 << updatesValue << " for column " << ra->getColumn()->getAttrId()
2665 << endl;
2666 return NDBT_FAILED;
2667 }
2668 }
2669 }
2670
2671 EventInfo ei;
2672
2673 switch (pOp->getEventType())
2674 {
2675 case NdbDictionary::Event::TE_INSERT:
2676 g_err << " Insert event" << endl;
2677 ei.type = Insert;
2678 break;
2679 case NdbDictionary::Event::TE_DELETE:
2680 ei.type = Delete;
2681 g_err << " Delete event" << endl;
2682 break;
2683 case NdbDictionary::Event::TE_UPDATE:
2684 ei.type = Update;
2685 g_err << " Update event" << endl;
2686 break;
2687 default:
2688 g_err << " Event type : " << pOp->getEventType() << endl;
2689 abort();
2690 break;
2691 }
2692
2693 ei.id = recNum;
2694 ei.gci = gci;
2695
2696 receivedEvents.push_back(ei);
2697 }
2698 }
2699 else
2700 {
2701 if (--MaxTimeouts == 0)
2702 {
2703 break;
2704 }
2705 }
2706 }
2707
2708 return NDBT_OK;
2709 }
2710
verifyEvents(const Vector<EventInfo> & receivedEvents,const Vector<ApiEventType> & expectedEvents,int records)2711 int verifyEvents(const Vector<EventInfo>& receivedEvents,
2712 const Vector<ApiEventType>& expectedEvents,
2713 int records)
2714 {
2715 /* Now verify received events against expected
2716 * This is messy as events occurring in the same epoch are unordered
2717 * except via id, so we use id-duplicates to determine which event
2718 * sequence we're looking at.
2719 */
2720 g_err << "Received total of " << receivedEvents.size() << " events" << endl;
2721 Vector<Uint32> keys;
2722 Vector<Uint64> gcis;
2723 Uint32 z = 0;
2724 Uint64 z2 = 0;
2725 keys.fill(records, z);
2726 gcis.fill(records, z2);
2727 Uint64 currGci = 0;
2728
2729 for (Uint32 e=0; e < receivedEvents.size(); e++)
2730 {
2731 EventInfo ei = receivedEvents[e];
2732
2733 if (ei.gci != currGci)
2734 {
2735 if (ei.gci < currGci)
2736 abort();
2737
2738 /* Epoch boundary */
2739 /* At this point, all id counts must be equal */
2740 for (int i=0; i < records; i++)
2741 {
2742 if (keys[i] != keys[0])
2743 {
2744 g_err << "Count for id " << i
2745 << " is " << keys[i]
2746 << " but should be " << keys[0] << endl;
2747 return NDBT_OK;
2748 }
2749 }
2750
2751 currGci = ei.gci;
2752 }
2753
2754 Uint32 eventIndex = keys[ei.id];
2755 keys[ei.id]++;
2756
2757 ApiEventType et = expectedEvents[eventIndex];
2758
2759 if (ei.type != et)
2760 {
2761 g_err << "Expected event of type " << et
2762 << " but found " << ei.type
2763 << " at expectedEvent " << eventIndex
2764 << " and event num " << e << endl;
2765 return NDBT_FAILED;
2766 }
2767 }
2768
2769 return NDBT_OK;
2770 }
2771
runRefreshTuple(NDBT_Context * ctx,NDBT_Step * step)2772 int runRefreshTuple(NDBT_Context* ctx, NDBT_Step* step){
2773 int records = ctx->getNumRecords();
2774 Ndb* ndb = GETNDB(step);
2775
2776 /* Now attempt to create EventOperation */
2777 NdbEventOperation* pOp;
2778 const NdbDictionary::Table& tab = *ctx->getTab();
2779
2780 char eventName[1024];
2781 sprintf(eventName,"%s_EVENT",tab.getName());
2782
2783 pOp = ndb->createEventOperation(eventName);
2784 if (pOp == NULL)
2785 {
2786 g_err << "Failed to create event operation\n";
2787 return NDBT_FAILED;
2788 }
2789
2790 HugoCalculator calc(tab);
2791 Vector<NdbRecAttr*> eventAfterRecAttr;
2792 Vector<NdbRecAttr*> eventBeforeRecAttr;
2793 int updateCol = -1;
2794 int idCol = -1;
2795
2796 /* Now request all attributes */
2797 for (int a = 0; a < tab.getNoOfColumns(); a++)
2798 {
2799 eventAfterRecAttr.push_back(pOp->getValue(tab.getColumn(a)->getName()));
2800 eventBeforeRecAttr.push_back(pOp->getPreValue(tab.getColumn(a)->getName()));
2801 if (calc.isIdCol(a))
2802 idCol = a;
2803 if (calc.isUpdateCol(a))
2804 updateCol = a;
2805 }
2806
2807 /* Now execute the event */
2808 if (pOp->execute())
2809 {
2810 g_err << "Event operation execution failed : " << pOp->getNdbError() << endl;
2811 return NDBT_FAILED;
2812 }
2813
2814 HugoOperations hugoOps(*ctx->getTab());
2815 int scenario = 0;
2816
2817 Vector<ApiEventType> expectedEvents;
2818
2819 for (scenario = 0; scenario < 2; scenario++)
2820 {
2821 g_err << "Scenario = " << scenario
2822 << " ( Refresh "
2823 << ((scenario == 0)? "before":"after")
2824 << " operations )" << endl;
2825 int optype = 0;
2826 bool done = false;
2827 int expectedError = 0;
2828 do
2829 {
2830 check(hugoOps.startTransaction(ndb) == 0, hugoOps);
2831
2832 if (scenario == 0)
2833 {
2834 g_err << "Refresh before operations" << endl;
2835 int anyValue =
2836 ((1) << 8) |
2837 optype;
2838 check(hugoOps.pkRefreshRecord(ndb, 0, records, anyValue) == 0, hugoOps);
2839 }
2840
2841 switch(optype)
2842 {
2843 case 0:
2844 {
2845 /* Refresh with no data present */
2846 g_err << " Do nothing" << endl;
2847 expectedError = 0; /* Single refresh should always be fine */
2848 expectedEvents.push_back(Delete);
2849 break;
2850 }
2851 case 1:
2852 {
2853 /* [Refresh] Insert [Refresh] */
2854 g_err << " Insert" << endl;
2855 check(hugoOps.pkInsertRecord(ndb, 0, records, 1) == 0, hugoOps);
2856 if (scenario == 0)
2857 {
2858 /* Tuple already existed error when we insert after refresh */
2859 expectedError = 630;
2860 expectedEvents.push_back(Delete);
2861 }
2862 else
2863 {
2864 expectedError = 0;
2865 expectedEvents.push_back(Insert);
2866 }
2867 /* Tuple already existed error when we insert after refresh */
2868 break;
2869 }
2870 case 2:
2871 {
2872 /* Refresh */
2873 g_err << " Refresh" << endl;
2874 if (scenario == 0)
2875 {
2876 expectedEvents.push_back(Delete);
2877 }
2878 else
2879 {
2880 expectedEvents.push_back(Insert);
2881 }
2882 expectedError = 0;
2883 break;
2884 }
2885 case 3:
2886 {
2887 /* [Refresh] Update [Refresh] */
2888 g_err << " Update" << endl;
2889 check(hugoOps.pkUpdateRecord(ndb, 0, records, 3) == 0, hugoOps);
2890 if (scenario == 0)
2891 {
2892 expectedError = 920;
2893 expectedEvents.push_back(Delete);
2894 }
2895 else
2896 {
2897 expectedError = 0;
2898 expectedEvents.push_back(Insert);
2899 }
2900 break;
2901 }
2902 case 4:
2903 {
2904 /* [Refresh] Delete [Refresh] */
2905 g_err << " [Refresh] Delete [Refresh]" << endl;
2906 if (scenario == 0)
2907 {
2908 expectedError = 920;
2909 expectedEvents.push_back(Delete);
2910 }
2911 else
2912 {
2913 expectedError = 0;
2914 expectedEvents.push_back(Delete);
2915 }
2916 check(hugoOps.pkDeleteRecord(ndb, 0, records) == 0, hugoOps);
2917 break;
2918 }
2919 case 5:
2920 {
2921 g_err << " Refresh" << endl;
2922 expectedError = 0;
2923 expectedEvents.push_back(Delete);
2924 /* Refresh with no data present */
2925 break;
2926 }
2927 case 6:
2928 {
2929 g_err << " Double refresh" << endl;
2930 int anyValue =
2931 ((2) << 8) |
2932 optype;
2933 check(hugoOps.pkRefreshRecord(ndb, 0, records, anyValue) == 0, hugoOps);
2934 expectedError = 920; /* Row operation defined after refreshTuple() */
2935 expectedEvents.push_back(Delete);
2936 }
2937 default:
2938 done = true;
2939 break;
2940 }
2941
2942 if (scenario == 1)
2943 {
2944 g_err << "Refresh after operations" << endl;
2945 int anyValue =
2946 ((4) << 8) |
2947 optype;
2948 check(hugoOps.pkRefreshRecord(ndb, 0, records, anyValue) == 0, hugoOps);
2949 }
2950
2951 int rc = hugoOps.execute_Commit(ndb, AO_IgnoreError);
2952 check(rc == expectedError, hugoOps);
2953
2954 check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
2955
2956 optype++;
2957
2958
2959 /* Now check fragment counts vs findable row counts */
2960 if (runVerifyRowCount(ctx, step) != NDBT_OK)
2961 return NDBT_FAILED;
2962
2963 } while (!done);
2964 } // for scenario...
2965
2966 /* Now check fragment counts vs findable row counts */
2967 if (runVerifyRowCount(ctx, step) != NDBT_OK)
2968 return NDBT_FAILED;
2969
2970 /* Now let's dump and check the events */
2971 g_err << "Expecting the following sequence..." << endl;
2972 for (Uint32 i=0; i < expectedEvents.size(); i++)
2973 {
2974 g_err << i << ". ";
2975 switch(expectedEvents[i])
2976 {
2977 case Insert:
2978 g_err << "Insert" << endl;
2979 break;
2980 case Update:
2981 g_err << "Update" << endl;
2982 break;
2983 case Delete:
2984 g_err << "Delete" << endl;
2985 break;
2986 default:
2987 abort();
2988 }
2989 }
2990
2991 Vector<EventInfo> receivedEvents;
2992
2993 int rc = collectEvents(ndb, calc, tab, receivedEvents, idCol, updateCol,
2994 &eventBeforeRecAttr,
2995 &eventAfterRecAttr);
2996 if (rc == NDBT_OK)
2997 {
2998 rc = verifyEvents(receivedEvents,
2999 expectedEvents,
3000 records);
3001 }
3002
3003 if (ndb->dropEventOperation(pOp) != 0)
3004 {
3005 g_err << "Drop Event Operation failed : " << ndb->getNdbError() << endl;
3006 return NDBT_FAILED;
3007 }
3008
3009 return rc;
3010 };
3011
3012 enum PreRefreshOps
3013 {
3014 PR_NONE,
3015 PR_INSERT,
3016 PR_INSERTDELETE,
3017 PR_DELETE
3018 };
3019
3020 struct RefreshScenario
3021 {
3022 const char* name;
3023 bool preExist;
3024 PreRefreshOps preRefreshOps;
3025 };
3026
3027 static RefreshScenario refreshTests[] = {
3028 { "No row, No pre-ops", false, PR_NONE },
3029 { "No row, Insert pre-op", false, PR_INSERT },
3030 { "No row, Insert-Del pre-op", false, PR_INSERTDELETE },
3031 { "Row exists, No pre-ops", true, PR_NONE },
3032 { "Row exists, Delete pre-op", true, PR_DELETE }
3033 };
3034
3035 enum OpTypes
3036 {
3037 OP_READ_C,
3038 OP_READ_S,
3039 OP_READ_E,
3040 OP_INSERT,
3041 OP_UPDATE,
3042 OP_WRITE,
3043 OP_DELETE,
3044 OP_LAST
3045 };
3046
3047 const char* opTypeNames[] =
3048 {
3049 "READ_C",
3050 "READ_S",
3051 "READ_E",
3052 "INSERT",
3053 "UPDATE",
3054 "WRITE",
3055 "DELETE"
3056 };
3057
3058
3059 int
runRefreshLocking(NDBT_Context * ctx,NDBT_Step * step)3060 runRefreshLocking(NDBT_Context* ctx, NDBT_Step* step)
3061 {
3062 /* Check that refresh in various situations has the
3063 * locks we expect it to
3064 * Scenario combinations :
3065 * Now row pre-existing | Row pre-existing
3066 * Trans1 : Refresh | Insert-Refresh | Insert-Delete-Refresh
3067 * Delete-Refresh
3068 * Trans2 : Read [Committed|Shared|Exclusive] | Insert | Update
3069 * Write | Delete
3070 *
3071 * Expectations : Read committed always non-blocking
3072 * Read committed sees pre-existing row
3073 * All other trans2 operations deadlock
3074 */
3075
3076 Ndb* ndb = GETNDB(step);
3077 Uint32 numScenarios = sizeof(refreshTests) / sizeof(refreshTests[0]);
3078 HugoTransactions hugoTrans(*ctx->getTab());
3079
3080 for (Uint32 s = 0; s < numScenarios; s++)
3081 {
3082 RefreshScenario& scenario = refreshTests[s];
3083
3084 if (scenario.preExist)
3085 {
3086 /* Create pre-existing tuple */
3087 if (hugoTrans.loadTable(ndb, 1) != 0)
3088 {
3089 g_err << "Pre-exist failed : " << hugoTrans.getNdbError() << endl;
3090 return NDBT_FAILED;
3091 }
3092 }
3093
3094 if (hugoTrans.startTransaction(ndb) != 0)
3095 {
3096 g_err << "Start trans failed : " << hugoTrans.getNdbError() << endl;
3097 return NDBT_FAILED;
3098 }
3099
3100 g_err << "Scenario : " << scenario.name << endl;
3101
3102 /* Do pre-refresh ops */
3103 switch (scenario.preRefreshOps)
3104 {
3105 case PR_NONE:
3106 break;
3107 case PR_INSERT:
3108 case PR_INSERTDELETE:
3109 if (hugoTrans.pkInsertRecord(ndb, 0) != 0)
3110 {
3111 g_err << "Pre insert failed : " << hugoTrans.getNdbError() << endl;
3112 return NDBT_FAILED;
3113 }
3114
3115 if (scenario.preRefreshOps == PR_INSERT)
3116 break;
3117 case PR_DELETE:
3118 if (hugoTrans.pkDeleteRecord(ndb, 0) != 0)
3119 {
3120 g_err << "Pre delete failed : " << hugoTrans.getNdbError() << endl;
3121 return NDBT_FAILED;
3122 }
3123 break;
3124 }
3125
3126 /* Then refresh */
3127 if (hugoTrans.pkRefreshRecord(ndb, 0) != 0)
3128 {
3129 g_err << "Refresh failed : " << hugoTrans.getNdbError() << endl;
3130 return NDBT_FAILED;
3131 }
3132
3133 /* Now execute */
3134 if (hugoTrans.execute_NoCommit(ndb) != 0)
3135 {
3136 g_err << "Execute failed : " << hugoTrans.getNdbError() << endl;
3137 return NDBT_FAILED;
3138 }
3139
3140 {
3141 /* Now try ops from another transaction */
3142 HugoOperations hugoOps(*ctx->getTab());
3143 Uint32 ot = OP_READ_C;
3144
3145 while (ot < OP_LAST)
3146 {
3147 if (hugoOps.startTransaction(ndb) != 0)
3148 {
3149 g_err << "Start trans2 failed : " << hugoOps.getNdbError() << endl;
3150 return NDBT_FAILED;
3151 }
3152
3153 g_err << "Operation type : " << opTypeNames[ot] << endl;
3154 int res = 0;
3155 switch (ot)
3156 {
3157 case OP_READ_C:
3158 res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_CommittedRead);
3159 break;
3160 case OP_READ_S:
3161 res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_Read);
3162 break;
3163 case OP_READ_E:
3164 res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_Exclusive);
3165 break;
3166 case OP_INSERT:
3167 res = hugoOps.pkInsertRecord(ndb, 0);
3168 break;
3169 case OP_UPDATE:
3170 res = hugoOps.pkUpdateRecord(ndb, 0);
3171 break;
3172 case OP_WRITE:
3173 res = hugoOps.pkWriteRecord(ndb, 0);
3174 break;
3175 case OP_DELETE:
3176 res = hugoOps.pkDeleteRecord(ndb, 0);
3177 break;
3178 case OP_LAST:
3179 abort();
3180 }
3181
3182 hugoOps.execute_Commit(ndb);
3183
3184 if ((ot == OP_READ_C) && (scenario.preExist))
3185 {
3186 if (hugoOps.getNdbError().code == 0)
3187 {
3188 g_err << "Read committed succeeded" << endl;
3189 }
3190 else
3191 {
3192 g_err << "UNEXPECTED : Read committed failed. " << hugoOps.getNdbError() << endl;
3193 return NDBT_FAILED;
3194 }
3195 }
3196 else
3197 {
3198 if (hugoOps.getNdbError().code == 0)
3199 {
3200 g_err << opTypeNames[ot] << " succeeded, should not have" << endl;
3201 return NDBT_FAILED;
3202 }
3203 }
3204
3205 hugoOps.closeTransaction(ndb);
3206
3207 ot = ot + 1;
3208 }
3209
3210 }
3211
3212 /* Close refresh transaction */
3213 hugoTrans.closeTransaction(ndb);
3214
3215 if (scenario.preExist)
3216 {
3217 /* Cleanup pre-existing before next iteration */
3218 if (hugoTrans.pkDelRecords(ndb, 0) != 0)
3219 {
3220 g_err << "Delete pre existing failed : " << hugoTrans.getNdbError() << endl;
3221 return NDBT_FAILED;
3222 }
3223 }
3224 }
3225
3226 return NDBT_OK;
3227 }
3228
3229
3230 NDBT_TESTSUITE(testBasic);
3231 TESTCASE("PkInsert",
3232 "Verify that we can insert and delete from this table using PK"
3233 "NOTE! No errors are allowed!" ){
3234 INITIALIZER(runInsert);
3235 VERIFIER(runVerifyInsert);
3236 }
3237 TESTCASE("PkRead",
3238 "Verify that we can insert, read and delete from this table using PK"){
3239 TC_PROPERTY("LockMode", NdbOperation::LM_Read);
3240 INITIALIZER(runLoadTable);
3241 STEP(runPkRead);
3242 FINALIZER(runClearTable);
3243 }
3244 TESTCASE("PkDirtyRead",
3245 "Verify that we can insert, dirty read and delete from this table using PK"){
3246 TC_PROPERTY("LockMode", NdbOperation::LM_Dirty);
3247 INITIALIZER(runLoadTable);
3248 STEP(runPkRead);
3249 FINALIZER(runClearTable);
3250 }
3251 TESTCASE("PkSimpleRead",
3252 "Verify that we can insert, simple read and delete from this table using PK"){
3253 TC_PROPERTY("LockMode", NdbOperation::LM_SimpleRead);
3254 INITIALIZER(runLoadTable);
3255 STEP(runPkRead);
3256 FINALIZER(runClearTable);
3257 }
3258 TESTCASE("PkUpdate",
3259 "Verify that we can insert, update and delete from this table using PK"){
3260 INITIALIZER(runLoadTable);
3261 STEP(runPkUpdate);
3262 FINALIZER(runClearTable);
3263 }
3264 TESTCASE("PkDelete",
3265 "Verify that we can delete from this table using PK"){
3266 INITIALIZER(runLoadTable);
3267 STEP(runPkDelete);
3268 FINALIZER(runClearTable);
3269 }
3270 TESTCASE("UpdateAndRead",
3271 "Verify that we can read and update at the same time"){
3272 INITIALIZER(runLoadTable);
3273 STEP(runPkRead);
3274 STEP(runPkRead);
3275 STEP(runPkRead);
3276 STEP(runPkUpdate);
3277 STEP(runPkUpdate);
3278 STEP(runPkUpdate);
3279 FINALIZER(runClearTable);
3280 }
3281 TESTCASE("PkReadAndLocker",
3282 "Verify that we can read although there are "\
3283 " a number of 1 second locks in the table"){
3284 INITIALIZER(runLoadTable);
3285 STEP(runPkReadUntilStopped);
3286 STEP(runLocker);
3287 FINALIZER(runClearTable);
3288 }
3289 TESTCASE("PkReadAndLocker2",
3290 "Verify that we can read and update although there are "\
3291 " a number of 1 second locks in the table"){
3292 INITIALIZER(runLoadTable);
3293 STEP(runPkReadUntilStopped);
3294 STEP(runPkReadUntilStopped);
3295 STEP(runPkReadUntilStopped);
3296 STEP(runPkReadUntilStopped);
3297 STEP(runPkReadUntilStopped);
3298 STEP(runPkReadUntilStopped);
3299 STEP(runLocker);
3300 FINALIZER(runClearTable);
3301 }
3302 TESTCASE("PkReadUpdateAndLocker",
3303 "Verify that we can read and update although there are "\
3304 " a number of 1 second locks in the table"){
3305 INITIALIZER(runLoadTable);
3306 STEP(runPkReadUntilStopped);
3307 STEP(runPkReadUntilStopped);
3308 STEP(runPkUpdateUntilStopped);
3309 STEP(runPkUpdateUntilStopped);
3310 STEP(runLocker);
3311 FINALIZER(runClearTable);
3312 }
3313 TESTCASE("ReadWithLocksAndInserts",
3314 "TR457: This test is added to verify that an insert of a records "\
3315 "that is already in the database does not delete the record"){
3316 INITIALIZER(runLoadTable);
3317 STEP(runPkReadUntilStopped);
3318 STEP(runPkReadUntilStopped);
3319 STEP(runLocker);
3320 STEP(runInsertUntilStopped);
3321 FINALIZER(runClearTable);
3322 }
3323 TESTCASE("PkInsertTwice",
3324 "Verify that we can't insert an already inserted record."
3325 "Error should be returned" ){
3326 INITIALIZER(runLoadTable);
3327 STEP(runInsertTwice);
3328 FINALIZER(runClearTable);
3329 }
3330 TESTCASE("NoCommitSleep",
3331 "Verify what happens when a NoCommit transaction is aborted by "
3332 "NDB because the application is sleeping" ){
3333 INITIALIZER(runLoadTable);
3334 INITIALIZER(runNoCommitSleep);
3335 FINALIZER(runClearTable2);
3336 }
3337 TESTCASE("Commit626",
3338 "Verify what happens when a Commit transaction is aborted by "
3339 "NDB because the record does no exist" ){
3340 INITIALIZER(runClearTable2);
3341 INITIALIZER(runCommit626);
3342 FINALIZER(runClearTable2);
3343 }
3344 TESTCASE("CommitTry626",
3345 "Verify what happens when a Commit(TryCommit) \n"
3346 "transaction is aborted by "
3347 "NDB because the record does no exist" ){
3348 INITIALIZER(runClearTable2);
3349 INITIALIZER(runCommit_TryCommit626);
3350 FINALIZER(runClearTable2);
3351 }
3352 TESTCASE("CommitAsMuch626",
3353 "Verify what happens when a Commit(CommitAsMuchAsPossible) \n"
3354 "transaction is aborted by\n"
3355 "NDB because the record does no exist" ){
3356 INITIALIZER(runClearTable2);
3357 INITIALIZER(runCommit_CommitAsMuchAsPossible626);
3358 FINALIZER(runClearTable2);
3359 }
3360 TESTCASE("NoCommit626",
3361 "Verify what happens when a NoCommit transaction is aborted by "
3362 "NDB because the record does no exist" ){
3363 INITIALIZER(runClearTable2);
3364 INITIALIZER(runNoCommit626);
3365 FINALIZER(runClearTable2);
3366 }
3367 TESTCASE("NoCommitRollback626",
3368 "Verify what happens when a NoCommit transaction is aborted by "
3369 "NDB because the record does no exist and then we try to rollback\n"
3370 "the transaction" ){
3371 INITIALIZER(runClearTable2);
3372 INITIALIZER(runNoCommitRollback626);
3373 FINALIZER(runClearTable2);
3374 }
3375 TESTCASE("Commit630",
3376 "Verify what happens when a Commit transaction is aborted by "
3377 "NDB because the record already exist" ){
3378 INITIALIZER(runLoadTable);
3379 INITIALIZER(runCommit630);
3380 FINALIZER(runClearTable2);
3381 }
3382 TESTCASE("CommitTry630",
3383 "Verify what happens when a Commit(TryCommit) \n"
3384 "transaction is aborted by "
3385 "NDB because the record already exist" ){
3386 INITIALIZER(runLoadTable);
3387 INITIALIZER(runCommit_TryCommit630);
3388 FINALIZER(runClearTable2);
3389 }
3390 TESTCASE("CommitAsMuch630",
3391 "Verify what happens when a Commit(CommitAsMuchAsPossible) \n"
3392 "transaction is aborted by\n"
3393 "NDB because the record already exist" ){
3394 INITIALIZER(runLoadTable);
3395 INITIALIZER(runCommit_CommitAsMuchAsPossible630);
3396 FINALIZER(runClearTable2);
3397 }
3398 TESTCASE("NoCommit630",
3399 "Verify what happens when a NoCommit transaction is aborted by "
3400 "NDB because the record already exist" ){
3401 INITIALIZER(runLoadTable);
3402 INITIALIZER(runNoCommit630);
3403 FINALIZER(runClearTable2);
3404 }
3405 TESTCASE("NoCommitRollback630",
3406 "Verify what happens when a NoCommit transaction is aborted by "
3407 "NDB because the record already exist and then we try to rollback\n"
3408 "the transaction" ){
3409 INITIALIZER(runLoadTable);
3410 INITIALIZER(runNoCommitRollback630);
3411 FINALIZER(runClearTable2);
3412 }
3413 TESTCASE("NoCommitAndClose",
3414 "Verify what happens when a NoCommit transaction is closed "
3415 "without rolling back the transaction " ){
3416 INITIALIZER(runLoadTable);
3417 INITIALIZER(runNoCommitAndClose);
3418 FINALIZER(runClearTable2);
3419 }
3420 TESTCASE("RollbackDelete",
3421 "Test rollback of a no committed delete"){
3422 INITIALIZER(runLoadTable);
3423 INITIALIZER(runCheckRollbackDelete);
3424 FINALIZER(runClearTable2);
3425 }
3426 TESTCASE("RollbackUpdate",
3427 "Test rollback of a no committed update"){
3428 INITIALIZER(runLoadTable);
3429 INITIALIZER(runCheckRollbackUpdate);
3430 FINALIZER(runClearTable2);
3431 }
3432 TESTCASE("RollbackDeleteMultiple",
3433 "Test rollback of 10 non committed delete"){
3434 INITIALIZER(runLoadTable);
3435 INITIALIZER(runCheckRollbackDeleteMultiple);
3436 FINALIZER(runClearTable2);
3437 }
3438 TESTCASE("ImplicitRollbackDelete",
3439 "Test close transaction after a no commited delete\n"
3440 "this would give an implicit rollback of the delete\n"){
3441 INITIALIZER(runLoadTable);
3442 INITIALIZER(runCheckImplicitRollbackDelete);
3443 FINALIZER(runClearTable2);
3444 }
3445 TESTCASE("CommitDelete",
3446 "Test close transaction after a no commited delete\n"
3447 "this would give an implicit rollback of the delete\n"){
3448 INITIALIZER(runLoadTable);
3449 INITIALIZER(runCheckCommitDelete);
3450 FINALIZER(runClearTable2);
3451 }
3452 TESTCASE("RollbackNothing",
3453 "Test rollback of nothing"){
3454 INITIALIZER(runLoadTable);
3455 INITIALIZER(runRollbackNothing);
3456 FINALIZER(runClearTable2);
3457 }
3458 TESTCASE("MassiveRollback",
3459 "Test rollback of 4096 operations"){
3460 INITIALIZER(runClearTable2);
3461 INITIALIZER(runMassiveRollback);
3462 FINALIZER(runClearTable2);
3463 }
3464 TESTCASE("MassiveRollback2",
3465 "Test rollback of 4096 operations"){
3466 INITIALIZER(runClearTable2);
3467 INITIALIZER(runMassiveRollback2);
3468 FINALIZER(runClearTable2);
3469 }
3470 TESTCASE("MassiveRollback3",
3471 "Test rollback of 4096 operations"){
3472 INITIALIZER(runClearTable2);
3473 STEP(runMassiveRollback3);
3474 STEP(runMassiveRollback3);
3475 FINALIZER(runClearTable2);
3476 }
3477 TESTCASE("MassiveRollback4",
3478 "Test rollback of 4096 operations"){
3479 INITIALIZER(runClearTable2);
3480 STEP(runMassiveRollback4);
3481 STEP(runMassiveRollback4);
3482 FINALIZER(runClearTable2);
3483 }
3484 TESTCASE("MassiveTransaction",
3485 "Test very large insert transaction"){
3486 INITIALIZER(runLoadTable2);
3487 FINALIZER(runClearTable2);
3488 }
3489 TESTCASE("TupError",
3490 "Verify what happens when we fill the db" ){
3491 INITIALIZER(runTupErrors);
3492 }
3493 TESTCASE("InsertError", "" ){
3494 INITIALIZER(runInsertError);
3495 }
3496 TESTCASE("InsertError2", "" ){
3497 INITIALIZER(runInsertError2);
3498 }
3499 TESTCASE("Fill",
3500 "Verify what happens when we fill the db" ){
3501 STEP(runFillTable);
3502 }
3503 TESTCASE("Bug25090",
3504 "Verify what happens when we fill the db" ){
3505 STEP(runBug25090);
3506 }
3507 TESTCASE("DeleteRead",
3508 "Verify Delete+Read" ){
3509 INITIALIZER(runLoadTable);
3510 INITIALIZER(runDeleteRead);
3511 FINALIZER(runClearTable2);
3512 }
3513 TESTCASE("Bug27756",
3514 "Verify what happens when we fill the db" ){
3515 STEP(runBug27756);
3516 }
3517 TESTCASE("Bug28073",
3518 "Infinite loop in lock queue" ){
3519 STEP(runBug28073);
3520 }
3521 TESTCASE("Bug20535",
3522 "Verify what happens when we fill the db" ){
3523 STEP(runBug20535);
3524 }
3525 TESTCASE("DDInsertFailUpdateBatch",
3526 "Verify DD insert failure effect on other ops in batch on same PK"){
3527 STEP(runDDInsertFailUpdateBatch);
3528 }
3529
3530 TESTCASE("Bug34348",
3531 "Test fragment directory range full in ACC.\n"
3532 "NOTE: If interrupted, must clear error insert 3002 manually"){
3533 STEP(runBug34348);
3534 }
3535 TESTCASE("UnlockBatch",
3536 "Test that batched unlock operations work ok"){
3537 TC_PROPERTY("Batchsize", 33);
3538 INITIALIZER(runLoadTable);
3539 STEP(runUnlocker);
3540 FINALIZER(runClearTable);
3541 }
3542 TESTCASE("DoubleUnlock",
3543 "Test that batched unlock operations work ok"){
3544 TC_PROPERTY("DoubleUnlock", 1);
3545 INITIALIZER(runLoadTable);
3546 STEP(runUnlocker);
3547 FINALIZER(runClearTable);
3548 }
3549 TESTCASE("UnlockUpdateBatch",
3550 "Test Unlock mixed with Update"){
3551 TC_PROPERTY("Batchsize", 32);
3552 INITIALIZER(runLoadTable);
3553 STEP(runUnlocker);
3554 STEP(runUnlocker);
3555 STEP(runLocker);
3556 STEP(runPkUpdate);
3557 STEP(runPkUpdate);
3558 STEP(runPkRead);
3559 FINALIZER(runClearTable);
3560 }
3561 TESTCASE("RefreshTuple",
3562 "Test refreshTuple() operation properties"){
3563 INITIALIZER(initSubscription);
3564 INITIALIZER(runRefreshTuple);
3565 FINALIZER(removeSubscription);
3566 }
3567 TESTCASE("Bug54986", "")
3568 {
3569 INITIALIZER(runBug54986);
3570 }
3571 TESTCASE("Bug54944", "")
3572 {
3573 INITIALIZER(runBug54944);
3574 }
3575 TESTCASE("Bug59496_case1", "")
3576 {
3577 STEP(runBug59496_case1);
3578 STEPS(runBug59496_scan, 10);
3579 }
3580 TESTCASE("Bug59496_case2", "")
3581 {
3582 TC_PROPERTY("CHECK_ROWCOUNT", 1);
3583 INITIALIZER(runLoadTable);
3584 STEP(runBug59496_case2);
3585 STEPS(runBug59496_scan, 10);
3586 }
3587 TESTCASE("899", "")
3588 {
3589 INITIALIZER(runLoadTable);
3590 INITIALIZER(runInit899);
3591 STEP(runTest899);
3592 FINALIZER(runEnd899);
3593 }
3594 TESTCASE("RefreshLocking",
3595 "Test Refresh locking properties")
3596 {
3597 INITIALIZER(runRefreshLocking);
3598 }
3599 NDBT_TESTSUITE_END(testBasic);
3600
3601 #if 0
3602 TESTCASE("ReadConsistency",
3603 "Check that a read within a transaction returns the " \
3604 "same result no matter"){
3605 STEP(runInsertOne);
3606 STEP(runReadOne);
3607 FINALIZER(runClearTable2);
3608 }
3609 TESTCASE("Fill",
3610 "Verify what happens when we fill the db" ){
3611 INITIALIZER(runFillTable);
3612 INITIALIZER(runPkRead);
3613 FINALIZER(runClearTable2);
3614 }
3615 #endif
3616
main(int argc,const char ** argv)3617 int main(int argc, const char** argv){
3618 ndb_init();
3619 NDBT_TESTSUITE_INSTANCE(testBasic);
3620 return testBasic.execute(argc, argv);
3621 }
3622
3623
3624
3625