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