1 /*
2 Copyright (c) 2003, 2010, 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.hpp>
26 #include <NDBT_Test.hpp>
27 #include <HugoTransactions.hpp>
28 #include <UtilTransactions.hpp>
29 #include <NdbRestarter.hpp>
30 #include <NdbRestarts.hpp>
31 #include <Vector.hpp>
32 #include <signaldata/DumpStateOrd.hpp>
33 #include <NodeBitmask.hpp>
34 #include <NdbSqlUtil.hpp>
35 #include <BlockNumbers.h>
36
37 #define CHECK(b) if (!(b)) { \
38 g_err << "ERR: "<< step->getName() \
39 << " failed on line " << __LINE__ << endl; \
40 result = NDBT_FAILED; break;\
41 }
42
43 #define CHECKRET(b) if (!(b)) { \
44 g_err << "ERR: "<< step->getName() \
45 << " failed on line " << __LINE__ << endl; \
46 return NDBT_FAILED; \
47 }
48
49
50 struct Attrib {
51 bool indexCreated;
52 int numAttribs;
53 int attribs[1024];
AttribAttrib54 Attrib(){
55 numAttribs = 0;
56 indexCreated = false;
57 }
58 };
59 class AttribList {
60 public:
AttribList()61 AttribList(){};
~AttribList()62 ~AttribList(){
63 for(size_t i = 0; i < attriblist.size(); i++){
64 delete attriblist[i];
65 }
66 };
67 void buildAttribList(const NdbDictionary::Table* pTab);
68 Vector<Attrib*> attriblist;
69 };
70
buildAttribList(const NdbDictionary::Table * pTab)71 void AttribList::buildAttribList(const NdbDictionary::Table* pTab){
72 attriblist.clear();
73
74 Attrib* attr;
75 // Build attrib definitions that describes which attributes to build index
76 // Try to build strange combinations, not just "all" or all PK's
77
78 int i;
79
80 for(i = 1; i <= pTab->getNoOfColumns(); i++){
81 attr = new Attrib;
82 attr->numAttribs = i;
83 for(int a = 0; a<i; a++)
84 attr->attribs[a] = a;
85 attriblist.push_back(attr);
86 }
87 int b = 0;
88 for(i = pTab->getNoOfColumns()-1; i > 0; i--){
89 attr = new Attrib;
90 attr->numAttribs = i;
91 b++;
92 for(int a = 0; a<i; a++)
93 attr->attribs[a] = a+b;
94 attriblist.push_back(attr);
95 }
96 for(i = pTab->getNoOfColumns(); i > 0; i--){
97 attr = new Attrib;
98 attr->numAttribs = pTab->getNoOfColumns() - i;
99 for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
100 attr->attribs[a] = pTab->getNoOfColumns()-a-1;
101 attriblist.push_back(attr);
102 }
103 for(i = 1; i < pTab->getNoOfColumns(); i++){
104 attr = new Attrib;
105 attr->numAttribs = pTab->getNoOfColumns() - i;
106 for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
107 attr->attribs[a] = pTab->getNoOfColumns()-a-1;
108 attriblist.push_back(attr);
109 }
110 for(i = 1; i < pTab->getNoOfColumns(); i++){
111 attr = new Attrib;
112 attr->numAttribs = 2;
113 for(int a = 0; a<2; a++){
114 attr->attribs[a] = i%pTab->getNoOfColumns();
115 }
116 attriblist.push_back(attr);
117 }
118
119 // Last
120 attr = new Attrib;
121 attr->numAttribs = 1;
122 attr->attribs[0] = pTab->getNoOfColumns()-1;
123 attriblist.push_back(attr);
124
125 // Last and first
126 attr = new Attrib;
127 attr->numAttribs = 2;
128 attr->attribs[0] = pTab->getNoOfColumns()-1;
129 attr->attribs[1] = 0;
130 attriblist.push_back(attr);
131
132 // First and last
133 attr = new Attrib;
134 attr->numAttribs = 2;
135 attr->attribs[0] = 0;
136 attr->attribs[1] = pTab->getNoOfColumns()-1;
137 attriblist.push_back(attr);
138
139 #if 0
140 for(size_t i = 0; i < attriblist.size(); i++){
141
142 ndbout << attriblist[i]->numAttribs << ": " ;
143 for(int a = 0; a < attriblist[i]->numAttribs; a++)
144 ndbout << attriblist[i]->attribs[a] << ", ";
145 ndbout << endl;
146 }
147 #endif
148
149 }
150
151 char idxName[255];
152 char pkIdxName[255];
153
154 static const int SKIP_INDEX = 99;
155
create_index(NDBT_Context * ctx,int indxNum,const NdbDictionary::Table * pTab,Ndb * pNdb,Attrib * attr,bool logged)156 int create_index(NDBT_Context* ctx, int indxNum,
157 const NdbDictionary::Table* pTab,
158 Ndb* pNdb, Attrib* attr, bool logged){
159 bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
160 bool notOnlyPkId = ctx->getProperty("NotOnlyPkId", (unsigned)0);
161 int result = NDBT_OK;
162
163 HugoCalculator calc(*pTab);
164
165 if (attr->numAttribs == 1 &&
166 calc.isUpdateCol(attr->attribs[0]) == true){
167 // Don't create index for the Hugo update column
168 // since it's not unique
169 return SKIP_INDEX;
170 }
171
172 // Create index
173 BaseString::snprintf(idxName, 255, "IDC%d", indxNum);
174 if (orderedIndex)
175 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "<<idxName << " (";
176 else
177 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "<<idxName << " (";
178 ndbout << flush;
179 NdbDictionary::Index pIdx(idxName);
180 pIdx.setTable(pTab->getName());
181 if (orderedIndex)
182 pIdx.setType(NdbDictionary::Index::OrderedIndex);
183 else
184 pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
185
186 bool includesOnlyPkIdCols = true;
187 for (int c = 0; c< attr->numAttribs; c++){
188 int attrNo = attr->attribs[c];
189 const NdbDictionary::Column* col = pTab->getColumn(attrNo);
190 switch(col->getType())
191 {
192 case NDB_TYPE_BIT:
193 case NDB_TYPE_BLOB:
194 case NDB_TYPE_TEXT:
195 /* Not supported */
196 ndbout << col->getName() << " - bad type )" << endl;
197 return SKIP_INDEX;
198 default:
199 break;
200 }
201 if (col->getStorageType() == NDB_STORAGETYPE_DISK)
202 {
203 ndbout << col->getName() << " - disk based )" << endl;
204 return SKIP_INDEX;
205 }
206
207 pIdx.addIndexColumn(col->getName());
208 ndbout << col->getName()<<" ";
209
210 if (! (col->getPrimaryKey() ||
211 calc.isIdCol(attrNo)))
212 includesOnlyPkIdCols = false;
213 }
214
215 if (notOnlyPkId && includesOnlyPkIdCols)
216 {
217 ndbout << " Only PK/id cols included - skipping" << endl;
218 return SKIP_INDEX;
219 }
220
221 if (!orderedIndex)
222 {
223 /**
224 * For unique indexes we must add PK, otherwise it's not guaranteed
225 * to be unique
226 */
227 for (int i = 0; i<pTab->getNoOfColumns(); i++)
228 {
229 if (pTab->getColumn(i)->getPrimaryKey())
230 {
231 for (int j = 0; j<attr->numAttribs; j++)
232 {
233 if (attr->attribs[j] == i)
234 goto next;
235 }
236 pIdx.addIndexColumn(pTab->getColumn(i)->getName());
237 ndbout << pTab->getColumn(i)->getName() << " ";
238 }
239 next:
240 (void)i;
241 }
242 }
243
244 pIdx.setStoredIndex(logged);
245 ndbout << ") ";
246 bool noddl= ctx->getProperty("NoDDL");
247
248 if (noddl)
249 {
250 const NdbDictionary::Index* idx= pNdb->
251 getDictionary()->getIndex(pIdx.getName(), pTab->getName());
252
253 if (!idx)
254 {
255 ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
256 return NDBT_FAILED;
257 }
258 else
259 {
260 attr->indexCreated = false;
261 // TODO : Check index definition is ok
262 }
263 }
264 else
265 {
266 if (pNdb->getDictionary()->createIndex(pIdx) != 0){
267 attr->indexCreated = false;
268 ndbout << "FAILED!" << endl;
269 const NdbError err = pNdb->getDictionary()->getNdbError();
270 ERR(err);
271 if (err.classification == NdbError::ApplicationError)
272 return SKIP_INDEX;
273
274 if (err.status == NdbError::TemporaryError)
275 return SKIP_INDEX;
276
277 return NDBT_FAILED;
278 } else {
279 ndbout << "OK!" << endl;
280 attr->indexCreated = true;
281 }
282 }
283 return result;
284 }
285
286
drop_index(int indxNum,Ndb * pNdb,const NdbDictionary::Table * pTab,Attrib * attr)287 int drop_index(int indxNum, Ndb* pNdb,
288 const NdbDictionary::Table* pTab, Attrib* attr){
289 int result = NDBT_OK;
290
291 if (attr->indexCreated == false)
292 return NDBT_OK;
293
294 BaseString::snprintf(idxName, 255, "IDC%d", indxNum);
295
296 // Drop index
297 ndbout << "Dropping index "<<idxName<<"(" << pTab->getName() << ") ";
298 if (pNdb->getDictionary()->dropIndex(idxName, pTab->getName()) != 0){
299 ndbout << "FAILED!" << endl;
300 ERR(pNdb->getDictionary()->getNdbError());
301 result = NDBT_FAILED;
302 } else {
303 ndbout << "OK!" << endl;
304 }
305 return result;
306 }
307
runCreateIndexes(NDBT_Context * ctx,NDBT_Step * step)308 int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){
309 int loops = ctx->getNumLoops();
310 int l = 0;
311 const NdbDictionary::Table* pTab = ctx->getTab();
312 Ndb* pNdb = GETNDB(step);
313 int result = NDBT_OK;
314 // NOTE If we need to test creating both logged and non logged indexes
315 // this should be divided into two testcases
316 // The paramater logged should then be specified
317 // as a TC_PROPERTY. ex TC_PROPERTY("LoggedIndexes", 1);
318 // and read into the test step like
319 bool logged = ctx->getProperty("LoggedIndexes", 1);
320
321 AttribList attrList;
322 attrList.buildAttribList(pTab);
323
324
325 while (l < loops && result == NDBT_OK){
326 unsigned int i;
327 for (i = 0; i < attrList.attriblist.size(); i++){
328
329 // Try to create index
330 if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED)
331 result = NDBT_FAILED;
332 }
333
334 // Now drop all indexes that where created
335 for (i = 0; i < attrList.attriblist.size(); i++){
336
337 // Try to drop index
338 if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK)
339 result = NDBT_FAILED;
340 }
341
342 l++;
343 }
344
345 return result;
346 }
347
createRandomIndex(NDBT_Context * ctx,NDBT_Step * step)348 int createRandomIndex(NDBT_Context* ctx, NDBT_Step* step){
349 const NdbDictionary::Table* pTab = ctx->getTab();
350 Ndb* pNdb = GETNDB(step);
351 bool logged = ctx->getProperty("LoggedIndexes", 1);
352
353 AttribList attrList;
354 attrList.buildAttribList(pTab);
355
356 int retries = 100;
357 while(retries > 0){
358 const Uint32 i = rand() % attrList.attriblist.size();
359 int res = create_index(ctx, i, pTab, pNdb, attrList.attriblist[i],
360 logged);
361 if (res == SKIP_INDEX){
362 retries--;
363 continue;
364 }
365
366 if (res == NDBT_FAILED){
367 return NDBT_FAILED;
368 }
369
370 ctx->setProperty("createRandomIndex", i);
371 // Now drop all indexes that where created
372
373 return NDBT_OK;
374 }
375
376 return NDBT_FAILED;
377 }
378
createRandomIndex_Drop(NDBT_Context * ctx,NDBT_Step * step)379 int createRandomIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
380 Ndb* pNdb = GETNDB(step);
381
382 Uint32 i = ctx->getProperty("createRandomIndex");
383
384 BaseString::snprintf(idxName, 255, "IDC%d", i);
385
386 // Drop index
387 ndbout << "Dropping index " << idxName << " ";
388 if (pNdb->getDictionary()->dropIndex(idxName,
389 ctx->getTab()->getName()) != 0){
390 ndbout << "FAILED!" << endl;
391 ERR(pNdb->getDictionary()->getNdbError());
392 return NDBT_FAILED;
393 } else {
394 ndbout << "OK!" << endl;
395 }
396
397 return NDBT_OK;
398 }
399
createPkIndex(NDBT_Context * ctx,NDBT_Step * step)400 int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
401 bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
402
403 const NdbDictionary::Table* pTab = ctx->getTab();
404 Ndb* pNdb = GETNDB(step);
405
406 bool logged = ctx->getProperty("LoggedIndexes", 1);
407 bool noddl= ctx->getProperty("NoDDL");
408
409 // Create index
410 BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName());
411 if (orderedIndex)
412 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
413 << pkIdxName << " (";
414 else
415 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
416 << pkIdxName << " (";
417
418 NdbDictionary::Index pIdx(pkIdxName);
419 pIdx.setTable(pTab->getName());
420 if (orderedIndex)
421 pIdx.setType(NdbDictionary::Index::OrderedIndex);
422 else
423 pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
424 for (int c = 0; c< pTab->getNoOfColumns(); c++){
425 const NdbDictionary::Column * col = pTab->getColumn(c);
426 if(col->getPrimaryKey()){
427 pIdx.addIndexColumn(col->getName());
428 ndbout << col->getName() <<" ";
429 }
430 }
431
432 pIdx.setStoredIndex(logged);
433 ndbout << ") ";
434 if (noddl)
435 {
436 const NdbDictionary::Index* idx= pNdb->
437 getDictionary()->getIndex(pkIdxName, pTab->getName());
438
439 if (!idx)
440 {
441 ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
442 ERR(pNdb->getDictionary()->getNdbError());
443 return NDBT_FAILED;
444 }
445 else
446 {
447 // TODO : Check index definition is ok
448 }
449 }
450 else
451 {
452 if (pNdb->getDictionary()->createIndex(pIdx) != 0){
453 ndbout << "FAILED!" << endl;
454 const NdbError err = pNdb->getDictionary()->getNdbError();
455 ERR(err);
456 return NDBT_FAILED;
457 }
458 }
459
460 ndbout << "OK!" << endl;
461 return NDBT_OK;
462 }
463
createPkIndex_Drop(NDBT_Context * ctx,NDBT_Step * step)464 int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
465 const NdbDictionary::Table* pTab = ctx->getTab();
466 Ndb* pNdb = GETNDB(step);
467
468 bool noddl= ctx->getProperty("NoDDL");
469
470 // Drop index
471 if (!noddl)
472 {
473 ndbout << "Dropping index " << pkIdxName << " ";
474 if (pNdb->getDictionary()->dropIndex(pkIdxName,
475 pTab->getName()) != 0){
476 ndbout << "FAILED!" << endl;
477 ERR(pNdb->getDictionary()->getNdbError());
478 return NDBT_FAILED;
479 } else {
480 ndbout << "OK!" << endl;
481 }
482 }
483
484 return NDBT_OK;
485 }
486
487 int
runVerifyIndex(NDBT_Context * ctx,NDBT_Step * step)488 runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){
489 // Verify that data in index match
490 // table data
491 Ndb* pNdb = GETNDB(step);
492 UtilTransactions utilTrans(*ctx->getTab());
493 const int batchSize = ctx->getProperty("BatchSize", 16);
494 const int parallelism = batchSize > 240 ? 240 : batchSize;
495
496 do {
497 if (utilTrans.verifyIndex(pNdb, idxName, parallelism, true) != 0){
498 g_err << "Inconsistent index" << endl;
499 return NDBT_FAILED;
500 }
501 } while(ctx->isTestStopped() == false);
502 return NDBT_OK;
503 }
504
505 int
runTransactions1(NDBT_Context * ctx,NDBT_Step * step)506 runTransactions1(NDBT_Context* ctx, NDBT_Step* step){
507 // Verify that data in index match
508 // table data
509 Ndb* pNdb = GETNDB(step);
510 HugoTransactions hugoTrans(*ctx->getTab());
511 const int batchSize = ctx->getProperty("BatchSize", 50);
512
513 int rows = ctx->getNumRecords();
514 while (ctx->isTestStopped() == false) {
515 if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
516 g_err << "Updated table failed" << endl;
517 return NDBT_FAILED;
518 }
519
520 ctx->sync_down("PauseThreads");
521 if(ctx->isTestStopped())
522 break;
523
524 if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){
525 g_err << "Updated table failed" << endl;
526 return NDBT_FAILED;
527 }
528
529 ctx->sync_down("PauseThreads");
530 }
531 return NDBT_OK;
532 }
533
534 int
runTransactions2(NDBT_Context * ctx,NDBT_Step * step)535 runTransactions2(NDBT_Context* ctx, NDBT_Step* step){
536 // Verify that data in index match
537 // table data
538 Ndb* pNdb = GETNDB(step);
539 HugoTransactions hugoTrans(*ctx->getTab());
540 const int batchSize = ctx->getProperty("BatchSize", 50);
541
542 int rows = ctx->getNumRecords();
543 while (ctx->isTestStopped() == false) {
544 #if 1
545 if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){
546 g_err << "Index read failed" << endl;
547 return NDBT_FAILED;
548 }
549 #endif
550 ctx->sync_down("PauseThreads");
551 if(ctx->isTestStopped())
552 break;
553 #if 1
554 if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){
555 g_err << "Index update failed" << endl;
556 return NDBT_FAILED;
557 }
558 #endif
559 ctx->sync_down("PauseThreads");
560 }
561 return NDBT_OK;
562 }
563
564 int
runTransactions3(NDBT_Context * ctx,NDBT_Step * step)565 runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
566 // Verify that data in index match
567 // table data
568 Ndb* pNdb = GETNDB(step);
569 HugoTransactions hugoTrans(*ctx->getTab());
570 UtilTransactions utilTrans(*ctx->getTab());
571 const int batchSize = ctx->getProperty("BatchSize", 32);
572 const int parallel = batchSize > 240 ? 240 : batchSize;
573
574 int rows = ctx->getNumRecords();
575 while (ctx->isTestStopped() == false) {
576 if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){
577 g_err << "Load table failed" << endl;
578 return NDBT_FAILED;
579 }
580 ctx->sync_down("PauseThreads");
581 if(ctx->isTestStopped())
582 break;
583
584 if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
585 g_err << "Updated table failed" << endl;
586 return NDBT_FAILED;
587 }
588
589 ctx->sync_down("PauseThreads");
590 if(ctx->isTestStopped())
591 break;
592
593 if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){
594 g_err << "Index read failed" << endl;
595 return NDBT_FAILED;
596 }
597
598 ctx->sync_down("PauseThreads");
599 if(ctx->isTestStopped())
600 break;
601
602 if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){
603 g_err << "Index update failed" << endl;
604 return NDBT_FAILED;
605 }
606
607 ctx->sync_down("PauseThreads");
608 if(ctx->isTestStopped())
609 break;
610
611 if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){
612 g_err << "Scan updated table failed" << endl;
613 return NDBT_FAILED;
614 }
615
616 ctx->sync_down("PauseThreads");
617 if(ctx->isTestStopped())
618 break;
619
620 if(utilTrans.clearTable(pNdb, rows, parallel) != 0){
621 g_err << "Clear table failed" << endl;
622 return NDBT_FAILED;
623 }
624
625 ctx->sync_down("PauseThreads");
626 if(ctx->isTestStopped())
627 break;
628
629 int count = -1;
630 if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0)
631 return NDBT_FAILED;
632 ctx->sync_down("PauseThreads");
633 }
634 return NDBT_OK;
635 }
636
runRestarts(NDBT_Context * ctx,NDBT_Step * step)637 int runRestarts(NDBT_Context* ctx, NDBT_Step* step){
638 int result = NDBT_OK;
639 int loops = ctx->getNumLoops();
640 NDBT_TestCase* pCase = ctx->getCase();
641 NdbRestarts restarts;
642 int i = 0;
643 int timeout = 240;
644 int sync_threads = ctx->getProperty("Threads", (unsigned)0);
645
646 while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
647 if(restarts.executeRestart(ctx, "RestartRandomNodeAbort", timeout) != 0){
648 g_err << "Failed to executeRestart(" <<pCase->getName() <<")" << endl;
649 result = NDBT_FAILED;
650 break;
651 }
652 ctx->sync_up_and_wait("PauseThreads", sync_threads);
653 i++;
654 }
655 ctx->stopTest();
656 return result;
657 }
658
runCreateLoadDropIndex(NDBT_Context * ctx,NDBT_Step * step)659 int runCreateLoadDropIndex(NDBT_Context* ctx, NDBT_Step* step){
660 int loops = ctx->getNumLoops();
661 int records = ctx->getNumRecords();
662 int l = 0;
663 const NdbDictionary::Table* pTab = ctx->getTab();
664 Ndb* pNdb = GETNDB(step);
665 int result = NDBT_OK;
666 int batchSize = ctx->getProperty("BatchSize", 1);
667 int parallelism = batchSize > 240? 240: batchSize;
668 ndbout << "batchSize="<<batchSize<<endl;
669 bool logged = ctx->getProperty("LoggedIndexes", 1);
670
671 HugoTransactions hugoTrans(*pTab);
672 UtilTransactions utilTrans(*pTab);
673 AttribList attrList;
674 attrList.buildAttribList(pTab);
675
676 for (unsigned int i = 0; i < attrList.attriblist.size(); i++){
677
678 while (l < loops && result == NDBT_OK){
679
680 if ((l % 2) == 0){
681 // Create index first and then load
682
683 // Try to create index
684 if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED){
685 result = NDBT_FAILED;
686 }
687
688 // Load the table with data
689 ndbout << "Loading data after" << endl;
690 CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
691
692
693 } else {
694 // Load table then create index
695
696 // Load the table with data
697 ndbout << "Loading data before" << endl;
698 CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
699
700 // Try to create index
701 if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED)
702 result = NDBT_FAILED;
703
704 }
705
706 // Verify that data in index match
707 // table data
708 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
709
710 // Do it all...
711 ndbout <<"Doing it all"<<endl;
712 int count;
713 ndbout << " pkUpdateRecords" << endl;
714 CHECK(hugoTrans.pkUpdateRecords(pNdb, records, batchSize) == 0);
715 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
716 CHECK(hugoTrans.pkUpdateRecords(pNdb, records, batchSize) == 0);
717 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
718 ndbout << " pkDelRecords half" << endl;
719 CHECK(hugoTrans.pkDelRecords(pNdb, records/2, batchSize) == 0);
720 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
721 ndbout << " scanUpdateRecords" << endl;
722 CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2, parallelism) == 0);
723 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
724 ndbout << " clearTable" << endl;
725 CHECK(utilTrans.clearTable(pNdb, records/2, parallelism) == 0);
726 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
727 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
728 CHECK(count == 0);
729 ndbout << " loadTable" << endl;
730 CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
731 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
732 ndbout << " loadTable again" << endl;
733 CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
734 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
735 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
736 CHECK(count == records);
737
738
739 if ((l % 2) == 0){
740 // Drop index first and then clear
741
742 // Try to create index
743 if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK){
744 result = NDBT_FAILED;
745 }
746
747 // Clear table
748 ndbout << "Clearing table after" << endl;
749 CHECK(hugoTrans.clearTable(pNdb, records, parallelism) == 0);
750
751
752 } else {
753 // Clear table then drop index
754
755 //Clear table
756 ndbout << "Clearing table before" << endl;
757 CHECK(hugoTrans.clearTable(pNdb, records, parallelism) == 0);
758
759 // Try to drop index
760 if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK)
761 result = NDBT_FAILED;
762 }
763
764 ndbout << " Done!" << endl;
765 l++;
766 }
767
768 // Make sure index is dropped
769 drop_index(i, pNdb, pTab, attrList.attriblist[i]);
770
771 }
772
773 return result;
774 }
775
runInsertDelete(NDBT_Context * ctx,NDBT_Step * step)776 int runInsertDelete(NDBT_Context* ctx, NDBT_Step* step){
777 int loops = ctx->getNumLoops();
778 int records = ctx->getNumRecords();
779 const NdbDictionary::Table* pTab = ctx->getTab();
780 Ndb* pNdb = GETNDB(step);
781 int result = NDBT_OK;
782 int batchSize = ctx->getProperty("BatchSize", 1);
783 int parallelism = batchSize > 240? 240: batchSize;
784 ndbout << "batchSize="<<batchSize<<endl;
785 bool logged = ctx->getProperty("LoggedIndexes", 1);
786
787 HugoTransactions hugoTrans(*pTab);
788 UtilTransactions utilTrans(*pTab);
789
790 AttribList attrList;
791 attrList.buildAttribList(pTab);
792
793 for (unsigned int i = 0; i < attrList.attriblist.size(); i++){
794
795 Attrib* attr = attrList.attriblist[i];
796 // Create index
797 if (create_index(ctx, i, pTab, pNdb, attr, logged) == NDBT_OK){
798 int l = 1;
799 while (l <= loops && result == NDBT_OK){
800
801 CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
802 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
803 CHECK(utilTrans.clearTable(pNdb, records, parallelism) == 0);
804 CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
805 l++;
806 }
807
808 // Drop index
809 if (drop_index(i, pNdb, pTab, attr) != NDBT_OK)
810 result = NDBT_FAILED;
811 }
812 }
813
814 return result;
815 }
816
tryAddUniqueIndex(Ndb * pNdb,const NdbDictionary::Table * pTab,const char * idxName,HugoCalculator & calc,int & chosenCol)817 int tryAddUniqueIndex(Ndb* pNdb,
818 const NdbDictionary::Table* pTab,
819 const char* idxName,
820 HugoCalculator& calc,
821 int& chosenCol)
822 {
823 for(int c = 0; c < pTab->getNoOfColumns(); c++)
824 {
825 const NdbDictionary::Column* col = pTab->getColumn(c);
826
827 if (!col->getPrimaryKey() &&
828 !calc.isUpdateCol(c) &&
829 !col->getNullable() &&
830 col->getStorageType() != NDB_STORAGETYPE_DISK)
831 {
832 chosenCol = c;
833 break;
834 }
835 }
836
837 if (chosenCol == -1)
838 {
839 return 1;
840 }
841
842
843 /* Create unique index on chosen column */
844
845 const char* colName = pTab->getColumn(chosenCol)->getName();
846 ndbout << "Creating unique index :" << idxName << " on ("
847 << colName << ")" << endl;
848
849 NdbDictionary::Index idxDef(idxName);
850 idxDef.setTable(pTab->getName());
851 idxDef.setType(NdbDictionary::Index::UniqueHashIndex);
852
853 idxDef.addIndexColumn(colName);
854 idxDef.setStoredIndex(false);
855
856 if (pNdb->getDictionary()->createIndex(idxDef) != 0)
857 {
858 ndbout << "FAILED!" << endl;
859 const NdbError err = pNdb->getDictionary()->getNdbError();
860 ERR(err);
861 return -1;
862 }
863
864 return 0;
865 }
866
tryInsertUniqueRecord(NDBT_Step * step,HugoOperations & hugoOps,int & recordNum)867 int tryInsertUniqueRecord(NDBT_Step* step,
868 HugoOperations& hugoOps,
869 int& recordNum)
870 {
871 Ndb* pNdb = GETNDB(step);
872 do
873 {
874 CHECKRET(hugoOps.startTransaction(pNdb) == 0);
875 CHECKRET(hugoOps.pkInsertRecord(pNdb,
876 recordNum,
877 1, // NumRecords
878 0) // UpdatesValue
879 == 0);
880 if (hugoOps.execute_Commit(pNdb) != 0)
881 {
882 NdbError err = hugoOps.getTransaction()->getNdbError();
883 hugoOps.closeTransaction(pNdb);
884 if (err.code == 839)
885 {
886 /* Unique constraint violation, try again with
887 * different record
888 */
889 recordNum++;
890 continue;
891 }
892 else
893 {
894 ERR(err);
895 return NDBT_FAILED;
896 }
897 }
898
899 hugoOps.closeTransaction(pNdb);
900 break;
901 } while (true);
902
903 return NDBT_OK;
904 }
905
906
runConstraintDetails(NDBT_Context * ctx,NDBT_Step * step)907 int runConstraintDetails(NDBT_Context* ctx, NDBT_Step* step)
908 {
909 const NdbDictionary::Table* pTab = ctx->getTab();
910 Ndb* pNdb = GETNDB(step);
911
912 /* Steps in testcase
913 * 1) Choose a column to index - not pk or updates column
914 * 2) Insert a couple of unique rows
915 * 3) For a number of different batch sizes :
916 * i) Insert a row with a conflicting values
917 * ii) Update an existing row with a conflicting value
918 * Verify :
919 * - The correct error is received
920 * - The failing constraint is detected
921 * - The error details string is as expected.
922 */
923 HugoCalculator calc(*pTab);
924
925 /* Choose column to add unique index to */
926
927 int chosenCol = -1;
928 const char* idxName = "constraintCheck";
929
930 int rc = tryAddUniqueIndex(pNdb, pTab, idxName, calc, chosenCol);
931
932 if (rc)
933 {
934 if (rc == 1)
935 {
936 ndbout << "No suitable column in this table, skipping" << endl;
937 return NDBT_OK;
938 }
939 return NDBT_FAILED;
940 }
941
942 const NdbDictionary::Index* pIdx =
943 pNdb->getDictionary()->getIndex(idxName, pTab->getName());
944 CHECKRET(pIdx != 0);
945
946
947 /* Now insert a couple of rows */
948
949 HugoOperations hugoOps(*pTab);
950 int firstRecordNum = 0;
951 CHECKRET(tryInsertUniqueRecord(step, hugoOps, firstRecordNum) == NDBT_OK);
952 int secondRecordNum = firstRecordNum + 1;
953 CHECKRET(tryInsertUniqueRecord(step, hugoOps, secondRecordNum) == NDBT_OK);
954
955
956 /* Now we'll attempt to insert/update records
957 * in various sized batches and check the errors which
958 * are returned
959 */
960
961 int maxBatchSize = 10;
962 int recordOffset = secondRecordNum + 1;
963 char buff[NDB_MAX_TUPLE_SIZE];
964 Uint32 real_len;
965 CHECKRET(calc.calcValue(firstRecordNum, chosenCol, 0, &buff[0],
966 pTab->getColumn(chosenCol)->getSizeInBytes(),
967 &real_len) != 0);
968
969 for (int optype = 0; optype < 2; optype ++)
970 {
971 bool useInsert = (optype == 0);
972 ndbout << "Verifying constraint violation for "
973 << (useInsert?"Insert":"Update")
974 << " operations" << endl;
975
976 for (int batchSize = 1; batchSize <= maxBatchSize; batchSize++)
977 {
978 NdbTransaction* trans = pNdb->startTransaction();
979 CHECKRET(trans != 0);
980
981 for (int rows = 0; rows < batchSize; rows ++)
982 {
983 int rowId = recordOffset + rows;
984 NdbOperation* op = trans->getNdbOperation(pTab);
985 CHECKRET(op != 0);
986 if (useInsert)
987 {
988 CHECKRET(op->insertTuple() == 0);
989
990 CHECKRET(hugoOps.setValues(op, rowId, 0) == 0);
991
992 /* Now override setValue for the indexed column to cause
993 * constraint violation
994 */
995 CHECKRET(op->setValue(chosenCol, &buff[0], real_len) == 0);
996 }
997 else
998 {
999 /* Update value of 'second' row to conflict with
1000 * first
1001 */
1002 CHECKRET(op->updateTuple() == 0);
1003 CHECKRET(hugoOps.equalForRow(op, secondRecordNum) == 0);
1004
1005 CHECKRET(op->setValue(chosenCol, &buff[0], real_len) == 0);
1006 }
1007 }
1008
1009 CHECKRET(trans->execute(Commit) == -1);
1010
1011 NdbError err = trans->getNdbError();
1012
1013 ERR(err);
1014
1015 CHECKRET(err.code == 893);
1016
1017 /* Ugliness - current NdbApi puts index schema object id
1018 * as abs. value of char* in NdbError struct
1019 */
1020
1021 int idxObjId = (int) ((UintPtr) err.details - UintPtr(0));
1022 char detailsBuff[100];
1023 const char* errIdxName = NULL;
1024
1025 ndbout_c("Got details column val of %p and string of %s\n",
1026 err.details, pNdb->getNdbErrorDetail(err,
1027 &detailsBuff[0],
1028 100));
1029 if (idxObjId == pIdx->getObjectId())
1030 {
1031 /* Insert / update failed on the constraint we added */
1032 errIdxName = pIdx->getName();
1033 }
1034 else
1035 {
1036 /* We failed on a different constraint.
1037 * Some NDBT tables already have constraints (e.g. I3)
1038 * Check that the failing constraint contains our column
1039 */
1040 NdbDictionary::Dictionary::List tableIndices;
1041
1042 CHECKRET(pNdb->getDictionary()->listIndexes(tableIndices,
1043 pTab->getName()) == 0);
1044
1045 bool ok = false;
1046 for (unsigned ind = 0; ind < tableIndices.count; ind ++)
1047 {
1048 if (tableIndices.elements[ind].id == (unsigned) idxObjId)
1049 {
1050 const char* otherIdxName = tableIndices.elements[ind].name;
1051 ndbout << "Found other violated constraint : " << otherIdxName << endl;
1052 const NdbDictionary::Index* otherIndex =
1053 pNdb->getDictionary()->getIndex(otherIdxName,
1054 pTab->getName());
1055 CHECKRET(otherIndex != NULL);
1056
1057 for (unsigned col = 0; col < otherIndex->getNoOfColumns(); col++)
1058 {
1059 if (strcmp(otherIndex->getColumn(col)->getName(),
1060 pTab->getColumn(chosenCol)->getName()) == 0)
1061 {
1062 /* Found our column in the index */
1063 ok = true;
1064 errIdxName = otherIndex->getName();
1065 break;
1066 }
1067 }
1068
1069 if (ok)
1070 {
1071 ndbout << " Constraint contains unique column " << endl;
1072 break;
1073 }
1074 ndbout << " Constraint does not contain unique col - fail" << endl;
1075 CHECKRET(false);
1076 }
1077 }
1078
1079 if (!ok)
1080 {
1081 ndbout << "Did not find violated constraint" << endl;
1082 CHECKRET(false);
1083 }
1084 }
1085
1086 /* Finally verify the name returned is :
1087 * <db>/<schema>/<table>/<index>
1088 */
1089 BaseString expected;
1090
1091 expected.assfmt("%s/%s/%s/%s",
1092 pNdb->getDatabaseName(),
1093 pNdb->getSchemaName(),
1094 pTab->getName(),
1095 errIdxName);
1096
1097 CHECKRET(strcmp(expected.c_str(), &detailsBuff[0]) == 0);
1098
1099 ndbout << " OK " << endl;
1100
1101 trans->close();
1102 }
1103 }
1104
1105 return NDBT_OK;
1106 }
1107
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)1108 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
1109 int records = ctx->getNumRecords();
1110
1111 HugoTransactions hugoTrans(*ctx->getTab());
1112 int batchSize = ctx->getProperty("BatchSize", 1);
1113 if(hugoTrans.loadTable(GETNDB(step), records, batchSize) != 0){
1114 return NDBT_FAILED;
1115 }
1116 return NDBT_OK;
1117 }
1118
1119
runClearTable(NDBT_Context * ctx,NDBT_Step * step)1120 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
1121 int records = ctx->getNumRecords();
1122
1123 UtilTransactions utilTrans(*ctx->getTab());
1124 if (utilTrans.clearTable(GETNDB(step), records) != 0){
1125 return NDBT_FAILED;
1126 }
1127 return NDBT_OK;
1128 }
1129
runSystemRestart1(NDBT_Context * ctx,NDBT_Step * step)1130 int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){
1131 Ndb* pNdb = GETNDB(step);
1132 int result = NDBT_OK;
1133 int timeout = 300;
1134 Uint32 loops = ctx->getNumLoops();
1135 int records = ctx->getNumRecords();
1136 int count;
1137 NdbRestarter restarter;
1138 Uint32 i = 1;
1139
1140 UtilTransactions utilTrans(*ctx->getTab());
1141 HugoTransactions hugoTrans(*ctx->getTab());
1142 while(i<=loops && result != NDBT_FAILED){
1143
1144 ndbout << "Loop " << i << "/"<< loops <<" started" << endl;
1145 /*
1146 1. Load data
1147 2. Restart cluster and verify records
1148 3. Update records
1149 4. Restart cluster and verify records
1150 5. Delete half of the records
1151 6. Restart cluster and verify records
1152 7. Delete all records
1153 8. Restart cluster and verify records
1154 9. Insert, update, delete records
1155 10. Restart cluster and verify records
1156 11. Insert, update, delete records
1157 12. Restart cluster with error insert 5020 and verify records
1158 */
1159 ndbout << "Loading records..." << endl;
1160 CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1161 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1162
1163 ndbout << "Restarting cluster" << endl;
1164 CHECK(restarter.restartAll() == 0);
1165 CHECK(restarter.waitClusterStarted(timeout) == 0);
1166 CHECK(pNdb->waitUntilReady(timeout) == 0);
1167
1168 ndbout << "Verifying records..." << endl;
1169 CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
1170 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1171 CHECK(count == records);
1172 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1173
1174 ndbout << "Updating records..." << endl;
1175 CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1176 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1177
1178 ndbout << "Restarting cluster..." << endl;
1179 CHECK(restarter.restartAll() == 0);
1180 CHECK(restarter.waitClusterStarted(timeout) == 0);
1181 CHECK(pNdb->waitUntilReady(timeout) == 0);
1182
1183 ndbout << "Verifying records..." << endl;
1184 CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
1185 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1186 CHECK(count == records);
1187 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1188
1189 ndbout << "Deleting 50% of records..." << endl;
1190 CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
1191 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1192
1193 ndbout << "Restarting cluster..." << endl;
1194 CHECK(restarter.restartAll() == 0);
1195 CHECK(restarter.waitClusterStarted(timeout) == 0);
1196 CHECK(pNdb->waitUntilReady(timeout) == 0);
1197
1198 ndbout << "Verifying records..." << endl;
1199 CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0);
1200 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1201 CHECK(count == (records/2));
1202 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1203
1204 ndbout << "Deleting all records..." << endl;
1205 CHECK(utilTrans.clearTable(pNdb, records/2) == 0);
1206 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1207
1208 ndbout << "Restarting cluster..." << endl;
1209 CHECK(restarter.restartAll() == 0);
1210 CHECK(restarter.waitClusterStarted(timeout) == 0);
1211 CHECK(pNdb->waitUntilReady(timeout) == 0);
1212
1213 ndbout << "Verifying records..." << endl;
1214 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1215 CHECK(count == 0);
1216 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1217
1218 ndbout << "Doing it all..." << endl;
1219 CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1220 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1221 CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1222 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1223 CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
1224 CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2) == 0);
1225 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1226 CHECK(utilTrans.clearTable(pNdb, records) == 0);
1227 CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1228 CHECK(utilTrans.clearTable(pNdb, records) == 0);
1229 CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1230 CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1231 CHECK(utilTrans.clearTable(pNdb, records) == 0);
1232
1233 ndbout << "Restarting cluster..." << endl;
1234 CHECK(restarter.restartAll() == 0);
1235 CHECK(restarter.waitClusterStarted(timeout) == 0);
1236 CHECK(pNdb->waitUntilReady(timeout) == 0);
1237
1238 ndbout << "Verifying records..." << endl;
1239 CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1240 CHECK(count == 0);
1241
1242 ndbout << "Doing it all..." << endl;
1243 CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1244 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1245 CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1246 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1247 CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
1248 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1249 CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2) == 0);
1250 CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1251 CHECK(utilTrans.clearTable(pNdb, records) == 0);
1252 CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1253 CHECK(utilTrans.clearTable(pNdb, records) == 0);
1254
1255 ndbout << "Restarting cluster with error insert 5020..." << endl;
1256 CHECK(restarter.restartAll(false, true) == 0);
1257 CHECK(restarter.waitClusterNoStart(timeout) == 0);
1258 CHECK(restarter.insertErrorInAllNodes(5020) == 0);
1259 CHECK(restarter.startAll() == 0);
1260 CHECK(restarter.waitClusterStarted(timeout) == 0);
1261 CHECK(pNdb->waitUntilReady(timeout) == 0);
1262
1263 i++;
1264 }
1265
1266 ctx->stopTest();
1267 ndbout << "runSystemRestart1 finished" << endl;
1268
1269 return result;
1270 }
1271
1272 #define CHECK2(b, t) if(!b){ g_err << __LINE__ << ": " << t << endl; break;}
1273 #define CHECKOKORTIMEOUT(e, t) { int rc= (e); \
1274 if (rc != 0) { \
1275 if (rc == 266) { \
1276 g_err << "Timeout : retries left : " \
1277 << timeoutRetries \
1278 << endl; \
1279 continue; \
1280 } \
1281 g_err << __LINE__ << ": " << (t) << endl; break; \
1282 } }
1283
1284
1285 int
runMixed1(NDBT_Context * ctx,NDBT_Step * step)1286 runMixed1(NDBT_Context* ctx, NDBT_Step* step){
1287 // Verify that data in index match
1288 // table data
1289 Ndb* pNdb = GETNDB(step);
1290 HugoOperations hugoOps(*ctx->getTab());
1291
1292 /* Old, rather ineffective testcase which nonetheless passes on 6.3 */
1293
1294 do {
1295 // TC1
1296 g_err << "pkRead, indexRead, Commit" << endl;
1297 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1298 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1299 CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord");
1300 CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1301 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1302
1303 // TC1
1304 g_err << "pkRead, indexRead, Commit" << endl;
1305 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1306 CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord");
1307 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1308 CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1309 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1310
1311
1312 // TC2
1313 g_err << "pkRead, indexRead, NoCommit, Commit" << endl;
1314 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1315 CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord");
1316 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0,
1317 "indexReadRecords");
1318 CHECK2(hugoOps.execute_NoCommit(pNdb) == 0, "executeNoCommit");
1319 CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1320 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1321
1322 // TC3
1323 g_err << "pkRead, pkRead, Commit" << endl;
1324 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1325 CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords ");
1326 CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords ");
1327 CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1328 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1329
1330 // TC4
1331 g_err << "indexRead, indexRead, Commit" << endl;
1332
1333 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1334 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1335 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1336 CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1337
1338 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1339
1340 return NDBT_OK;
1341 } while(false);
1342
1343
1344 hugoOps.closeTransaction(pNdb);
1345 return NDBT_FAILED;
1346 }
1347
1348
1349
1350 int
runMixedUpdateInterleaved(Ndb * pNdb,HugoOperations & hugoOps,int outOfRangeRec,int testSize,bool commit,bool abort,int pkFailRec,int ixFailRec,bool invertFail,AbortOption ao,int whatToUpdate,int updatesValue,bool ixFirst)1351 runMixedUpdateInterleaved(Ndb* pNdb,
1352 HugoOperations& hugoOps,
1353 int outOfRangeRec,
1354 int testSize,
1355 bool commit,
1356 bool abort,
1357 int pkFailRec,
1358 int ixFailRec,
1359 bool invertFail,
1360 AbortOption ao,
1361 int whatToUpdate,
1362 int updatesValue,
1363 bool ixFirst)
1364 {
1365 Uint32 execRc= 0;
1366 if ((pkFailRec != -1) || (ixFailRec != -1))
1367 {
1368 execRc= 626;
1369 }
1370
1371 bool updateViaPk= whatToUpdate & 1;
1372 bool updateViaIx= whatToUpdate & 2;
1373
1374 int ixOpNum= (ixFirst?0:1);
1375 int pkOpNum= (ixFirst?1:0);
1376
1377 int timeoutRetries= 3;
1378
1379 while (timeoutRetries--)
1380 {
1381 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1382 for (int i=0; i < testSize; i++)
1383 {
1384 /* invertFail causes all issued reads *except* the fail record number
1385 * to fail
1386 */
1387 int indxKey= ((i == ixFailRec)^invertFail)? outOfRangeRec : i;
1388 int pkKey= ((i == pkFailRec)^invertFail)? outOfRangeRec : i;
1389
1390 for (int opNum=0; opNum < 2; opNum++)
1391 {
1392 if (opNum == ixOpNum)
1393 {
1394 if (updateViaIx)
1395 {
1396 CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, indxKey, 1, updatesValue) == 0,
1397 "indexUpdateRecord");
1398 }
1399 else
1400 {
1401 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, indxKey) == 0, "indexReadRecords");
1402 }
1403 }
1404
1405 if (opNum == pkOpNum)
1406 {
1407 if (updateViaPk)
1408 {
1409 CHECK2(hugoOps.pkUpdateRecord(pNdb, pkKey, 1, updatesValue) == 0,
1410 "pkUpdateRecord");
1411 }
1412 else
1413 {
1414 CHECK2(hugoOps.pkReadRecord(pNdb, pkKey) == 0, "pkReadRecord");
1415 }
1416 }
1417 }
1418 }
1419 if (commit)
1420 {
1421 int rc= hugoOps.execute_Commit(pNdb, ao);
1422 if (rc == 266)
1423 {
1424 /* Timeout */
1425 g_err << "Timeout : retries left=" << timeoutRetries << endl;
1426 hugoOps.closeTransaction(pNdb);
1427 continue;
1428 }
1429 CHECK2(rc == execRc, "execute_Commit");
1430 NdbError err= hugoOps.getTransaction()->getNdbError();
1431 CHECK2(err.code == execRc, "getNdbError");
1432 }
1433 else
1434 {
1435 int rc= hugoOps.execute_NoCommit(pNdb, ao);
1436 if (rc == 266)
1437 {
1438 /* Timeout */
1439 g_err << "Timeout : retries left=" << timeoutRetries << endl;
1440 hugoOps.closeTransaction(pNdb);
1441 continue;
1442 }
1443 CHECK2(rc == execRc, "execute_NoCommit");
1444 NdbError err= hugoOps.getTransaction()->getNdbError();
1445 CHECK2(err.code == execRc, "getNdbError");
1446 if (execRc && (ao == AO_IgnoreError))
1447 {
1448 /* Transaction should still be open, let's commit it */
1449 CHECK2(hugoOps.execute_Commit(pNdb, ao) == 0, "executeCommit");
1450 }
1451 else if (abort)
1452 {
1453 CHECK2(hugoOps.execute_Rollback(pNdb) == 0, "executeRollback");
1454 }
1455 }
1456 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1457
1458 return 1;
1459 }
1460
1461 hugoOps.closeTransaction(pNdb);
1462 return 0;
1463 }
1464
1465
1466
1467 int
runMixed2(NDBT_Context * ctx,NDBT_Step * step)1468 runMixed2(NDBT_Context* ctx, NDBT_Step* step){
1469 Ndb* pNdb = GETNDB(step);
1470 HugoOperations hugoOps(*ctx->getTab());
1471
1472 int numRecordsInTable= ctx->getNumRecords();
1473 const int maxTestSize= 10000;
1474 int testSize= MIN(numRecordsInTable, maxTestSize);
1475
1476 /* Avoid overloading Send Buffers */
1477 Uint32 rowSize= NdbDictionary::getRecordRowLength(ctx->getTab()->getDefaultRecord());
1478 Uint32 dataXfer= 2 * rowSize * testSize;
1479 const Uint32 MaxDataXfer= 500000; // 0.5M
1480
1481 if (dataXfer > MaxDataXfer)
1482 {
1483 testSize= MIN((int)(MaxDataXfer/rowSize), testSize);
1484 }
1485
1486 g_err << "testSize= " << testSize << endl;
1487 g_err << "rowSize= " << rowSize << endl;
1488
1489 int updatesValue= 1;
1490 const int maxTimeoutRetries= 3;
1491
1492 do {
1493 // TC0
1494 {
1495 bool ok= false;
1496 int timeoutRetries= maxTimeoutRetries;
1497 while (timeoutRetries--)
1498 {
1499 g_err << "TC0 : indexRead, pkread, Commit" << endl;
1500 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1501 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1502 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1503 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1504 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1505
1506 ok= true;
1507 break;
1508 }
1509 if (!ok) { break; };
1510 }
1511
1512
1513 // TC1
1514 {
1515 bool ok= false;
1516 int timeoutRetries= maxTimeoutRetries;
1517 while (timeoutRetries--)
1518 {
1519 g_err << "TC1 : pkRead, indexRead, Commit" << endl;
1520 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1521 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1522 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1523 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1524 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1525
1526 ok= true;
1527 break;
1528 }
1529 if (!ok) { break; };
1530 }
1531
1532 // TC2
1533 {
1534 bool ok= false;
1535 int timeoutRetries= maxTimeoutRetries;
1536 while (timeoutRetries--)
1537 {
1538 g_err << "TC2 : pkRead, indexRead, NoCommit, Commit" << endl;
1539 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1540 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1541 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0,
1542 "indexReadRecords");
1543 CHECKOKORTIMEOUT(hugoOps.execute_NoCommit(pNdb), "executeNoCommit");
1544 CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1545 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1546 ok= true;
1547 break;
1548 }
1549 if (!ok) { break; };
1550 }
1551
1552 // TC3
1553 {
1554 bool ok= false;
1555 int timeoutRetries= maxTimeoutRetries;
1556 while (timeoutRetries--)
1557 {
1558 g_err << "TC3 : pkRead, pkRead, Commit" << endl;
1559 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1560 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords ");
1561 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords ");
1562 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1563 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1564 ok= true;
1565 break;
1566 }
1567 if (!ok) { break; };
1568 }
1569
1570 // TC4
1571 {
1572 bool ok= false;
1573 int timeoutRetries= maxTimeoutRetries;
1574 while (timeoutRetries--)
1575 {
1576 g_err << "TC4 : indexRead, indexRead, Commit" << endl;
1577 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1578 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1579 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1580 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1581 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1582 ok= true;
1583 break;
1584 }
1585 if (!ok) { break; };
1586 }
1587
1588 // TC5
1589 {
1590 bool ok= false;
1591 int timeoutRetries= maxTimeoutRetries;
1592 while (timeoutRetries--)
1593 {
1594 g_err << "TC5 : indexRead, pkUpdate, Commit" << endl;
1595 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1596 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1597 CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord");
1598 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1599 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1600 ok= true;
1601 break;
1602 }
1603 if (!ok) { break; };
1604 }
1605
1606 // TC6
1607 {
1608 bool ok= false;
1609 int timeoutRetries= maxTimeoutRetries;
1610 while (timeoutRetries--)
1611 {
1612 g_err << "TC6 : pkUpdate, indexRead, Commit" << endl;
1613 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1614 CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord");
1615 CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1616 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1617 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1618 ok= true;
1619 break;
1620 }
1621 if (!ok) { break; };
1622 }
1623
1624 // TC7
1625 {
1626 bool ok= false;
1627 int timeoutRetries= maxTimeoutRetries;
1628 while (timeoutRetries--)
1629 {
1630 g_err << "TC7 : pkRead, indexUpdate, Commit" << endl;
1631 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1632 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1633 CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0,
1634 "indexReadRecords");
1635 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1636 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1637 ok= true;
1638 break;
1639 }
1640 if (!ok) { break; };
1641 }
1642
1643 // TC8
1644 {
1645 bool ok= false;
1646 int timeoutRetries= maxTimeoutRetries;
1647 while (timeoutRetries--)
1648 {
1649 g_err << "TC8 : indexUpdate, pkRead, Commit" << endl;
1650 CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1651 CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0,
1652 "indexReadRecords ");
1653 CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords ");
1654 CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1655 CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1656 ok= true;
1657 break;
1658 }
1659 if (!ok) { break; };
1660 }
1661
1662 for (int ao=0; ao < 2; ao++)
1663 {
1664 AbortOption abortOption= ao?AO_IgnoreError:AbortOnError;
1665
1666 for (int exType=0; exType < 3; exType++)
1667 {
1668 bool commit= (exType == 1);
1669 bool abort= (exType == 2);
1670
1671 const char* exTypeStr= ((exType == 0) ? "NoCommit" :
1672 (exType == 1) ? "Commit" :
1673 "Abort");
1674
1675 for (int failType= 0; failType < 4; failType++)
1676 {
1677 for (int failPos= 0; failPos < 2; failPos++)
1678 {
1679 int failRec= (failPos == 0)? 0 : testSize -1;
1680 int pkFailRec= -1;
1681 int ixFailRec= -1;
1682 if (failType)
1683 {
1684 if (failType & 1)
1685 pkFailRec= failRec;
1686 if (failType & 2)
1687 ixFailRec= failRec;
1688 }
1689
1690 for (int invFail= 0;
1691 invFail < ((failType==0)?1:2);
1692 invFail++)
1693 {
1694 bool invertFail= (invFail)?true:false;
1695 const char* failTypeStr= ((failType==0)? "None" :
1696 ((failType==1)? "Pk":
1697 ((failType==2)?"Ix": "Both")));
1698 for (int updateVia= 0; updateVia < 3; updateVia++)
1699 {
1700 const char* updateViaStr= ((updateVia == 0)? "None" :
1701 (updateVia == 1)? "Pk" :
1702 (updateVia == 2)? "Ix" :
1703 "Both");
1704 for (int updateOrder= 0; updateOrder < 2; updateOrder++)
1705 {
1706 bool updateIxFirst= (updateOrder == 0);
1707 g_err << endl
1708 << "AbortOption : " << (ao?"IgnoreError":"AbortOnError") << endl
1709 << "ExecType : " << exTypeStr << endl
1710 << "Failtype : " << failTypeStr << endl
1711 << "Failpos : " << ((failPos == 0)? "Early" : "Late") << endl
1712 << "Failure scenarios : " << (invFail?"All but one":"one") << endl
1713 << "UpdateVia : " << updateViaStr << endl
1714 << "Order : " << (updateIxFirst? "Index First" : "Pk first") << endl;
1715 bool ok= false;
1716 do
1717 {
1718 g_err << "Mixed read/update interleaved" << endl;
1719 CHECK2(runMixedUpdateInterleaved(pNdb, hugoOps, numRecordsInTable, testSize,
1720 commit, // Commit
1721 abort, // Abort
1722 pkFailRec, // PkFail
1723 ixFailRec, // IxFail
1724 invertFail, // Invertfail
1725 abortOption,
1726 updateVia,
1727 updatesValue++,
1728 updateIxFirst),
1729 "TC4");
1730
1731 ok= true;
1732 } while (false);
1733
1734 if (!ok)
1735 {
1736 hugoOps.closeTransaction(pNdb);
1737 return NDBT_FAILED;
1738 }
1739 }
1740 }
1741 }
1742 }
1743 }
1744 }
1745 }
1746
1747 return NDBT_OK;
1748 } while (false);
1749
1750 hugoOps.closeTransaction(pNdb);
1751 return NDBT_FAILED;
1752 }
1753
1754 #define check(b, e) \
1755 if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e.getNdbError() << endl; return NDBT_FAILED; }
1756
runRefreshTupleAbort(NDBT_Context * ctx,NDBT_Step * step)1757 int runRefreshTupleAbort(NDBT_Context* ctx, NDBT_Step* step){
1758 int records = ctx->getNumRecords();
1759 int loops = ctx->getNumLoops();
1760
1761 Ndb* ndb = GETNDB(step);
1762
1763 const NdbDictionary::Table& tab = *ctx->getTab();
1764
1765 for (int i=0; i < tab.getNoOfColumns(); i++)
1766 {
1767 if (tab.getColumn(i)->getStorageType() == NDB_STORAGETYPE_DISK)
1768 {
1769 g_err << "Table has disk column(s) skipping." << endl;
1770 return NDBT_OK;
1771 }
1772 }
1773
1774
1775 g_err << "Loading table." << endl;
1776 HugoTransactions hugoTrans(*ctx->getTab());
1777 check(hugoTrans.loadTable(ndb, records) == 0, hugoTrans);
1778
1779 HugoOperations hugoOps(*ctx->getTab());
1780
1781 /* Check refresh, abort sequence with an ordered index
1782 * Previously this gave bugs due to corruption of the
1783 * tuple version
1784 */
1785 while (loops--)
1786 {
1787 Uint32 numRefresh = 2 + rand() % 10;
1788
1789 g_err << "Refresh, rollback * " << numRefresh << endl;
1790
1791 while (--numRefresh)
1792 {
1793 /* Refresh, rollback */
1794 check(hugoOps.startTransaction(ndb) == 0, hugoOps);
1795 check(hugoOps.pkRefreshRecord(ndb, 0, records, 0) == 0, hugoOps);
1796 check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
1797 check(hugoOps.execute_Rollback(ndb) == 0, hugoOps);
1798 check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
1799 }
1800
1801 g_err << "Refresh, commit" << endl;
1802 /* Refresh, commit */
1803 check(hugoOps.startTransaction(ndb) == 0, hugoOps);
1804 check(hugoOps.pkRefreshRecord(ndb, 0, records, 0) == 0, hugoOps);
1805 check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
1806 check(hugoOps.execute_Commit(ndb) == 0, hugoOps);
1807 check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
1808
1809 g_err << "Update, commit" << endl;
1810 /* Update */
1811 check(hugoOps.startTransaction(ndb) == 0, hugoOps);
1812 check(hugoOps.pkUpdateRecord(ndb, 0, records, 2 + loops) == 0, hugoOps);
1813 check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
1814 check(hugoOps.execute_Commit(ndb) == 0, hugoOps);
1815 check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
1816 }
1817
1818 return NDBT_OK;
1819 }
1820
1821
1822 int
runBuildDuring(NDBT_Context * ctx,NDBT_Step * step)1823 runBuildDuring(NDBT_Context* ctx, NDBT_Step* step){
1824 // Verify that data in index match
1825 // table data
1826 const int Threads = ctx->getProperty("Threads", (Uint32)0);
1827 const int loops = ctx->getNumLoops();
1828
1829 for(int i = 0; i<loops; i++){
1830 #if 1
1831 if(createPkIndex(ctx, step) != NDBT_OK){
1832 g_err << "Failed to create index" << endl;
1833 return NDBT_FAILED;
1834 }
1835 #endif
1836
1837 if(ctx->isTestStopped())
1838 break;
1839
1840 #if 1
1841 if(createRandomIndex(ctx, step) != NDBT_OK){
1842 g_err << "Failed to create index" << endl;
1843 return NDBT_FAILED;
1844 }
1845 #endif
1846
1847 if(ctx->isTestStopped())
1848 break;
1849
1850 ctx->setProperty("pause", 1);
1851 int count = 0;
1852 for(int j = 0; count < Threads && !ctx->isTestStopped();
1853 j = (j+1) % Threads){
1854 char buf[255];
1855 sprintf(buf, "Thread%d_paused", j);
1856 int tmp = ctx->getProperty(buf, (Uint32)0);
1857 count += tmp;
1858 }
1859
1860 if(ctx->isTestStopped())
1861 break;
1862
1863 #if 1
1864 if(createPkIndex_Drop(ctx, step) != NDBT_OK){
1865 g_err << "Failed to drop index" << endl;
1866 return NDBT_FAILED;
1867 }
1868 #endif
1869
1870 if(ctx->isTestStopped())
1871 break;
1872
1873 #if 1
1874 if(createRandomIndex_Drop(ctx, step) != NDBT_OK){
1875 g_err << "Failed to drop index" << endl;
1876 return NDBT_FAILED;
1877 }
1878 #endif
1879
1880 ctx->setProperty("pause", (Uint32)0);
1881 NdbSleep_SecSleep(2);
1882 }
1883
1884 ctx->stopTest();
1885 return NDBT_OK;
1886 }
1887
1888 static NdbLockable g_lock;
1889 static int threadCounter = 0;
1890
1891 void
wait_paused(NDBT_Context * ctx,int id)1892 wait_paused(NDBT_Context* ctx, int id){
1893 if(ctx->getProperty("pause", (Uint32)0) == 1){
1894 char buf[255];
1895 sprintf(buf, "Thread%d_paused", id);
1896 ctx->setProperty(buf, 1);
1897 while(!ctx->isTestStopped() && ctx->getProperty("pause", (Uint32)0) == 1){
1898 NdbSleep_MilliSleep(250);
1899 }
1900 ctx->setProperty(buf, (Uint32)0);
1901 }
1902 }
1903
1904 int
runTransactions4(NDBT_Context * ctx,NDBT_Step * step)1905 runTransactions4(NDBT_Context* ctx, NDBT_Step* step){
1906
1907 g_lock.lock();
1908 const int ThreadId = threadCounter++;
1909 g_lock.unlock();
1910
1911 // Verify that data in index match
1912 // table data
1913 Ndb* pNdb = GETNDB(step);
1914 HugoTransactions hugoTrans(*ctx->getTab());
1915 UtilTransactions utilTrans(*ctx->getTab());
1916 const int batchSize = ctx->getProperty("BatchSize", 32);
1917 const int parallel = batchSize > 240 ? 240 : batchSize;
1918
1919 int rows = ctx->getNumRecords();
1920 while (ctx->isTestStopped() == false) {
1921 if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){
1922 g_err << "Load table failed" << endl;
1923 return NDBT_FAILED;
1924 }
1925
1926 wait_paused(ctx, ThreadId);
1927
1928 if(ctx->isTestStopped())
1929 break;
1930
1931 if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
1932 g_err << "Updated table failed" << endl;
1933 return NDBT_FAILED;
1934 }
1935
1936 wait_paused(ctx, ThreadId);
1937
1938 if(ctx->isTestStopped())
1939 break;
1940
1941 if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){
1942 g_err << "Scan updated table failed" << endl;
1943 return NDBT_FAILED;
1944 }
1945
1946 wait_paused(ctx, ThreadId);
1947
1948 if(ctx->isTestStopped())
1949 break;
1950
1951 if(utilTrans.clearTable(pNdb, rows, parallel) != 0){
1952 g_err << "Clear table failed" << endl;
1953 return NDBT_FAILED;
1954 }
1955 }
1956 return NDBT_OK;
1957 }
1958
1959 int
runUniqueNullTransactions(NDBT_Context * ctx,NDBT_Step * step)1960 runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){
1961 Ndb* pNdb = GETNDB(step);
1962
1963 bool logged = ctx->getProperty("LoggedIndexes", 1);
1964 bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
1965 NdbConnection * pTrans = 0;
1966
1967 const NdbDictionary::Table* pTab = ctx->getTab();
1968 // Create index
1969 char nullIndex[255];
1970 BaseString::snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName());
1971 if (orderedIndex)
1972 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
1973 << pkIdxName << " (";
1974 else
1975 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
1976 << pkIdxName << " (";
1977
1978 NdbDictionary::Index pIdx(pkIdxName);
1979 pIdx.setTable(pTab->getName());
1980 if (orderedIndex)
1981 pIdx.setType(NdbDictionary::Index::OrderedIndex);
1982 else
1983 pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
1984 pIdx.setStoredIndex(logged);
1985 int c;
1986 for (c = 0; c< pTab->getNoOfColumns(); c++){
1987 const NdbDictionary::Column * col = pTab->getColumn(c);
1988 if(col->getPrimaryKey()){
1989 pIdx.addIndexColumn(col->getName());
1990 ndbout << col->getName() <<" ";
1991 }
1992 }
1993
1994 int colId = -1;
1995 for (c = 0; c< pTab->getNoOfColumns(); c++){
1996 const NdbDictionary::Column * col = pTab->getColumn(c);
1997 if(col->getNullable()){
1998 pIdx.addIndexColumn(col->getName());
1999 ndbout << col->getName() <<" ";
2000 colId = c;
2001 break;
2002 }
2003 }
2004 ndbout << ") ";
2005
2006 if(colId == -1){
2007 ndbout << endl << "No nullable column found -> NDBT_FAILED" << endl;
2008 return NDBT_FAILED;
2009 }
2010
2011 bool noddl= ctx->getProperty("NoDDL");
2012 if (noddl)
2013 {
2014 const NdbDictionary::Index* idx= pNdb->
2015 getDictionary()->getIndex(pIdx.getName(), pTab->getName());
2016
2017 if (!idx)
2018 {
2019 ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
2020 ERR(pNdb->getDictionary()->getNdbError());
2021 return NDBT_FAILED;
2022 }
2023 else
2024 {
2025 // TODO : Check index definition is ok
2026 }
2027 }
2028 else
2029 {
2030 if (pNdb->getDictionary()->createIndex(pIdx) != 0){
2031 ndbout << "FAILED!" << endl;
2032 const NdbError err = pNdb->getDictionary()->getNdbError();
2033 ERR(err);
2034 return NDBT_FAILED;
2035 }
2036 }
2037
2038 int result = NDBT_OK;
2039
2040 HugoTransactions hugoTrans(*ctx->getTab());
2041 const int batchSize = ctx->getProperty("BatchSize", 50);
2042 int loops = ctx->getNumLoops();
2043 int rows = ctx->getNumRecords();
2044 while (loops-- > 0 && ctx->isTestStopped() == false) {
2045 if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
2046 g_err << "Updated table failed" << endl;
2047 result = NDBT_FAILED;
2048 goto done;
2049 }
2050 }
2051
2052 if(ctx->isTestStopped()){
2053 goto done;
2054 }
2055
2056 ctx->stopTest();
2057 while(ctx->getNoOfRunningSteps() > 1){
2058 NdbSleep_MilliSleep(100);
2059 }
2060
2061 result = NDBT_FAILED;
2062 pTrans = pNdb->startTransaction();
2063 NdbScanOperation * sOp;
2064
2065 int eof;
2066 if(!pTrans) goto done;
2067 sOp = pTrans->getNdbScanOperation(pTab->getName());
2068 if(!sOp) goto done;
2069 if(sOp->readTuples(NdbScanOperation::LM_Exclusive)) goto done;
2070 if(pTrans->execute(NoCommit) == -1) goto done;
2071 while((eof = sOp->nextResult(true)) == 0){
2072 do {
2073 NdbOperation * uOp = sOp->updateCurrentTuple();
2074 if(uOp == 0) goto done;
2075 uOp->setValue(colId, 0);
2076 } while((eof = sOp->nextResult(false)) == 0);
2077 eof = pTrans->execute(Commit);
2078 if(eof == -1) goto done;
2079 }
2080
2081 done:
2082 if(pTrans) pNdb->closeTransaction(pTrans);
2083 pNdb->getDictionary()->dropIndex(nullIndex, pTab->getName());
2084 return result;
2085 }
2086
runLQHKEYREF(NDBT_Context * ctx,NDBT_Step * step)2087 int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){
2088 int loops = ctx->getNumLoops() * 100;
2089 NdbRestarter restarter;
2090
2091 myRandom48Init((long)NdbTick_CurrentMillisecond());
2092
2093 #if 0
2094 int val = DumpStateOrd::DihMinTimeBetweenLCP;
2095 if(restarter.dumpStateAllNodes(&val, 1) != 0){
2096 g_err << "Failed to dump DihMinTimeBetweenLCP" << endl;
2097 return NDBT_FAILED;
2098 }
2099 #endif
2100
2101 for(int i = 0; i<loops && !ctx->isTestStopped(); i++){
2102 int randomId = myRandom48(restarter.getNumDbNodes());
2103 int nodeId = restarter.getDbNodeId(randomId);
2104
2105 const Uint32 error = 5031 + (i % 3);
2106
2107 if(restarter.insertErrorInNode(nodeId, error) != 0){
2108 g_err << "Failed to error insert( " << error << ") in node "
2109 << nodeId << endl;
2110 return NDBT_FAILED;
2111 }
2112 }
2113
2114 ctx->stopTest();
2115 return NDBT_OK;
2116 }
2117
2118 int
runBug21384(NDBT_Context * ctx,NDBT_Step * step)2119 runBug21384(NDBT_Context* ctx, NDBT_Step* step)
2120 {
2121 Ndb* pNdb = GETNDB(step);
2122 HugoTransactions hugoTrans(*ctx->getTab());
2123 NdbRestarter restarter;
2124
2125 int loops = ctx->getNumLoops();
2126 const int rows = ctx->getNumRecords();
2127 const int batchsize = ctx->getProperty("BatchSize", 50);
2128
2129 while (loops--)
2130 {
2131 if(restarter.insertErrorInAllNodes(8037) != 0)
2132 {
2133 g_err << "Failed to error insert(8037)" << endl;
2134 return NDBT_FAILED;
2135 }
2136
2137 if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) == 0)
2138 {
2139 g_err << "Index succeded (it should have failed" << endl;
2140 return NDBT_FAILED;
2141 }
2142
2143 if(restarter.insertErrorInAllNodes(0) != 0)
2144 {
2145 g_err << "Failed to error insert(0)" << endl;
2146 return NDBT_FAILED;
2147 }
2148
2149 if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) != 0){
2150 g_err << "Index read failed" << endl;
2151 return NDBT_FAILED;
2152 }
2153 }
2154
2155 return NDBT_OK;
2156 }
2157
2158 int
runReadIndexUntilStopped(NDBT_Context * ctx,NDBT_Step * step)2159 runReadIndexUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
2160 {
2161 Ndb* pNdb = GETNDB(step);
2162 HugoTransactions hugoTrans(*ctx->getTab());
2163 int rows = ctx->getNumRecords();
2164 while (!ctx->isTestStopped())
2165 {
2166 hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, 1);
2167 }
2168 return NDBT_OK;
2169 }
2170
2171 int
runBug25059(NDBT_Context * ctx,NDBT_Step * step)2172 runBug25059(NDBT_Context* ctx, NDBT_Step* step)
2173 {
2174 Ndb* pNdb = GETNDB(step);
2175 NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2176 const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
2177 ctx->getTab()->getName());
2178
2179 HugoOperations ops(*ctx->getTab(), idx);
2180
2181 int res = NDBT_OK;
2182 int loops = ctx->getNumLoops();
2183 const int rows = ctx->getNumRecords();
2184
2185 while (res == NDBT_OK && loops--)
2186 {
2187 ops.startTransaction(pNdb);
2188 ops.pkReadRecord(pNdb, 10 + rand() % rows, rows);
2189 int tmp;
2190 if ((tmp = ops.execute_Commit(pNdb, AO_IgnoreError)))
2191 {
2192 if (tmp == 4012)
2193 res = NDBT_FAILED;
2194 else
2195 if (ops.getTransaction()->getNdbError().code == 4012)
2196 res = NDBT_FAILED;
2197 }
2198 ops.closeTransaction(pNdb);
2199 }
2200
2201 loops = ctx->getNumLoops();
2202 while (res == NDBT_OK && loops--)
2203 {
2204 ops.startTransaction(pNdb);
2205 ops.pkUpdateRecord(pNdb, 10 + rand() % rows, rows);
2206 int tmp;
2207 int arg;
2208 switch(rand() % 2){
2209 case 0:
2210 arg = AbortOnError;
2211 break;
2212 case 1:
2213 arg = AO_IgnoreError;
2214 ndbout_c("ignore error");
2215 break;
2216 }
2217 if ((tmp = ops.execute_Commit(pNdb, (AbortOption)arg)))
2218 {
2219 if (tmp == 4012)
2220 res = NDBT_FAILED;
2221 else
2222 if (ops.getTransaction()->getNdbError().code == 4012)
2223 res = NDBT_FAILED;
2224 }
2225 ops.closeTransaction(pNdb);
2226 }
2227
2228 return res;
2229 }
2230
2231 // From 6.3.X, Unique index operations do not use
2232 // TransactionBufferMemory.
2233 // Long signal KeyInfo and AttrInfo storage exhaustion
2234 // is already tested by testLimits
2235 // Testing of segment exhaustion when accumulating from
2236 // signal trains cannot be tested from 7.0 as we cannot
2237 // generate short signal trains.
2238 // TODO : Execute testcase as part of upgrade testing -
2239 // 6.3 to 7.0?
tcSaveINDX_test(NDBT_Context * ctx,NDBT_Step * step,int inject_err)2240 int tcSaveINDX_test(NDBT_Context* ctx, NDBT_Step* step, int inject_err)
2241 {
2242 int result= NDBT_OK;
2243 Ndb* pNdb = GETNDB(step);
2244 NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2245 const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
2246 ctx->getTab()->getName());
2247
2248 HugoOperations ops(*ctx->getTab(), idx);
2249
2250 g_err << "Using INDEX: " << pkIdxName << endl;
2251
2252 NdbRestarter restarter;
2253
2254 int loops = ctx->getNumLoops();
2255 const int rows = ctx->getNumRecords();
2256
2257 for(int bs=1; bs < loops; bs++)
2258 {
2259 int c= 0;
2260 while (c++ < loops)
2261 {
2262 g_err << "BS " << bs << " LOOP #" << c << endl;
2263
2264 g_err << "inserting error on op#" << c << endl;
2265
2266 CHECK(ops.startTransaction(pNdb) == 0);
2267 for(int i=1;i<=c;i++)
2268 {
2269 if(i==c)
2270 {
2271 if(restarter.insertErrorInAllNodes(inject_err)!=0)
2272 {
2273 g_err << "**** FAILED to insert error" << endl;
2274 result= NDBT_FAILED;
2275 break;
2276 }
2277 }
2278 CHECK(ops.indexReadRecords(pNdb, pkIdxName, i,false,1) == 0);
2279 if(i%bs==0 || i==c)
2280 {
2281 if(i<c)
2282 {
2283 if(ops.execute_NoCommit(pNdb, AO_IgnoreError)!=NDBT_OK)
2284 {
2285 g_err << "**** executeNoCommit should have succeeded" << endl;
2286 result= NDBT_FAILED;
2287 }
2288 }
2289 else
2290 {
2291 if(ops.execute_NoCommit(pNdb, AO_IgnoreError)!=289)
2292 {
2293 g_err << "**** executeNoCommit should have failed with 289"
2294 << endl;
2295 result= NDBT_FAILED;
2296 }
2297 g_err << "NdbError.code= " <<
2298 ops.getTransaction()->getNdbError().code << endl;
2299 break;
2300 }
2301 }
2302 }
2303
2304 CHECK(ops.closeTransaction(pNdb) == 0);
2305
2306 if(restarter.insertErrorInAllNodes(0) != 0)
2307 {
2308 g_err << "**** Failed to error insert(0)" << endl;
2309 return NDBT_FAILED;
2310 }
2311
2312 CHECK(ops.startTransaction(pNdb) == 0);
2313 if (ops.indexReadRecords(pNdb, pkIdxName,0,0,rows) != 0){
2314 g_err << "**** Index read failed" << endl;
2315 return NDBT_FAILED;
2316 }
2317 CHECK(ops.closeTransaction(pNdb) == 0);
2318 }
2319 }
2320
2321 return result;
2322 }
2323
2324 int
runBug28804(NDBT_Context * ctx,NDBT_Step * step)2325 runBug28804(NDBT_Context* ctx, NDBT_Step* step)
2326 {
2327 return tcSaveINDX_test(ctx, step, 8052);
2328 }
2329
2330 int
runBug28804_ATTRINFO(NDBT_Context * ctx,NDBT_Step * step)2331 runBug28804_ATTRINFO(NDBT_Context* ctx, NDBT_Step* step)
2332 {
2333 return tcSaveINDX_test(ctx, step, 8051);
2334 }
2335
2336 int
runBug46069(NDBT_Context * ctx,NDBT_Step * step)2337 runBug46069(NDBT_Context* ctx, NDBT_Step* step)
2338 {
2339 HugoTransactions hugoTrans(*ctx->getTab());
2340 Ndb* pNdb = GETNDB(step);
2341 const int rows = ctx->getNumRecords();
2342 Uint32 threads = ctx->getProperty("THREADS", 12);
2343 int loops = ctx->getNumLoops();
2344
2345 ctx->getPropertyWait("STARTED", threads);
2346
2347 for (int i = 0; i<loops; i++)
2348 {
2349 ndbout << "Loop: " << i << endl;
2350 if (hugoTrans.loadTable(pNdb, rows) != 0)
2351 return NDBT_FAILED;
2352
2353 ctx->setProperty("STARTED", Uint32(0));
2354 ctx->getPropertyWait("STARTED", threads);
2355 }
2356
2357 ctx->stopTest();
2358 return NDBT_OK;
2359 }
2360
2361 int
runBug46069_pkdel(NDBT_Context * ctx,NDBT_Step * step)2362 runBug46069_pkdel(NDBT_Context* ctx, NDBT_Step* step)
2363 {
2364 HugoOperations hugoOps(*ctx->getTab());
2365 Ndb* pNdb = GETNDB(step);
2366 const int rows = ctx->getNumRecords();
2367
2368 while(!ctx->isTestStopped())
2369 {
2370 ctx->incProperty("STARTED");
2371 ctx->getPropertyWait("STARTED", Uint32(0));
2372 if (ctx->isTestStopped())
2373 break;
2374
2375 for (int i = 0; i<rows && !ctx->isTestStopped(); )
2376 {
2377 int cnt = (rows - i);
2378 if (cnt > 100)
2379 cnt = 100;
2380 cnt = 1 + (rand() % cnt);
2381 if (hugoOps.startTransaction(pNdb) != 0)
2382 {
2383 break;
2384 }
2385 hugoOps.pkDeleteRecord(pNdb, i, cnt);
2386 int res = hugoOps.execute_Commit(pNdb, AO_IgnoreError);
2387 if (res != -1)
2388 {
2389 i += cnt;
2390 }
2391 hugoOps.closeTransaction(pNdb);
2392 }
2393 }
2394
2395 return NDBT_OK;
2396 }
2397
2398 int
runBug46069_scandel(NDBT_Context * ctx,NDBT_Step * step)2399 runBug46069_scandel(NDBT_Context* ctx, NDBT_Step* step)
2400 {
2401 Ndb* pNdb = GETNDB(step);
2402 NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2403 const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
2404 ctx->getTab()->getName());
2405 if (idx == 0)
2406 {
2407 return NDBT_FAILED;
2408 }
2409 UtilTransactions hugoTrans(*ctx->getTab(), idx);
2410
2411 while(!ctx->isTestStopped())
2412 {
2413 ctx->incProperty("STARTED");
2414 ctx->getPropertyWait("STARTED", Uint32(0));
2415 if (ctx->isTestStopped())
2416 break;
2417
2418 hugoTrans.clearTable(pNdb);
2419 }
2420
2421 return NDBT_OK;
2422 }
2423
2424 int
runBug50118(NDBT_Context * ctx,NDBT_Step * step)2425 runBug50118(NDBT_Context* ctx, NDBT_Step* step)
2426 {
2427 NdbSleep_MilliSleep(500);
2428 int loops = ctx->getNumLoops();
2429 while (loops--)
2430 {
2431 createPkIndex_Drop(ctx, step);
2432 createPkIndex(ctx, step);
2433 }
2434 ctx->stopTest();
2435 return NDBT_OK;
2436 }
2437
2438 int
runTrigOverload(NDBT_Context * ctx,NDBT_Step * step)2439 runTrigOverload(NDBT_Context* ctx, NDBT_Step* step)
2440 {
2441 /* Test inserts, deletes and updates via
2442 * PK with error inserts
2443 */
2444 Ndb* pNdb = GETNDB(step);
2445 HugoOperations hugoOps(*ctx->getTab());
2446 NdbRestarter restarter;
2447
2448 unsigned numScenarios = 3;
2449 unsigned errorInserts[3] = {8085, 8086, 0};
2450 int results[3] = {218, 218, 0};
2451
2452 unsigned iterations = 50;
2453
2454 /* Insert some records */
2455 if (hugoOps.startTransaction(pNdb) ||
2456 hugoOps.pkInsertRecord(pNdb, 0, iterations) ||
2457 hugoOps.execute_Commit(pNdb))
2458 {
2459 g_err << "Failed on initial insert "
2460 << pNdb->getNdbError()
2461 << endl;
2462 return NDBT_FAILED;
2463 }
2464
2465 hugoOps.closeTransaction(pNdb);
2466
2467 for(unsigned i = 0 ; i < iterations; i++)
2468 {
2469 unsigned scenario = i % numScenarios;
2470 unsigned errorVal = errorInserts[ scenario ];
2471 g_err << "Iteration :" << i
2472 << " inserting error " << errorVal
2473 << " expecting result : " << results[scenario]
2474 << endl;
2475 restarter.insertErrorInAllNodes(errorVal);
2476 // NdbSleep_MilliSleep(500); // Error insert latency?
2477
2478 CHECKRET(hugoOps.startTransaction(pNdb) == 0);
2479
2480 CHECKRET(hugoOps.pkInsertRecord(pNdb, iterations + i, 1) == 0);
2481
2482 hugoOps.execute_Commit(pNdb);
2483
2484 int errorCode = hugoOps.getTransaction()->getNdbError().code;
2485
2486 if (errorCode != results[scenario])
2487 {
2488 g_err << "For Insert in scenario " << scenario
2489 << " expected code " << results[scenario]
2490 << " but got " << hugoOps.getTransaction()->getNdbError()
2491 << endl;
2492 return NDBT_FAILED;
2493 }
2494
2495 hugoOps.closeTransaction(pNdb);
2496
2497 CHECKRET(hugoOps.startTransaction(pNdb) == 0);
2498
2499 CHECKRET(hugoOps.pkUpdateRecord(pNdb, i, 1, iterations) == 0);
2500
2501 hugoOps.execute_Commit(pNdb);
2502
2503 errorCode = hugoOps.getTransaction()->getNdbError().code;
2504
2505 if (errorCode != results[scenario])
2506 {
2507 g_err << "For Update in scenario " << scenario
2508 << " expected code " << results[scenario]
2509 << " but got " << hugoOps.getTransaction()->getNdbError()
2510 << endl;
2511 return NDBT_FAILED;
2512 }
2513
2514 hugoOps.closeTransaction(pNdb);
2515
2516 CHECKRET(hugoOps.startTransaction(pNdb) == 0);
2517
2518 CHECKRET(hugoOps.pkDeleteRecord(pNdb, i, 1) == 0);
2519
2520 hugoOps.execute_Commit(pNdb);
2521
2522 errorCode = hugoOps.getTransaction()->getNdbError().code;
2523
2524 if (errorCode != results[scenario])
2525 {
2526 g_err << "For Delete in scenario " << scenario
2527 << " expected code " << results[scenario]
2528 << " but got " << hugoOps.getTransaction()->getNdbError()
2529 << endl;
2530 return NDBT_FAILED;
2531 }
2532
2533 hugoOps.closeTransaction(pNdb);
2534
2535 }
2536
2537 restarter.insertErrorInAllNodes(0);
2538
2539 return NDBT_OK;
2540 }
2541
2542 int
runClearError(NDBT_Context * ctx,NDBT_Step * step)2543 runClearError(NDBT_Context* ctx, NDBT_Step* step)
2544 {
2545 NdbRestarter restarter;
2546
2547 restarter.insertErrorInAllNodes(0);
2548
2549 return NDBT_OK;
2550 }
2551
2552 // bug#56829
2553
2554 #undef CHECK2 // previous no good
2555 #define CHECK2(b, e) \
2556 if (!(b)) { \
2557 g_err << "ERR: " << #b << " failed at line " << __LINE__ \
2558 << ": " << e << endl; \
2559 result = NDBT_FAILED; \
2560 break; \
2561 }
2562
2563 static int
get_data_memory_pages(NdbMgmHandle h,NdbNodeBitmask dbmask,int * pages_out)2564 get_data_memory_pages(NdbMgmHandle h, NdbNodeBitmask dbmask, int* pages_out)
2565 {
2566 int result = NDBT_OK;
2567 int pages = 0;
2568
2569 while (1)
2570 {
2571 // sends dump 1000 and retrieves all replies
2572 ndb_mgm_events* e = 0;
2573 CHECK2((e = ndb_mgm_dump_events(h, NDB_LE_MemoryUsage, 0, 0)) != 0, ndb_mgm_get_latest_error_msg(h));
2574
2575 // sum up pages (also verify sanity)
2576 for (int i = 0; i < e->no_of_events; i++)
2577 {
2578 ndb_logevent* le = &e->events[i];
2579 CHECK2(le->type == NDB_LE_MemoryUsage, "bad event type " << le->type);
2580 const ndb_logevent_MemoryUsage* lem = &le->MemoryUsage;
2581 if (lem->block != DBTUP)
2582 continue;
2583 int nodeId = le->source_nodeid;
2584 CHECK2(dbmask.get(nodeId), "duplicate event from node " << nodeId);
2585 dbmask.clear(nodeId);
2586 pages += lem->pages_used;
2587 g_info << "i:" << i << " node:" << le->source_nodeid << " pages:" << lem->pages_used << endl;
2588 }
2589 free(e);
2590 CHECK2(result == NDBT_OK, "failed");
2591
2592 char buf[NdbNodeBitmask::TextLength + 1];
2593 CHECK2(dbmask.isclear(), "no response from nodes " << dbmask.getText(buf));
2594 break;
2595 }
2596
2597 *pages_out = pages;
2598 return result;
2599 }
2600
2601 int
runBug56829(NDBT_Context * ctx,NDBT_Step * step)2602 runBug56829(NDBT_Context* ctx, NDBT_Step* step)
2603 {
2604 Ndb* pNdb = GETNDB(step);
2605 NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
2606 const int loops = ctx->getNumLoops();
2607 int result = NDBT_OK;
2608 const NdbDictionary::Table tab(*ctx->getTab());
2609 const int rows = ctx->getNumRecords();
2610 const char* mgm = 0;//XXX ctx->getRemoteMgm();
2611
2612 char tabname[100];
2613 strcpy(tabname, tab.getName());
2614 char indname[100];
2615 strcpy(indname, tabname);
2616 strcat(indname, "X1");
2617
2618 (void)pDic->dropTable(tabname);
2619
2620 NdbMgmHandle h = 0;
2621 NdbNodeBitmask dbmask;
2622 // entry n marks if row with PK n exists
2623 char* rowmask = new char [rows];
2624 memset(rowmask, 0, rows);
2625 int loop = 0;
2626 while (loop < loops)
2627 {
2628 CHECK2(rows > 0, "rows must be != 0");
2629 g_info << "loop " << loop << "<" << loops << endl;
2630
2631 // at first loop connect to mgm
2632 if (loop == 0)
2633 {
2634 CHECK2((h = ndb_mgm_create_handle()) != 0, "mgm: failed to create handle");
2635 CHECK2(ndb_mgm_set_connectstring(h, mgm) == 0, ndb_mgm_get_latest_error_msg(h));
2636 CHECK2(ndb_mgm_connect(h, 0, 0, 0) == 0, ndb_mgm_get_latest_error_msg(h));
2637 g_info << "mgm: connected to " << (mgm ? mgm : "default") << endl;
2638
2639 // make bitmask of DB nodes
2640 dbmask.clear();
2641 ndb_mgm_cluster_state* cs = 0;
2642 CHECK2((cs = ndb_mgm_get_status(h)) != 0, ndb_mgm_get_latest_error_msg(h));
2643 for (int j = 0; j < cs->no_of_nodes; j++)
2644 {
2645 ndb_mgm_node_state* ns = &cs->node_states[j];
2646 if (ns->node_type == NDB_MGM_NODE_TYPE_NDB)
2647 {
2648 CHECK2(ns->node_status == NDB_MGM_NODE_STATUS_STARTED, "node " << ns->node_id << " not started status " << ns->node_status);
2649 CHECK2(!dbmask.get(ns->node_id), "duplicate node id " << ns->node_id);
2650 dbmask.set(ns->node_id);
2651 g_info << "added DB node " << ns->node_id << endl;
2652 }
2653 }
2654 free(cs);
2655 CHECK2(result == NDBT_OK, "some DB nodes are not started");
2656 CHECK2(!dbmask.isclear(), "found no DB nodes");
2657 }
2658
2659 // data memory pages after following events
2660 // 0-initial 1,2-create table,index 3-load 4-delete 5,6-drop index,table
2661 int pages[7];
2662
2663 // initial
2664 CHECK2(get_data_memory_pages(h, dbmask, &pages[0]) == NDBT_OK, "failed");
2665 g_info << "initial pages " << pages[0] << endl;
2666
2667 // create table
2668 g_info << "create table " << tabname << endl;
2669 const NdbDictionary::Table* pTab = 0;
2670 CHECK2(pDic->createTable(tab) == 0, pDic->getNdbError());
2671 CHECK2((pTab = pDic->getTable(tabname)) != 0, pDic->getNdbError());
2672 CHECK2(get_data_memory_pages(h, dbmask, &pages[1]) == NDBT_OK, "failed");
2673 g_info << "create table pages " << pages[1] << endl;
2674
2675 // choice of index attributes is not relevant to this bug
2676 // choose one non-PK updateable column
2677 NdbDictionary::Index ind;
2678 ind.setName(indname);
2679 ind.setTable(tabname);
2680 ind.setType(NdbDictionary::Index::OrderedIndex);
2681 ind.setLogging(false);
2682 {
2683 HugoCalculator calc(*pTab);
2684 for (int j = 0; j < pTab->getNoOfColumns(); j++)
2685 {
2686 const NdbDictionary::Column* col = pTab->getColumn(j);
2687 if (col->getPrimaryKey() || calc.isUpdateCol(j))
2688 continue;
2689 //CHARSET_INFO* cs = col->getCharset();
2690 if (NdbSqlUtil::check_column_for_ordered_index(col->getType(), col->getCharset()) == 0)
2691 {
2692 ind.addColumn(*col);
2693 break;
2694 }
2695 }
2696 }
2697 CHECK2(ind.getNoOfColumns() == 1, "cannot use table " << tabname);
2698
2699 // create index
2700 g_info << "create index " << indname << " on " << ind.getColumn(0)->getName() << endl;
2701 const NdbDictionary::Index* pInd = 0;
2702 CHECK2(pDic->createIndex(ind, *pTab) == 0, pDic->getNdbError());
2703 CHECK2((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError());
2704 CHECK2(get_data_memory_pages(h, dbmask, &pages[2]) == NDBT_OK, "failed");
2705 g_info << "create index pages " << pages[2] << endl;
2706
2707 HugoTransactions trans(*pTab);
2708
2709 // load all records
2710 g_info << "load records" << endl;
2711 CHECK2(trans.loadTable(pNdb, rows) == 0, trans.getNdbError());
2712 memset(rowmask, 1, rows);
2713 CHECK2(get_data_memory_pages(h, dbmask, &pages[3]) == NDBT_OK, "failed");
2714 g_info << "load records pages " << pages[3] << endl;
2715
2716 // test index with random ops
2717 g_info << "test index ops" << endl;
2718 {
2719 HugoOperations ops(*pTab);
2720 for (int i = 0; i < rows; i++)
2721 {
2722 CHECK2(ops.startTransaction(pNdb) == 0, ops.getNdbError());
2723 for (int j = 0; j < 32; j++)
2724 {
2725 int n = rand() % rows;
2726 if (!rowmask[n])
2727 {
2728 CHECK2(ops.pkInsertRecord(pNdb, n) == 0, ops.getNdbError());
2729 rowmask[n] = 1;
2730 }
2731 else if (rand() % 2 == 0)
2732 {
2733 CHECK2(ops.pkDeleteRecord(pNdb, n) == 0, ops.getNdbError());
2734 rowmask[n] = 0;
2735 }
2736 else
2737 {
2738 CHECK2(ops.pkUpdateRecord(pNdb, n) == 0, ops.getNdbError());
2739 }
2740 }
2741 CHECK2(result == NDBT_OK, "index ops batch failed");
2742 CHECK2(ops.execute_Commit(pNdb) == 0, ops.getNdbError());
2743 ops.closeTransaction(pNdb);
2744 }
2745 CHECK2(result == NDBT_OK, "index ops failed");
2746 }
2747
2748 // delete all records
2749 g_info << "delete records" << endl;
2750 CHECK2(trans.clearTable(pNdb) == 0, trans.getNdbError());
2751 memset(rowmask, 0, rows);
2752 CHECK2(get_data_memory_pages(h, dbmask, &pages[4]) == NDBT_OK, "failed");
2753 g_info << "delete records pages " << pages[4] << endl;
2754
2755 // drop index
2756 g_info << "drop index" << endl;
2757 CHECK2(pDic->dropIndex(indname, tabname) == 0, pDic->getNdbError());
2758 CHECK2(get_data_memory_pages(h, dbmask, &pages[5]) == NDBT_OK, "failed");
2759 g_info << "drop index pages " << pages[5] << endl;
2760
2761 // drop table
2762 g_info << "drop table" << endl;
2763 CHECK2(pDic->dropTable(tabname) == 0, pDic->getNdbError());
2764 CHECK2(get_data_memory_pages(h, dbmask, &pages[6]) == NDBT_OK, "failed");
2765 g_info << "drop table pages " << pages[6] << endl;
2766
2767 // verify
2768 CHECK2(pages[1] == pages[0], "pages after create table " << pages[1]
2769 << " not == initial pages " << pages[0]);
2770 CHECK2(pages[2] == pages[0], "pages after create index " << pages[2]
2771 << " not == initial pages " << pages[0]);
2772 CHECK2(pages[3] > pages[0], "pages after load " << pages[3]
2773 << " not > initial pages " << pages[0]);
2774 CHECK2(pages[4] == pages[0], "pages after delete " << pages[4]
2775 << " not == initial pages " << pages[0]);
2776 CHECK2(pages[5] == pages[0], "pages after drop index " << pages[5]
2777 << " not == initial pages " << pages[0]);
2778 CHECK2(pages[6] == pages[0], "pages after drop table " << pages[6]
2779 << " not == initial pages " << pages[0]);
2780
2781 loop++;
2782
2783 // at last loop disconnect from mgm
2784 if (loop == loops)
2785 {
2786 CHECK2(ndb_mgm_disconnect(h) == 0, ndb_mgm_get_latest_error_msg(h));
2787 ndb_mgm_destroy_handle(&h);
2788 g_info << "mgm: disconnected" << endl;
2789 }
2790 }
2791 delete [] rowmask;
2792
2793 return result;
2794 }
2795
2796 #define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
2797
2798 int
runBug12315582(NDBT_Context * ctx,NDBT_Step * step)2799 runBug12315582(NDBT_Context* ctx, NDBT_Step* step)
2800 {
2801 const NdbDictionary::Table * pTab = ctx->getTab();
2802 Ndb* pNdb = GETNDB(step);
2803 NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2804
2805 const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
2806 CHK_RET_FAILED(pIdx != 0);
2807
2808 const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2809 CHK_RET_FAILED(pRowRecord != 0);
2810 const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
2811 CHK_RET_FAILED(pIdxRecord != 0);
2812
2813 const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2814 Uint8 * pRow = new Uint8[len];
2815 bzero(pRow, len);
2816
2817 HugoCalculator calc(* pTab);
2818 calc.equalForRow(pRow, pRowRecord, 0);
2819
2820 NdbTransaction* pTrans = pNdb->startTransaction();
2821 CHK_RET_FAILED(pTrans != 0);
2822
2823 const NdbOperation * pOp[2] = { 0, 0 };
2824 for (Uint32 i = 0; i<2; i++)
2825 {
2826 NdbInterpretedCode code;
2827 if (i == 0)
2828 code.interpret_exit_ok();
2829 else
2830 code.interpret_exit_nok();
2831
2832 code.finalise();
2833
2834 NdbOperation::OperationOptions opts;
2835 bzero(&opts, sizeof(opts));
2836 opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
2837 opts.interpretedCode = &code;
2838
2839 pOp[i] = pTrans->readTuple(pIdxRecord, (char*)pRow,
2840 pRowRecord, (char*)pRow,
2841 NdbOperation::LM_Read,
2842 0,
2843 &opts,
2844 sizeof(opts));
2845 CHK_RET_FAILED(pOp[i]);
2846 }
2847
2848 int res = pTrans->execute(Commit, AO_IgnoreError);
2849
2850 CHK_RET_FAILED(res == 0);
2851 CHK_RET_FAILED(pOp[0]->getNdbError().code == 0);
2852 CHK_RET_FAILED(pOp[1]->getNdbError().code != 0);
2853
2854 delete [] pRow;
2855
2856 return NDBT_OK;
2857 }
2858
2859 int
runBug60851(NDBT_Context * ctx,NDBT_Step * step)2860 runBug60851(NDBT_Context* ctx, NDBT_Step* step)
2861 {
2862 const NdbDictionary::Table * pTab = ctx->getTab();
2863 Ndb* pNdb = GETNDB(step);
2864 NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2865
2866 const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
2867 CHK_RET_FAILED(pIdx != 0);
2868
2869 const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2870 CHK_RET_FAILED(pRowRecord != 0);
2871 const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
2872 CHK_RET_FAILED(pIdxRecord != 0);
2873
2874 const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2875 Uint8 * pRow = new Uint8[len];
2876
2877 NdbTransaction* pTrans = pNdb->startTransaction();
2878 CHK_RET_FAILED(pTrans != 0);
2879
2880 const NdbOperation * pOp[3] = { 0, 0, 0};
2881 for (Uint32 i = 0; i<3; i++)
2882 {
2883 NdbInterpretedCode code;
2884 if (i == 1)
2885 code.interpret_exit_nok();
2886 else
2887 code.interpret_exit_ok();
2888
2889 code.finalise();
2890
2891 bzero(pRow, len);
2892 HugoCalculator calc(* pTab);
2893 calc.equalForRow(pRow, pRowRecord, i);
2894
2895 NdbOperation::OperationOptions opts;
2896 bzero(&opts, sizeof(opts));
2897 opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
2898 opts.interpretedCode = &code;
2899
2900 pOp[i] = pTrans->deleteTuple(pIdxRecord, (char*)pRow,
2901 pRowRecord, (char*)pRow,
2902 0,
2903 &opts,
2904 sizeof(opts));
2905 CHK_RET_FAILED(pOp[i]);
2906 }
2907
2908 int res = pTrans->execute(Commit, AO_IgnoreError);
2909
2910 CHK_RET_FAILED(res == 0);
2911 CHK_RET_FAILED(pOp[0]->getNdbError().code == 0);
2912 CHK_RET_FAILED(pOp[1]->getNdbError().code != 0);
2913 CHK_RET_FAILED(pOp[2]->getNdbError().code == 0);
2914
2915 delete [] pRow;
2916
2917 return NDBT_OK;
2918 }
2919
2920 static
2921 const int
2922 deferred_errors[] = {
2923 5064, 0,
2924 5065, 0,
2925 5066, 0,
2926 5067, 0,
2927 5068, 0,
2928 5069, 0,
2929 5070, 0,
2930 5071, 0,
2931 5072, 1,
2932 8090, 0,
2933 8091, 0,
2934 8092, 2, // connected tc
2935 0, 0 // trailer
2936 };
2937
2938 int
runTestDeferredError(NDBT_Context * ctx,NDBT_Step * step)2939 runTestDeferredError(NDBT_Context* ctx, NDBT_Step* step)
2940 {
2941 NdbRestarter res;
2942 Ndb* pNdb = GETNDB(step);
2943 const NdbDictionary::Table* pTab = ctx->getTab();
2944
2945 const int rows = ctx->getNumRecords();
2946
2947 const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2948 CHK_RET_FAILED(pRowRecord != 0);
2949
2950 const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2951 Uint8 * pRow = new Uint8[len];
2952
2953 for (int i = 0; deferred_errors[i] != 0; i += 2)
2954 {
2955 const int errorno = deferred_errors[i];
2956 const int nodefail = deferred_errors[i+1];
2957
2958 for (int j = 0; j<3; j++)
2959 {
2960 NdbTransaction* pTrans = pNdb->startTransaction();
2961 CHK_RET_FAILED(pTrans != 0);
2962
2963 int nodeId =
2964 nodefail == 0 ? 0 :
2965 nodefail == 1 ? res.getNode(NdbRestarter::NS_RANDOM) :
2966 nodefail == 2 ? pTrans->getConnectedNodeId() :
2967 0;
2968
2969 ndbout_c("errorno: %u(nf: %u - %u) j: %u : %s", errorno,
2970 nodefail, nodeId, j,
2971 j == 0 ? "test before error insert" :
2972 j == 1 ? "test with error insert" :
2973 j == 2 ? "test after error insert" :
2974 "");
2975 if (j == 0 || j == 2)
2976 {
2977 // First time succeed
2978 // Last time succeed
2979 }
2980 else if (nodefail == 0)
2981 {
2982 CHK_RET_FAILED(res.insertErrorInAllNodes(errorno) == 0);
2983 }
2984 else
2985 {
2986 int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2987 CHK_RET_FAILED(res.dumpStateOneNode(nodeId, val2, 2) == 0);
2988 CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
2989 }
2990
2991 for (int rowNo = 0; rowNo < 100; rowNo++)
2992 {
2993 int rowId = rand() % rows;
2994 bzero(pRow, len);
2995
2996 HugoCalculator calc(* pTab);
2997 calc.setValues(pRow, pRowRecord, rowId, rand());
2998
2999 NdbOperation::OperationOptions opts;
3000 bzero(&opts, sizeof(opts));
3001 opts.optionsPresent =
3002 NdbOperation::OperationOptions::OO_DEFERRED_CONSTAINTS;
3003
3004 const NdbOperation * pOp = pTrans->updateTuple(pRowRecord, (char*)pRow,
3005 pRowRecord, (char*)pRow,
3006 0,
3007 &opts,
3008 sizeof(opts));
3009 CHK_RET_FAILED(pOp != 0);
3010 }
3011
3012 int result = pTrans->execute(Commit, AO_IgnoreError);
3013 if (j == 0 || j == 2)
3014 {
3015 CHK_RET_FAILED(result == 0);
3016 }
3017 else
3018 {
3019 CHK_RET_FAILED(result != 0);
3020 }
3021 pTrans->close();
3022
3023
3024 if (j == 0 || j == 2)
3025 {
3026 }
3027 else
3028 {
3029 if (nodefail)
3030 {
3031 ndbout_c(" waiting for %u to enter not-started", nodeId);
3032 // Wait for a node to enter not-started
3033 CHK_RET_FAILED(res.waitNodesNoStart(&nodeId, 1) == 0);
3034
3035 ndbout_c(" starting all");
3036 CHK_RET_FAILED(res.startAll() == 0);
3037 ndbout_c(" wait cluster started");
3038 CHK_RET_FAILED(res.waitClusterStarted() == 0);
3039 ndbout_c(" cluster started");
3040 }
3041 CHK_RET_FAILED(res.insertErrorInAllNodes(0) == 0);
3042 }
3043 }
3044 }
3045
3046 delete [] pRow;
3047
3048 return NDBT_OK;
3049 }
3050
3051 int
runMixedDML(NDBT_Context * ctx,NDBT_Step * step)3052 runMixedDML(NDBT_Context* ctx, NDBT_Step* step)
3053 {
3054 Ndb* pNdb = GETNDB(step);
3055 const NdbDictionary::Table* pTab = ctx->getTab();
3056
3057 unsigned seed = (unsigned)NdbTick_CurrentMillisecond();
3058
3059 const int rows = ctx->getNumRecords();
3060 const int loops = 10 * ctx->getNumLoops();
3061 const int until_stopped = ctx->getProperty("UntilStopped");
3062 const int deferred = ctx->getProperty("Deferred");
3063 const int batch = ctx->getProperty("Batch", Uint32(50));
3064
3065 const NdbRecord * pRowRecord = pTab->getDefaultRecord();
3066 CHK_RET_FAILED(pRowRecord != 0);
3067
3068 const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
3069 Uint8 * pRow = new Uint8[len];
3070
3071 int count_ok = 0;
3072 int count_failed = 0;
3073 for (int i = 0; i < loops || (until_stopped && !ctx->isTestStopped()); i++)
3074 {
3075 NdbTransaction* pTrans = pNdb->startTransaction();
3076 CHK_RET_FAILED(pTrans != 0);
3077
3078 int lastrow = 0;
3079 int result = 0;
3080 for (int rowNo = 0; rowNo < batch; rowNo++)
3081 {
3082 int left = rows - lastrow;
3083 int rowId = lastrow;
3084 if (left)
3085 {
3086 rowId += ndb_rand_r(&seed) % (left / 10 + 1);
3087 }
3088 else
3089 {
3090 break;
3091 }
3092 lastrow = rowId;
3093
3094 bzero(pRow, len);
3095
3096 HugoCalculator calc(* pTab);
3097 calc.setValues(pRow, pRowRecord, rowId, rand());
3098
3099 NdbOperation::OperationOptions opts;
3100 bzero(&opts, sizeof(opts));
3101 if (deferred)
3102 {
3103 opts.optionsPresent =
3104 NdbOperation::OperationOptions::OO_DEFERRED_CONSTAINTS;
3105 }
3106
3107 const NdbOperation* pOp = 0;
3108 switch(ndb_rand_r(&seed) % 3){
3109 case 0:
3110 pOp = pTrans->writeTuple(pRowRecord, (char*)pRow,
3111 pRowRecord, (char*)pRow,
3112 0,
3113 &opts,
3114 sizeof(opts));
3115 break;
3116 case 1:
3117 pOp = pTrans->deleteTuple(pRowRecord, (char*)pRow,
3118 pRowRecord, (char*)pRow,
3119 0,
3120 &opts,
3121 sizeof(opts));
3122 break;
3123 case 2:
3124 pOp = pTrans->updateTuple(pRowRecord, (char*)pRow,
3125 pRowRecord, (char*)pRow,
3126 0,
3127 &opts,
3128 sizeof(opts));
3129 break;
3130 }
3131 CHK_RET_FAILED(pOp != 0);
3132 result = pTrans->execute(NoCommit, AO_IgnoreError);
3133 if (result != 0)
3134 {
3135 goto found_error;
3136 }
3137 }
3138
3139 result = pTrans->execute(Commit, AO_IgnoreError);
3140 if (result != 0)
3141 {
3142 found_error:
3143 count_failed++;
3144 NdbError err = pTrans->getNdbError();
3145 ndbout << err << endl;
3146 CHK_RET_FAILED(err.code == 1235 ||
3147 err.code == 1236 ||
3148 err.code == 5066 ||
3149 err.status == NdbError::TemporaryError ||
3150 err.classification == NdbError::NoDataFound ||
3151 err.classification == NdbError::ConstraintViolation);
3152 }
3153 else
3154 {
3155 count_ok++;
3156 }
3157 pTrans->close();
3158 }
3159
3160 ndbout_c("count_ok: %d count_failed: %d",
3161 count_ok, count_failed);
3162 delete [] pRow;
3163
3164 return NDBT_OK;
3165 }
3166
3167 int
runDeferredError(NDBT_Context * ctx,NDBT_Step * step)3168 runDeferredError(NDBT_Context* ctx, NDBT_Step* step)
3169 {
3170 NdbRestarter res;
3171
3172 for (int l = 0; l<ctx->getNumLoops() && !ctx->isTestStopped(); l++)
3173 {
3174 for (int i = 0; deferred_errors[i] != 0 && !ctx->isTestStopped(); i += 2)
3175 {
3176 const int errorno = deferred_errors[i];
3177 const int nodefail = deferred_errors[i+1];
3178
3179 int nodeId = res.getNode(NdbRestarter::NS_RANDOM);
3180
3181 ndbout_c("errorno: %u (nf: %u - %u)",
3182 errorno,
3183 nodefail, nodeId);
3184
3185 if (nodefail == 0)
3186 {
3187 CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3188 NdbSleep_MilliSleep(300);
3189 CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3190 }
3191 else
3192 {
3193 int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
3194 CHK_RET_FAILED(res.dumpStateOneNode(nodeId, val2, 2) == 0);
3195 CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3196 ndbout_c(" waiting for %u to enter not-started", nodeId);
3197 // Wait for a node to enter not-started
3198 CHK_RET_FAILED(res.waitNodesNoStart(&nodeId, 1) == 0);
3199
3200 ndbout_c(" starting all");
3201 CHK_RET_FAILED(res.startAll() == 0);
3202 ndbout_c(" wait cluster started");
3203 CHK_RET_FAILED(res.waitClusterStarted() == 0);
3204 ndbout_c(" cluster started");
3205 }
3206 }
3207 }
3208
3209 ctx->stopTest();
3210 return NDBT_OK;
3211 }
3212
3213 NDBT_TESTSUITE(testIndex);
3214 TESTCASE("CreateAll",
3215 "Test that we can create all various indexes on each table\n"
3216 "Then drop the indexes\n"){
3217 INITIALIZER(runCreateIndexes);
3218 }
3219 TESTCASE("CreateAll_O",
3220 "Test that we can create all various indexes on each table\n"
3221 "Then drop the indexes\n"){
3222 TC_PROPERTY("OrderedIndex", 1);
3223 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3224 INITIALIZER(runCreateIndexes);
3225 }
3226 TESTCASE("InsertDeleteGentle",
3227 "Create one index, then perform insert and delete in the table\n"
3228 "loop number of times. Use batch size 1."){
3229 TC_PROPERTY("BatchSize", 1);
3230 INITIALIZER(runInsertDelete);
3231 FINALIZER(runClearTable);
3232 }
3233 TESTCASE("InsertDeleteGentle_O",
3234 "Create one index, then perform insert and delete in the table\n"
3235 "loop number of times. Use batch size 1."){
3236 TC_PROPERTY("OrderedIndex", 1);
3237 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3238 TC_PROPERTY("BatchSize", 1);
3239 INITIALIZER(runInsertDelete);
3240 FINALIZER(runClearTable);
3241 }
3242 TESTCASE("InsertDelete",
3243 "Create one index, then perform insert and delete in the table\n"
3244 "loop number of times. Use batchsize 512 to stress db more"){
3245 TC_PROPERTY("BatchSize", 512);
3246 INITIALIZER(runInsertDelete);
3247 FINALIZER(runClearTable);
3248
3249 }
3250 TESTCASE("InsertDelete_O",
3251 "Create one index, then perform insert and delete in the table\n"
3252 "loop number of times. Use batchsize 512 to stress db more"){
3253 TC_PROPERTY("OrderedIndex", 1);
3254 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3255 TC_PROPERTY("BatchSize", 512);
3256 INITIALIZER(runInsertDelete);
3257 FINALIZER(runClearTable);
3258
3259 }
3260 TESTCASE("CreateLoadDropGentle",
3261 "Try to create, drop and load various indexes \n"
3262 "on table loop number of times.Usa batch size 1.\n"){
3263 TC_PROPERTY("BatchSize", 1);
3264 INITIALIZER(runCreateLoadDropIndex);
3265 }
3266 TESTCASE("CreateLoadDropGentle_O",
3267 "Try to create, drop and load various indexes \n"
3268 "on table loop number of times.Usa batch size 1.\n"){
3269 TC_PROPERTY("OrderedIndex", 1);
3270 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3271 TC_PROPERTY("BatchSize", 1);
3272 INITIALIZER(runCreateLoadDropIndex);
3273 }
3274 TESTCASE("CreateLoadDrop",
3275 "Try to create, drop and load various indexes \n"
3276 "on table loop number of times. Use batchsize 512 to stress db more\n"){
3277 TC_PROPERTY("BatchSize", 512);
3278 INITIALIZER(runCreateLoadDropIndex);
3279 }
3280 TESTCASE("CreateLoadDrop_O",
3281 "Try to create, drop and load various indexes \n"
3282 "on table loop number of times. Use batchsize 512 to stress db more\n"){
3283 TC_PROPERTY("OrderedIndex", 1);
3284 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3285 TC_PROPERTY("BatchSize", 512);
3286 INITIALIZER(runCreateLoadDropIndex);
3287 }
3288 TESTCASE("NFNR1",
3289 "Test that indexes are correctly maintained during node fail and node restart"){
3290 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3291 TC_PROPERTY("PauseThreads", 2);
3292 INITIALIZER(runClearTable);
3293 INITIALIZER(createRandomIndex);
3294 INITIALIZER(runLoadTable);
3295 STEP(runRestarts);
3296 STEP(runTransactions1);
3297 STEP(runTransactions1);
3298 FINALIZER(runVerifyIndex);
3299 FINALIZER(createRandomIndex_Drop);
3300 FINALIZER(runClearTable);
3301 }
3302 TESTCASE("NFNR1_O",
3303 "Test that indexes are correctly maintained during node fail and node restart"){
3304 TC_PROPERTY("OrderedIndex", 1);
3305 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3306 TC_PROPERTY("PauseThreads", 2);
3307 INITIALIZER(runClearTable);
3308 INITIALIZER(createRandomIndex);
3309 INITIALIZER(runLoadTable);
3310 STEP(runRestarts);
3311 STEP(runTransactions1);
3312 STEP(runTransactions1);
3313 FINALIZER(runVerifyIndex);
3314 FINALIZER(createRandomIndex_Drop);
3315 FINALIZER(runClearTable);
3316 }
3317 TESTCASE("NFNR2",
3318 "Test that indexes are correctly maintained during node fail and node restart"){
3319 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3320 TC_PROPERTY("PauseThreads", 2);
3321 INITIALIZER(runClearTable);
3322 INITIALIZER(createRandomIndex);
3323 INITIALIZER(createPkIndex);
3324 INITIALIZER(runLoadTable);
3325 STEP(runRestarts);
3326 STEP(runTransactions2);
3327 STEP(runTransactions2);
3328 FINALIZER(runVerifyIndex);
3329 FINALIZER(createRandomIndex_Drop);
3330 FINALIZER(createPkIndex_Drop);
3331 FINALIZER(runClearTable);
3332 }
3333 TESTCASE("NFNR2_O",
3334 "Test that indexes are correctly maintained during node fail and node restart"){
3335 TC_PROPERTY("OrderedIndex", 1);
3336 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3337 TC_PROPERTY("PauseThreads", 1);
3338 INITIALIZER(runClearTable);
3339 INITIALIZER(createRandomIndex);
3340 INITIALIZER(createPkIndex);
3341 INITIALIZER(runLoadTable);
3342 STEP(runRestarts);
3343 STEP(runTransactions2);
3344 //STEP(runTransactions2);
3345 FINALIZER(runVerifyIndex);
3346 FINALIZER(createRandomIndex_Drop);
3347 FINALIZER(createPkIndex_Drop);
3348 FINALIZER(runClearTable);
3349 }
3350 TESTCASE("NFNR3",
3351 "Test that indexes are correctly maintained during node fail and node restart"){
3352 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3353 TC_PROPERTY("PauseThreads", 2);
3354 INITIALIZER(runClearTable);
3355 INITIALIZER(createRandomIndex);
3356 INITIALIZER(createPkIndex);
3357 STEP(runRestarts);
3358 STEP(runTransactions3);
3359 STEP(runVerifyIndex);
3360 FINALIZER(runVerifyIndex);
3361 FINALIZER(createPkIndex_Drop);
3362 FINALIZER(createRandomIndex_Drop);
3363 FINALIZER(runClearTable);
3364 }
3365 TESTCASE("NFNR3_O",
3366 "Test that indexes are correctly maintained during node fail and node restart"){
3367 TC_PROPERTY("OrderedIndex", 1);
3368 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3369 TC_PROPERTY("PauseThreads", 2);
3370 INITIALIZER(runClearTable);
3371 INITIALIZER(createRandomIndex);
3372 INITIALIZER(createPkIndex);
3373 STEP(runRestarts);
3374 STEP(runTransactions3);
3375 STEP(runVerifyIndex);
3376 FINALIZER(runVerifyIndex);
3377 FINALIZER(createPkIndex_Drop);
3378 FINALIZER(createRandomIndex_Drop);
3379 FINALIZER(runClearTable);
3380 }
3381 TESTCASE("NFNR4",
3382 "Test that indexes are correctly maintained during node fail and node restart"){
3383 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3384 TC_PROPERTY("PauseThreads", 4);
3385 INITIALIZER(runClearTable);
3386 INITIALIZER(createRandomIndex);
3387 INITIALIZER(createPkIndex);
3388 INITIALIZER(runLoadTable);
3389 STEP(runRestarts);
3390 STEP(runTransactions1);
3391 STEP(runTransactions1);
3392 STEP(runTransactions2);
3393 STEP(runTransactions2);
3394 FINALIZER(runVerifyIndex);
3395 FINALIZER(createRandomIndex_Drop);
3396 FINALIZER(createPkIndex_Drop);
3397 FINALIZER(runClearTable);
3398 }
3399 TESTCASE("NFNR4_O",
3400 "Test that indexes are correctly maintained during node fail and node restart"){
3401 TC_PROPERTY("OrderedIndex", 1);
3402 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3403 TC_PROPERTY("PauseThreads", 4);
3404 INITIALIZER(runClearTable);
3405 INITIALIZER(createRandomIndex);
3406 INITIALIZER(createPkIndex);
3407 INITIALIZER(runLoadTable);
3408 STEP(runRestarts);
3409 STEP(runTransactions1);
3410 STEP(runTransactions1);
3411 STEP(runTransactions2);
3412 STEP(runTransactions2);
3413 FINALIZER(runVerifyIndex);
3414 FINALIZER(createRandomIndex_Drop);
3415 FINALIZER(createPkIndex_Drop);
3416 FINALIZER(runClearTable);
3417 }
3418 TESTCASE("NFNR5",
3419 "Test that indexes are correctly maintained during node fail and node restart"){
3420 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3421 TC_PROPERTY("BatchSize", (unsigned)1);
3422 INITIALIZER(runClearTable);
3423 INITIALIZER(createRandomIndex);
3424 INITIALIZER(createPkIndex);
3425 INITIALIZER(runLoadTable);
3426 STEP(runLQHKEYREF);
3427 STEP(runTransactions1);
3428 STEP(runTransactions1);
3429 STEP(runTransactions2);
3430 STEP(runTransactions2);
3431 FINALIZER(runVerifyIndex);
3432 FINALIZER(createRandomIndex_Drop);
3433 FINALIZER(createPkIndex_Drop);
3434 FINALIZER(runClearTable);
3435 }
3436 TESTCASE("NFNR5_O",
3437 "Test that indexes are correctly maintained during node fail and node restart"){
3438 TC_PROPERTY("OrderedIndex", 1);
3439 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3440 TC_PROPERTY("BatchSize", (unsigned)1);
3441 INITIALIZER(runClearTable);
3442 INITIALIZER(createRandomIndex);
3443 INITIALIZER(createPkIndex);
3444 INITIALIZER(runLoadTable);
3445 STEP(runLQHKEYREF);
3446 STEP(runTransactions1);
3447 STEP(runTransactions1);
3448 STEP(runTransactions2);
3449 STEP(runTransactions2);
3450 FINALIZER(runVerifyIndex);
3451 FINALIZER(createRandomIndex_Drop);
3452 FINALIZER(createPkIndex_Drop);
3453 FINALIZER(runClearTable);
3454 }
3455 TESTCASE("SR1",
3456 "Test that indexes are correctly maintained during SR"){
3457 INITIALIZER(runClearTable);
3458 INITIALIZER(createRandomIndex);
3459 INITIALIZER(createPkIndex);
3460 STEP(runSystemRestart1);
3461 FINALIZER(runVerifyIndex);
3462 FINALIZER(createPkIndex_Drop);
3463 FINALIZER(createRandomIndex_Drop);
3464 FINALIZER(runClearTable);
3465 }
3466 TESTCASE("MixedTransaction",
3467 "Test mixing of index and normal operations"){
3468 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3469 INITIALIZER(runClearTable);
3470 INITIALIZER(createPkIndex);
3471 INITIALIZER(runLoadTable);
3472 STEP(runMixed1);
3473 FINALIZER(createPkIndex_Drop);
3474 FINALIZER(runClearTable);
3475 }
3476 TESTCASE("MixedTransaction2",
3477 "Test mixing of index and normal operations with batching"){
3478 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3479 INITIALIZER(runClearTable);
3480 INITIALIZER(createPkIndex);
3481 INITIALIZER(runLoadTable);
3482 STEP(runMixed2);
3483 FINALIZER(createPkIndex_Drop);
3484 FINALIZER(runClearTable);
3485 }
3486 TESTCASE("SR1_O",
3487 "Test that indexes are correctly maintained during SR"){
3488 TC_PROPERTY("OrderedIndex", 1);
3489 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3490 INITIALIZER(runClearTable);
3491 INITIALIZER(createRandomIndex);
3492 INITIALIZER(createPkIndex);
3493 STEP(runSystemRestart1);
3494 FINALIZER(runVerifyIndex);
3495 FINALIZER(createPkIndex_Drop);
3496 FINALIZER(createRandomIndex_Drop);
3497 FINALIZER(runClearTable);
3498 }
3499 TESTCASE("BuildDuring",
3500 "Test that index build when running transactions work"){
3501 TC_PROPERTY("OrderedIndex", (unsigned)0);
3502 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3503 TC_PROPERTY("Threads", 1); // # runTransactions4
3504 TC_PROPERTY("BatchSize", 1);
3505 INITIALIZER(runClearTable);
3506 STEP(runBuildDuring);
3507 STEP(runTransactions4);
3508 //STEP(runTransactions4);
3509 FINALIZER(runClearTable);
3510 }
3511 TESTCASE("BuildDuring_O",
3512 "Test that index build when running transactions work"){
3513 TC_PROPERTY("OrderedIndex", (unsigned)1);
3514 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3515 TC_PROPERTY("Threads", 1); // # runTransactions4
3516 INITIALIZER(runClearTable);
3517 STEP(runBuildDuring);
3518 STEP(runTransactions4);
3519 //STEP(runTransactions4);
3520 FINALIZER(runClearTable);
3521 }
3522 TESTCASE("UniqueNull",
3523 "Test that unique indexes and nulls"){
3524 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3525 INITIALIZER(runClearTable);
3526 INITIALIZER(createRandomIndex);
3527 INITIALIZER(createPkIndex);
3528 INITIALIZER(runLoadTable);
3529 STEP(runTransactions1);
3530 STEP(runTransactions2);
3531 STEP(runUniqueNullTransactions);
3532 FINALIZER(runVerifyIndex);
3533 FINALIZER(createRandomIndex_Drop);
3534 FINALIZER(createPkIndex_Drop);
3535 FINALIZER(runClearTable);
3536 }
3537 TESTCASE("Bug21384",
3538 "Test that unique indexes and nulls"){
3539 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3540 INITIALIZER(runClearTable);
3541 INITIALIZER(createPkIndex);
3542 INITIALIZER(runLoadTable);
3543 STEP(runBug21384);
3544 FINALIZER(createPkIndex_Drop);
3545 FINALIZER(runClearTable);
3546 }
3547 TESTCASE("Bug25059",
3548 "Test that unique indexes and nulls"){
3549 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3550 INITIALIZER(createPkIndex);
3551 INITIALIZER(runLoadTable);
3552 STEP(runBug25059);
3553 FINALIZER(createPkIndex_Drop);
3554 }
3555 TESTCASE("Bug28804",
3556 "Test behaviour on out of TransactionBufferMemory for index lookup"){
3557 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3558 INITIALIZER(runClearTable);
3559 INITIALIZER(createPkIndex);
3560 INITIALIZER(runLoadTable);
3561 STEP(runBug28804);
3562 FINALIZER(createPkIndex_Drop);
3563 FINALIZER(runClearTable);
3564 }
3565 TESTCASE("Bug28804_ATTRINFO",
3566 "Test behaviour on out of TransactionBufferMemory for index lookup"
3567 " in saveINDXATTRINFO"){
3568 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3569 INITIALIZER(runClearTable);
3570 INITIALIZER(createPkIndex);
3571 INITIALIZER(runLoadTable);
3572 STEP(runBug28804_ATTRINFO);
3573 FINALIZER(createPkIndex_Drop);
3574 FINALIZER(runClearTable);
3575 }
3576 TESTCASE("Bug46069", ""){
3577 TC_PROPERTY("OrderedIndex", 1);
3578 TC_PROPERTY("THREADS", 12);
3579 TC_PROPERTY("LoggedIndexes", Uint32(0));
3580 INITIALIZER(createPkIndex);
3581 STEP(runBug46069);
3582 STEPS(runBug46069_pkdel, 10);
3583 STEPS(runBug46069_scandel, 2);
3584 FINALIZER(createPkIndex_Drop);
3585 }
3586 TESTCASE("ConstraintDetails",
3587 "Test that the details part of the returned NdbError is as "
3588 "expected"){
3589 INITIALIZER(runConstraintDetails);
3590 }
3591 TESTCASE("Bug50118", ""){
3592 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3593 INITIALIZER(runClearTable);
3594 INITIALIZER(runLoadTable);
3595 INITIALIZER(createPkIndex);
3596 STEP(runReadIndexUntilStopped);
3597 STEP(runReadIndexUntilStopped);
3598 STEP(runReadIndexUntilStopped);
3599 STEP(runBug50118);
3600 FINALIZER(createPkIndex_Drop);
3601 FINALIZER(runClearTable);
3602 }
3603 TESTCASE("FireTrigOverload", ""){
3604 TC_PROPERTY("LoggedIndexes", (unsigned)0);
3605 TC_PROPERTY("NotOnlyPkId", (unsigned)1); // Index must be non PK to fire triggers
3606 TC_PROPERTY(NDBT_TestCase::getStepThreadStackSizePropName(), 128*1024);
3607 INITIALIZER(createRandomIndex);
3608 INITIALIZER(runClearTable);
3609 STEP(runTrigOverload);
3610 FINALIZER(runClearError);
3611 FINALIZER(createRandomIndex_Drop);
3612 }
3613 TESTCASE("DeferredError",
3614 "Test with deferred unique index handling and error inserts")
3615 {
3616 TC_PROPERTY("LoggedIndexes", Uint32(0));
3617 TC_PROPERTY("OrderedIndex", Uint32(0));
3618 INITIALIZER(createPkIndex);
3619 INITIALIZER(runLoadTable);
3620 STEP(runTestDeferredError);
3621 FINALIZER(createPkIndex_Drop);
3622 }
3623 TESTCASE("DeferredMixedLoad",
3624 "Test mixed load of DML with deferred indexes")
3625 {
3626 TC_PROPERTY("LoggedIndexes", Uint32(0));
3627 TC_PROPERTY("OrderedIndex", Uint32(0));
3628 TC_PROPERTY("UntilStopped", Uint32(0));
3629 TC_PROPERTY("Deferred", Uint32(1));
3630 INITIALIZER(createPkIndex);
3631 INITIALIZER(runLoadTable);
3632 STEPS(runMixedDML, 10);
3633 FINALIZER(createPkIndex_Drop);
3634 }
3635 TESTCASE("DeferredMixedLoadError",
3636 "Test mixed load of DML with deferred indexes")
3637 {
3638 TC_PROPERTY("LoggedIndexes", Uint32(0));
3639 TC_PROPERTY("OrderedIndex", Uint32(0));
3640 TC_PROPERTY("UntilStopped", Uint32(1));
3641 TC_PROPERTY("Deferred", Uint32(1));
3642 INITIALIZER(createPkIndex);
3643 INITIALIZER(runLoadTable);
3644 STEPS(runMixedDML, 4);
3645 STEP(runDeferredError);
3646 FINALIZER(createPkIndex_Drop);
3647 }
3648 TESTCASE("NF_DeferredMixed",
3649 "Test mixed load of DML with deferred indexes")
3650 {
3651 TC_PROPERTY("LoggedIndexes", Uint32(0));
3652 TC_PROPERTY("OrderedIndex", Uint32(0));
3653 TC_PROPERTY("UntilStopped", Uint32(1));
3654 TC_PROPERTY("Deferred", Uint32(1));
3655 INITIALIZER(createPkIndex);
3656 INITIALIZER(runLoadTable);
3657 STEPS(runMixedDML, 4);
3658 STEP(runRestarts);
3659 FINALIZER(createPkIndex_Drop);
3660 }
3661 TESTCASE("NF_Mixed",
3662 "Test mixed load of DML")
3663 {
3664 TC_PROPERTY("LoggedIndexes", Uint32(0));
3665 TC_PROPERTY("OrderedIndex", Uint32(0));
3666 TC_PROPERTY("UntilStopped", Uint32(1));
3667 INITIALIZER(createPkIndex);
3668 INITIALIZER(runLoadTable);
3669 STEPS(runMixedDML, 4);
3670 STEP(runRestarts);
3671 FINALIZER(createPkIndex_Drop);
3672 }
3673 TESTCASE("Bug56829",
3674 "Return empty ordered index nodes to index fragment "
3675 "so that empty fragment pages can be freed"){
3676 STEP(runBug56829);
3677 }
3678 TESTCASE("Bug12315582", "")
3679 {
3680 TC_PROPERTY("LoggedIndexes", Uint32(0));
3681 TC_PROPERTY("OrderedIndex", Uint32(0));
3682 INITIALIZER(createPkIndex);
3683 INITIALIZER(runLoadTable);
3684 INITIALIZER(runBug12315582);
3685 FINALIZER(createPkIndex_Drop);
3686 }
3687 TESTCASE("Bug60851", "")
3688 {
3689 TC_PROPERTY("LoggedIndexes", Uint32(0));
3690 TC_PROPERTY("OrderedIndex", Uint32(0));
3691 INITIALIZER(createPkIndex);
3692 INITIALIZER(runLoadTable);
3693 INITIALIZER(runBug60851);
3694 FINALIZER(createPkIndex_Drop);
3695 }
3696 TESTCASE("RefreshWithOrderedIndex",
3697 "Refresh tuples with ordered index(es)")
3698 {
3699 TC_PROPERTY("OrderedIndex", 1);
3700 TC_PROPERTY("LoggedIndexes", Uint32(0));
3701 INITIALIZER(createPkIndex);
3702 INITIALIZER(runRefreshTupleAbort);
3703 FINALIZER(createPkIndex_Drop);
3704 FINALIZER(runClearTable);
3705 }
3706 NDBT_TESTSUITE_END(testIndex);
3707
main(int argc,const char ** argv)3708 int main(int argc, const char** argv){
3709 ndb_init();
3710 NDBT_TESTSUITE_INSTANCE(testIndex);
3711 return testIndex.execute(argc, argv);
3712 }
3713
3714 template class Vector<Attrib*>;
3715