MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
testUpgrade.cpp
1 /*
2  Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <NDBT.hpp>
19 #include <NDBT_Test.hpp>
20 #include <HugoTransactions.hpp>
21 #include <UtilTransactions.hpp>
22 #include <NdbRestarter.hpp>
23 #include <AtrtClient.hpp>
24 #include <Bitmask.hpp>
25 #include <NdbBackup.hpp>
26 #include <ndb_version.h>
27 
28 static Vector<BaseString> table_list;
29 
30 struct NodeInfo
31 {
32  int nodeId;
33  int processId;
34  int nodeGroup;
35 };
36 
37 static
38 int
39 createEvent(Ndb *pNdb,
40  const NdbDictionary::Table &tab,
41  bool merge_events = true,
42  bool report = true)
43 {
44  char eventName[1024];
45  sprintf(eventName,"%s_EVENT",tab.getName());
46 
47  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
48 
49  if (!myDict) {
50  g_err << "Dictionary not found "
51  << pNdb->getNdbError().code << " "
52  << pNdb->getNdbError().message << endl;
53  return NDBT_FAILED;
54  }
55 
56  myDict->dropEvent(eventName);
57 
58  NdbDictionary::Event myEvent(eventName);
59  myEvent.setTable(tab.getName());
60  myEvent.addTableEvent(NdbDictionary::Event::TE_ALL);
61  for(int a = 0; a < tab.getNoOfColumns(); a++){
62  myEvent.addEventColumn(a);
63  }
64  myEvent.mergeEvents(merge_events);
65 
66  if (report)
67  myEvent.setReport(NdbDictionary::Event::ER_SUBSCRIBE);
68 
69  int res = myDict->createEvent(myEvent); // Add event to database
70 
71  if (res == 0)
72  myEvent.print();
73  else if (myDict->getNdbError().classification ==
75  {
76  g_info << "Event creation failed event exists\n";
77  res = myDict->dropEvent(eventName);
78  if (res) {
79  g_err << "Failed to drop event: "
80  << myDict->getNdbError().code << " : "
81  << myDict->getNdbError().message << endl;
82  return NDBT_FAILED;
83  }
84  // try again
85  res = myDict->createEvent(myEvent); // Add event to database
86  if (res) {
87  g_err << "Failed to create event (1): "
88  << myDict->getNdbError().code << " : "
89  << myDict->getNdbError().message << endl;
90  return NDBT_FAILED;
91  }
92  }
93  else
94  {
95  g_err << "Failed to create event (2): "
96  << myDict->getNdbError().code << " : "
97  << myDict->getNdbError().message << endl;
98  return NDBT_FAILED;
99  }
100 
101  return NDBT_OK;
102 }
103 
104 static
105 int
106 dropEvent(Ndb *pNdb, const NdbDictionary::Table &tab)
107 {
108  char eventName[1024];
109  sprintf(eventName,"%s_EVENT",tab.getName());
110  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
111  if (!myDict) {
112  g_err << "Dictionary not found "
113  << pNdb->getNdbError().code << " "
114  << pNdb->getNdbError().message << endl;
115  return NDBT_FAILED;
116  }
117  if (myDict->dropEvent(eventName)) {
118  g_err << "Failed to drop event: "
119  << myDict->getNdbError().code << " : "
120  << myDict->getNdbError().message << endl;
121  return NDBT_FAILED;
122  }
123  return NDBT_OK;
124 }
125 
126 
127 static
128 int
129 createDropEvent(NDBT_Context* ctx, NDBT_Step* step)
130 {
131  Ndb* pNdb = GETNDB(step);
132  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
133 
134  if (ctx->getProperty("NoDDL", Uint32(0)) == 0)
135  {
136  for (unsigned i = 0; i<table_list.size(); i++)
137  {
138  int res = NDBT_OK;
139  const NdbDictionary::Table* tab = myDict->getTable(table_list[i].c_str());
140  if (tab == 0)
141  {
142  continue;
143  }
144  if ((res = createEvent(pNdb, *tab) != NDBT_OK))
145  {
146  return res;
147  }
148 
149 
150 
151  if ((res = dropEvent(pNdb, *tab)) != NDBT_OK)
152  {
153  return res;
154  }
155  }
156  }
157 
158  return NDBT_OK;
159 }
160 
161 /* An enum for expressing how many of the multiple nodes
162  * of a given type an action should be applied to
163  */
164 enum NodeSet
165 {
166  All = 0,
167  NotAll = 1, /* less than All, or None if there's only 1 */
168  None = 2
169 };
170 
171 uint getNodeCount(NodeSet set, uint numNodes)
172 {
173  switch(set)
174  {
175  case All:
176  return numNodes;
177  case NotAll:
178  {
179  if (numNodes < 2)
180  return 0;
181 
182  if (numNodes == 2)
183  return 1;
184 
185  uint range = numNodes - 2;
186 
187  /* At least 1, at most numNodes - 1 */
188  return (1 + (rand() % (range + 1)));
189  }
190  case None:
191  {
192  return 0;
193  }
194  default:
195  g_err << "Unknown set type : " << set << endl;
196  abort();
197  return 0;
198  }
199 };
200 
201 
206 int runUpgrade_NR1(NDBT_Context* ctx, NDBT_Step* step){
207  AtrtClient atrt;
208 
209  NodeSet mgmdNodeSet = (NodeSet) ctx->getProperty("MgmdNodeSet", Uint32(0));
210  NodeSet ndbdNodeSet = (NodeSet) ctx->getProperty("NdbdNodeSet", Uint32(0));
211 
212  SqlResultSet clusters;
213  if (!atrt.getClusters(clusters))
214  return NDBT_FAILED;
215 
216  while (clusters.next())
217  {
218  uint clusterId= clusters.columnAsInt("id");
219  SqlResultSet tmp_result;
220  if (!atrt.getConnectString(clusterId, tmp_result))
221  return NDBT_FAILED;
222 
223  NdbRestarter restarter(tmp_result.column("connectstring"));
224  restarter.setReconnect(true); // Restarting mgmd
225  g_err << "Cluster '" << clusters.column("name")
226  << "@" << tmp_result.column("connectstring") << "'" << endl;
227 
228  if (restarter.waitClusterStarted())
229  return NDBT_FAILED;
230 
231  // Restart ndb_mgmd(s)
232  SqlResultSet mgmds;
233  if (!atrt.getMgmds(clusterId, mgmds))
234  return NDBT_FAILED;
235 
236  uint mgmdCount = mgmds.numRows();
237  uint restartCount = getNodeCount(mgmdNodeSet, mgmdCount);
238 
239  ndbout << "Restarting "
240  << restartCount << " of " << mgmdCount
241  << " mgmds" << endl;
242 
243  while (mgmds.next() && restartCount --)
244  {
245  ndbout << "Restart mgmd " << mgmds.columnAsInt("node_id") << endl;
246  if (!atrt.changeVersion(mgmds.columnAsInt("id"), ""))
247  return NDBT_FAILED;
248 
249  if (restarter.waitConnected())
250  return NDBT_FAILED;
251  ndbout << "Connected to mgmd"<< endl;
252  }
253 
254  ndbout << "Waiting for started"<< endl;
255  if (restarter.waitClusterStarted())
256  return NDBT_FAILED;
257  ndbout << "Started"<< endl;
258 
259  // Restart ndbd(s)
260  SqlResultSet ndbds;
261  if (!atrt.getNdbds(clusterId, ndbds))
262  return NDBT_FAILED;
263 
264  uint ndbdCount = ndbds.numRows();
265  restartCount = getNodeCount(ndbdNodeSet, ndbdCount);
266 
267  ndbout << "Restarting "
268  << restartCount << " of " << ndbdCount
269  << " ndbds" << endl;
270 
271  while(ndbds.next() && restartCount --)
272  {
273  int nodeId = ndbds.columnAsInt("node_id");
274  int processId = ndbds.columnAsInt("id");
275  ndbout << "Restart node " << nodeId << endl;
276 
277  if (!atrt.changeVersion(processId, ""))
278  return NDBT_FAILED;
279 
280  if (restarter.waitNodesNoStart(&nodeId, 1))
281  return NDBT_FAILED;
282 
283  if (restarter.startNodes(&nodeId, 1))
284  return NDBT_FAILED;
285 
286  if (restarter.waitNodesStarted(&nodeId, 1))
287  return NDBT_FAILED;
288 
289  if (createDropEvent(ctx, step))
290  return NDBT_FAILED;
291  }
292  }
293 
294  ctx->stopTest();
295  return NDBT_OK;
296 }
297 
298 static
299 int
300 runBug48416(NDBT_Context* ctx, NDBT_Step* step)
301 {
302  Ndb* pNdb = GETNDB(step);
303 
304  return NDBT_Tables::createTable(pNdb, "I1");
305 }
306 
307 static
308 int
309 runUpgrade_Half(NDBT_Context* ctx, NDBT_Step* step)
310 {
311  // Assuming 2 replicas
312 
313  AtrtClient atrt;
314 
315  const bool waitNode = ctx->getProperty("WaitNode", Uint32(0)) != 0;
316  const bool event = ctx->getProperty("CreateDropEvent", Uint32(0)) != 0;
317  const char * args = "";
318  if (ctx->getProperty("KeepFS", Uint32(0)) != 0)
319  {
320  args = "--initial=0";
321  }
322 
323  NodeSet mgmdNodeSet = (NodeSet) ctx->getProperty("MgmdNodeSet", Uint32(0));
324  NodeSet ndbdNodeSet = (NodeSet) ctx->getProperty("NdbdNodeSet", Uint32(0));
325 
326  SqlResultSet clusters;
327  if (!atrt.getClusters(clusters))
328  return NDBT_FAILED;
329 
330  while (clusters.next())
331  {
332  uint clusterId= clusters.columnAsInt("id");
333  SqlResultSet tmp_result;
334  if (!atrt.getConnectString(clusterId, tmp_result))
335  return NDBT_FAILED;
336 
337  NdbRestarter restarter(tmp_result.column("connectstring"));
338  restarter.setReconnect(true); // Restarting mgmd
339  g_err << "Cluster '" << clusters.column("name")
340  << "@" << tmp_result.column("connectstring") << "'" << endl;
341 
342  if(restarter.waitClusterStarted())
343  return NDBT_FAILED;
344 
345  // Restart ndb_mgmd(s)
346  SqlResultSet mgmds;
347  if (!atrt.getMgmds(clusterId, mgmds))
348  return NDBT_FAILED;
349 
350  uint mgmdCount = mgmds.numRows();
351  uint restartCount = getNodeCount(mgmdNodeSet, mgmdCount);
352 
353  ndbout << "Restarting "
354  << restartCount << " of " << mgmdCount
355  << " mgmds" << endl;
356 
357  while (mgmds.next() && restartCount --)
358  {
359  ndbout << "Restart mgmd" << mgmds.columnAsInt("node_id") << endl;
360  if (!atrt.changeVersion(mgmds.columnAsInt("id"), ""))
361  return NDBT_FAILED;
362 
363  if(restarter.waitConnected())
364  return NDBT_FAILED;
365  }
366 
367  NdbSleep_SecSleep(5); // TODO, handle arbitration
368 
369  // Restart one ndbd in each node group
370  SqlResultSet ndbds;
371  if (!atrt.getNdbds(clusterId, ndbds))
372  return NDBT_FAILED;
373 
374  Vector<NodeInfo> nodes;
375  while (ndbds.next())
376  {
377  struct NodeInfo n;
378  n.nodeId = ndbds.columnAsInt("node_id");
379  n.processId = ndbds.columnAsInt("id");
380  n.nodeGroup = restarter.getNodeGroup(n.nodeId);
381  nodes.push_back(n);
382  }
383 
384  uint ndbdCount = ndbds.numRows();
385  restartCount = getNodeCount(ndbdNodeSet, ndbdCount);
386 
387  ndbout << "Restarting "
388  << restartCount << " of " << ndbdCount
389  << " ndbds" << endl;
390 
391  int nodesarray[256];
392  int cnt= 0;
393 
394  Bitmask<4> seen_groups;
395  Bitmask<4> restarted_nodes;
396  for (Uint32 i = 0; (i<nodes.size() && restartCount); i++)
397  {
398  int nodeId = nodes[i].nodeId;
399  int processId = nodes[i].processId;
400  int nodeGroup= nodes[i].nodeGroup;
401 
402  if (seen_groups.get(nodeGroup))
403  {
404  // One node in this node group already down
405  continue;
406  }
407  seen_groups.set(nodeGroup);
408  restarted_nodes.set(nodeId);
409 
410  ndbout << "Restart node " << nodeId << endl;
411 
412  if (!atrt.changeVersion(processId, args))
413  return NDBT_FAILED;
414 
415  if (waitNode)
416  {
417  restarter.waitNodesNoStart(&nodeId, 1);
418  }
419 
420  nodesarray[cnt++]= nodeId;
421  restartCount--;
422  }
423 
424  if (!waitNode)
425  {
426  if (restarter.waitNodesNoStart(nodesarray, cnt))
427  return NDBT_FAILED;
428  }
429 
430  ndbout << "Starting and wait for started..." << endl;
431  if (restarter.startAll())
432  return NDBT_FAILED;
433 
434  if (restarter.waitClusterStarted())
435  return NDBT_FAILED;
436 
437  if (event && createDropEvent(ctx, step))
438  {
439  return NDBT_FAILED;
440  }
441 
442  // Restart the remaining nodes
443  cnt= 0;
444  for (Uint32 i = 0; (i<nodes.size() && restartCount); i++)
445  {
446  int nodeId = nodes[i].nodeId;
447  int processId = nodes[i].processId;
448 
449  if (restarted_nodes.get(nodeId))
450  continue;
451 
452  ndbout << "Restart node " << nodeId << endl;
453  if (!atrt.changeVersion(processId, args))
454  return NDBT_FAILED;
455 
456  if (waitNode)
457  {
458  restarter.waitNodesNoStart(&nodeId, 1);
459  }
460 
461  nodesarray[cnt++]= nodeId;
462  restartCount --;
463  }
464 
465 
466  if (!waitNode)
467  {
468  if (restarter.waitNodesNoStart(nodesarray, cnt))
469  return NDBT_FAILED;
470  }
471 
472  ndbout << "Starting and wait for started..." << endl;
473  if (restarter.startAll())
474  return NDBT_FAILED;
475 
476  if (restarter.waitClusterStarted())
477  return NDBT_FAILED;
478 
479  if (event && createDropEvent(ctx, step))
480  {
481  return NDBT_FAILED;
482  }
483  }
484 
485  return NDBT_OK;
486 }
487 
488 
489 
495 int runUpgrade_NR2(NDBT_Context* ctx, NDBT_Step* step)
496 {
497  // Assuming 2 replicas
498 
499  ctx->setProperty("WaitNode", 1);
500  ctx->setProperty("CreateDropEvent", 1);
501  int res = runUpgrade_Half(ctx, step);
502  ctx->stopTest();
503  return res;
504 }
505 
512 int runUpgrade_NR3(NDBT_Context* ctx, NDBT_Step* step){
513  // Assuming 2 replicas
514 
515  ctx->setProperty("CreateDropEvent", 1);
516  int res = runUpgrade_Half(ctx, step);
517  ctx->stopTest();
518  return res;
519 }
520 
524 int runUpgrade_NdbdOnly(NDBT_Context* ctx, NDBT_Step* step)
525 {
526  ctx->setProperty("MgmdNodeSet", (Uint32) NodeSet(None));
527  int res = runUpgrade_Half(ctx, step);
528  ctx->stopTest();
529  return res;
530 }
531 
536 int runUpgrade_NdbdFirst(NDBT_Context* ctx, NDBT_Step* step)
537 {
538  ctx->setProperty("MgmdNodeSet", (Uint32) NodeSet(None));
539  int res = runUpgrade_Half(ctx, step);
540  if (res == NDBT_OK)
541  {
542  ctx->setProperty("MgmdNodeSet", (Uint32) NodeSet(All));
543  ctx->setProperty("NdbdNodeSet", (Uint32) NodeSet(None));
544  res = runUpgrade_Half(ctx, step);
545  }
546  ctx->stopTest();
547  return res;
548 }
549 
553 int runUpgrade_NotAllMGMD(NDBT_Context* ctx, NDBT_Step* step)
554 {
555  ctx->setProperty("MgmdNodeSet", (Uint32) NodeSet(NotAll));
556  ctx->setProperty("NdbdNodeSet", (Uint32) NodeSet(None));
557  int res = runUpgrade_Half(ctx, step);
558  ctx->stopTest();
559  return res;
560 }
561 
562 int runCheckStarted(NDBT_Context* ctx, NDBT_Step* step){
563 
564  // Check cluster is started
565  NdbRestarter restarter;
566  if(restarter.waitClusterStarted() != 0){
567  g_err << "All nodes was not started " << endl;
568  return NDBT_FAILED;
569  }
570 
571  // Check atrtclient is started
572  AtrtClient atrt;
573  if(!atrt.waitConnected()){
574  g_err << "atrt server was not started " << endl;
575  return NDBT_FAILED;
576  }
577 
578  // Make sure atrt assigns nodeid != -1
579  SqlResultSet procs;
580  if (!atrt.doQuery("SELECT * FROM process where type <> \'mysql\'", procs))
581  return NDBT_FAILED;
582 
583  while (procs.next())
584  {
585  if (procs.columnAsInt("node_id") == (unsigned)-1){
586  ndbout << "Found one process with node_id -1, "
587  << "use --fix-nodeid=1 to atrt to fix this" << endl;
588  return NDBT_FAILED;
589  }
590  }
591 
592  return NDBT_OK;
593 }
594 
595 int
596 runCreateAllTables(NDBT_Context* ctx, NDBT_Step* step)
597 {
598  ndbout_c("createAllTables");
599  if (NDBT_Tables::createAllTables(GETNDB(step), false, true))
600  return NDBT_FAILED;
601 
602  for (int i = 0; i<NDBT_Tables::getNumTables(); i++)
603  table_list.push_back(BaseString(NDBT_Tables::getTable(i)->getName()));
604 
605  return NDBT_OK;
606 }
607 
608 int
609 runCreateOneTable(NDBT_Context* ctx, NDBT_Step* step)
610 {
611  // Table is already created...
612  // so we just add it to table_list
613  table_list.push_back(BaseString(ctx->getTab()->getName()));
614 
615  return NDBT_OK;
616 }
617 
618 int runGetTableList(NDBT_Context* ctx, NDBT_Step* step)
619 {
620  table_list.clear();
621  ndbout << "Looking for tables ... ";
622  for (int i = 0; i<NDBT_Tables::getNumTables(); i++)
623  {
624  const NdbDictionary::Table* tab =
625  GETNDB(step)->getDictionary()
626  ->getTable(NDBT_Tables::getTable(i)
627  ->getName());
628  if (tab != NULL)
629  {
630  ndbout << tab->getName() << " ";
631  table_list.push_back(BaseString(tab->getName()));
632  }
633  }
634  ndbout << endl;
635 
636  return NDBT_OK;
637 }
638 
639 int
640 runLoadAll(NDBT_Context* ctx, NDBT_Step* step)
641 {
642  Ndb* pNdb = GETNDB(step);
643  NdbDictionary::Dictionary * pDict = pNdb->getDictionary();
644  int records = ctx->getNumRecords();
645  int result = NDBT_OK;
646 
647  for (unsigned i = 0; i<table_list.size(); i++)
648  {
649  const NdbDictionary::Table* tab = pDict->getTable(table_list[i].c_str());
650  HugoTransactions trans(* tab);
651  trans.loadTable(pNdb, records);
652  trans.scanUpdateRecords(pNdb, records);
653  }
654 
655  return result;
656 }
657 
658 int
659 runClearAll(NDBT_Context* ctx, NDBT_Step* step)
660 {
661  Ndb* pNdb = GETNDB(step);
662  NdbDictionary::Dictionary * pDict = pNdb->getDictionary();
663  int records = ctx->getNumRecords();
664  int result = NDBT_OK;
665 
666  for (unsigned i = 0; i<table_list.size(); i++)
667  {
668  const NdbDictionary::Table* tab = pDict->getTable(table_list[i].c_str());
669  if (tab)
670  {
671  HugoTransactions trans(* tab);
672  trans.clearTable(pNdb, records);
673  }
674  }
675 
676  return result;
677 }
678 
679 
680 int
681 runBasic(NDBT_Context* ctx, NDBT_Step* step)
682 {
683  Ndb* pNdb = GETNDB(step);
684  NdbDictionary::Dictionary * pDict = pNdb->getDictionary();
685  int records = ctx->getNumRecords();
686  int result = NDBT_OK;
687 
688  int l = 0;
689  while (!ctx->isTestStopped())
690  {
691  for (unsigned i = 0; i<table_list.size(); i++)
692  {
693  const NdbDictionary::Table* tab = pDict->getTable(table_list[i].c_str());
694  HugoTransactions trans(* tab);
695  switch(l % 4){
696  case 0:
697  trans.loadTable(pNdb, records);
698  trans.scanUpdateRecords(pNdb, records);
699  trans.pkUpdateRecords(pNdb, records);
700  trans.pkReadUnlockRecords(pNdb, records);
701  break;
702  case 1:
703  trans.scanUpdateRecords(pNdb, records);
704  // TODO make pkInterpretedUpdateRecords work on any table
705  // (or check if it does)
706  if (strcmp(tab->getName(), "T1") == 0)
707  trans.pkInterpretedUpdateRecords(pNdb, records);
708  trans.clearTable(pNdb, records/2);
709  trans.loadTable(pNdb, records/2);
710  break;
711  case 2:
712  trans.clearTable(pNdb, records/2);
713  trans.loadTable(pNdb, records/2);
714  trans.clearTable(pNdb, records/2);
715  break;
716  case 3:
717  if (createDropEvent(ctx, step))
718  {
719  return NDBT_FAILED;
720  }
721  break;
722  }
723  }
724  l++;
725  }
726 
727  return result;
728 }
729 
730 int
731 rollingRestart(NDBT_Context* ctx, NDBT_Step* step)
732 {
733  // Assuming 2 replicas
734 
735  AtrtClient atrt;
736 
737  SqlResultSet clusters;
738  if (!atrt.getClusters(clusters))
739  return NDBT_FAILED;
740 
741  while (clusters.next())
742  {
743  uint clusterId= clusters.columnAsInt("id");
744  SqlResultSet tmp_result;
745  if (!atrt.getConnectString(clusterId, tmp_result))
746  return NDBT_FAILED;
747 
748  NdbRestarter restarter(tmp_result.column("connectstring"));
749  if (restarter.rollingRestart())
750  return NDBT_FAILED;
751  }
752 
753  return NDBT_OK;
754 
755 }
756 
757 int runUpgrade_Traffic(NDBT_Context* ctx, NDBT_Step* step){
758  // Assuming 2 replicas
759 
760  ndbout_c("upgrading");
761  int res = runUpgrade_Half(ctx, step);
762  if (res == NDBT_OK)
763  {
764  ndbout_c("rolling restarting");
765  res = rollingRestart(ctx, step);
766  }
767  ctx->stopTest();
768  return res;
769 }
770 
771 int
772 startPostUpgradeChecks(NDBT_Context* ctx, NDBT_Step* step)
773 {
778  BaseString extraArgs;
779  if (ctx->getProperty("RestartNoDDL", Uint32(0)))
780  {
781  /* Ask post-upgrade steps not to perform DDL
782  * (e.g. for 6.3->7.0 upgrade)
783  */
784  extraArgs.append(" --noddl ");
785  }
786 
795  BaseString tc;
796  tc.assfmt("-n %s--post-upgrade %s",
797  ctx->getCase()->getName(),
798  extraArgs.c_str());
799 
800  ndbout << "About to restart self with extra arg: " << tc.c_str() << endl;
801 
802  AtrtClient atrt;
803  int process_id = atrt.getOwnProcessId();
804  if (process_id == -1)
805  {
806  g_err << "Failed to find own process id" << endl;
807  return NDBT_FAILED;
808  }
809 
810  if (!atrt.changeVersion(process_id, tc.c_str()))
811  return NDBT_FAILED;
812 
813  // Will not be reached...
814 
815  return NDBT_OK;
816 }
817 
818 int
819 startPostUpgradeChecksApiFirst(NDBT_Context* ctx, NDBT_Step* step)
820 {
821  /* If Api is upgraded before all NDBDs then it may not
822  * be possible to use DDL from the upgraded API
823  * The upgraded Api will decide, but we pass NoDDL
824  * in
825  */
826  ctx->setProperty("RestartNoDDL", 1);
827  return startPostUpgradeChecks(ctx, step);
828 }
829 
830 int
831 runPostUpgradeChecks(NDBT_Context* ctx, NDBT_Step* step)
832 {
838  NdbBackup backup(GETNDB(step)->getNodeId()+1);
839 
840  ndbout << "Starting backup..." << flush;
841  if (backup.start() != 0)
842  {
843  ndbout << "Failed" << endl;
844  return NDBT_FAILED;
845  }
846  ndbout << "done" << endl;
847 
848 
849  if ((ctx->getProperty("NoDDL", Uint32(0)) == 0) &&
850  (ctx->getProperty("KeepFS", Uint32(0)) != 0))
851  {
858  Ndb* pNdb = GETNDB(step);
859  NdbDictionary::Dictionary *pDict = pNdb->getDictionary();
860  {
862  pDict->listObjects(l);
863  for (Uint32 i = 0; i<l.count; i++)
864  ndbout_c("found %u : %s", l.elements[i].id, l.elements[i].name);
865  }
866 
867  pDict->dropTable("I3");
868  if (NDBT_Tables::createTable(pNdb, "I3"))
869  {
870  ndbout_c("Failed to create table!");
871  ndbout << pDict->getNdbError() << endl;
872  return NDBT_FAILED;
873  }
874 
875  {
877  pDict->listObjects(l);
878  for (Uint32 i = 0; i<l.count; i++)
879  ndbout_c("found %u : %s", l.elements[i].id, l.elements[i].name);
880  }
881 
882  NdbRestarter res;
883  if (res.restartAll() != 0)
884  {
885  ndbout_c("restartAll() failed");
886  return NDBT_FAILED;
887  }
888 
889  if (res.waitClusterStarted() != 0)
890  {
891  ndbout_c("waitClusterStarted() failed");
892  return NDBT_FAILED;
893  }
894 
895  if (pDict->getTable("I3") == 0)
896  {
897  ndbout_c("Table disappered");
898  return NDBT_FAILED;
899  }
900  }
901 
902  return NDBT_OK;
903 }
904 
905 
906 int
907 runWait(NDBT_Context* ctx, NDBT_Step* step)
908 {
909  Uint32 waitSeconds = ctx->getProperty("WaitSeconds", Uint32(30));
910  while (waitSeconds &&
911  !ctx->isTestStopped())
912  {
913  NdbSleep_MilliSleep(1000);
914  waitSeconds --;
915  }
916  ctx->stopTest();
917  return NDBT_OK;
918 }
919 
920 bool versionsSpanBoundary(int verA, int verB, int incBoundaryVer)
921 {
922  int minPeerVer = MIN(verA, verB);
923  int maxPeerVer = MAX(verA, verB);
924 
925  return ( (minPeerVer < incBoundaryVer) &&
926  (maxPeerVer >= incBoundaryVer) );
927 }
928 
929 #define SchemaTransVersion NDB_MAKE_VERSION(6,4,0)
930 
931 int runPostUpgradeDecideDDL(NDBT_Context* ctx, NDBT_Step* step)
932 {
933  /* We are running post-upgrade, now examine the versions
934  * of connected nodes and update the 'NoDDL' variable
935  * accordingly
936  */
937  /* DDL should be ok as long as
938  * 1) All data nodes have the same version
939  * 2) There is not some version specific exception
940  */
941  bool useDDL = true;
942 
943  Ndb* pNdb = GETNDB(step);
944  NdbRestarter restarter;
945  int minNdbVer = 0;
946  int maxNdbVer = 0;
947  int myVer = NDB_VERSION;
948 
949  if (restarter.getNodeTypeVersionRange(NDB_MGM_NODE_TYPE_NDB,
950  minNdbVer,
951  maxNdbVer) == -1)
952  {
953  g_err << "getNodeTypeVersionRange call failed" << endl;
954  return NDBT_FAILED;
955  }
956 
957  if (minNdbVer != maxNdbVer)
958  {
959  useDDL = false;
960  ndbout << "Ndbd nodes have mixed versions, DDL not supported" << endl;
961  }
962  if (versionsSpanBoundary(myVer, minNdbVer, SchemaTransVersion))
963  {
964  useDDL = false;
965  ndbout << "Api and Ndbd versions span schema-trans boundary, DDL not supported" << endl;
966  }
967 
968  ctx->setProperty("NoDDL", useDDL?0:1);
969 
970  if (useDDL)
971  {
972  ndbout << "Dropping and recreating tables..." << endl;
973 
974  for (int i=0; i < NDBT_Tables::getNumTables(); i++)
975  {
976  /* Drop table (ignoring rc if it doesn't exist etc...) */
977  pNdb->getDictionary()->dropTable(NDBT_Tables::getTable(i)->getName());
978  int ret= NDBT_Tables::createTable(pNdb,
979  NDBT_Tables::getTable(i)->getName(),
980  false, // temp
981  false); // exists ok
982  if(ret)
983  {
984  NdbError err = pNdb->getDictionary()->getNdbError();
985 
986  g_err << "Failed to create table "
987  << NDBT_Tables::getTable(i)->getName()
988  << " error : "
989  << err
990  << endl;
991 
992  /* Check for allowed exceptions during upgrade */
993  if (err.code == 794)
994  {
995  /* Schema feature requires data node upgrade */
996  if (minNdbVer >= myVer)
997  {
998  g_err << "Error 794 received, but data nodes are upgraded" << endl;
999  // TODO : Dump versions here
1000  return NDBT_FAILED;
1001  }
1002  g_err << "Create table failure due to old version NDBDs, continuing" << endl;
1003  }
1004  }
1005  }
1006  ndbout << "Done" << endl;
1007  }
1008 
1009  return NDBT_OK;
1010 }
1011 
1012 
1013 NDBT_TESTSUITE(testUpgrade);
1014 TESTCASE("Upgrade_NR1",
1015  "Test that one node at a time can be upgraded"){
1016  INITIALIZER(runCheckStarted);
1017  INITIALIZER(runBug48416);
1018  STEP(runUpgrade_NR1);
1019  VERIFIER(startPostUpgradeChecks);
1020 }
1021 POSTUPGRADE("Upgrade_NR1")
1022 {
1023  INITIALIZER(runCheckStarted);
1024  INITIALIZER(runPostUpgradeChecks);
1025 }
1026 TESTCASE("Upgrade_NR2",
1027  "Test that one node in each nodegroup can be upgradde simultaneously"){
1028  INITIALIZER(runCheckStarted);
1029  STEP(runUpgrade_NR2);
1030  VERIFIER(startPostUpgradeChecks);
1031 }
1032 POSTUPGRADE("Upgrade_NR2")
1033 {
1034  INITIALIZER(runCheckStarted);
1035  INITIALIZER(runPostUpgradeChecks);
1036 }
1037 TESTCASE("Upgrade_NR3",
1038  "Test that one node in each nodegroup can be upgradde simultaneously"){
1039  INITIALIZER(runCheckStarted);
1040  STEP(runUpgrade_NR3);
1041  VERIFIER(startPostUpgradeChecks);
1042 }
1043 POSTUPGRADE("Upgrade_NR3")
1044 {
1045  INITIALIZER(runCheckStarted);
1046  INITIALIZER(runPostUpgradeChecks);
1047 }
1048 TESTCASE("Upgrade_FS",
1049  "Test that one node in each nodegroup can be upgrade simultaneously")
1050 {
1051  TC_PROPERTY("KeepFS", 1);
1052  INITIALIZER(runCheckStarted);
1053  INITIALIZER(runCreateAllTables);
1054  INITIALIZER(runLoadAll);
1055  STEP(runUpgrade_Traffic);
1056  VERIFIER(startPostUpgradeChecks);
1057 }
1058 POSTUPGRADE("Upgrade_FS")
1059 {
1060  INITIALIZER(runCheckStarted);
1061  INITIALIZER(runPostUpgradeChecks);
1062 }
1063 TESTCASE("Upgrade_Traffic",
1064  "Test upgrade with traffic, all tables and restart --initial")
1065 {
1066  INITIALIZER(runCheckStarted);
1067  INITIALIZER(runCreateAllTables);
1068  STEP(runUpgrade_Traffic);
1069  STEP(runBasic);
1070  VERIFIER(startPostUpgradeChecks);
1071 }
1072 POSTUPGRADE("Upgrade_Traffic")
1073 {
1074  INITIALIZER(runCheckStarted);
1075  INITIALIZER(runPostUpgradeChecks);
1076 }
1077 TESTCASE("Upgrade_Traffic_FS",
1078  "Test upgrade with traffic, all tables and restart using FS")
1079 {
1080  TC_PROPERTY("KeepFS", 1);
1081  INITIALIZER(runCheckStarted);
1082  INITIALIZER(runCreateAllTables);
1083  STEP(runUpgrade_Traffic);
1084  STEP(runBasic);
1085  VERIFIER(startPostUpgradeChecks);
1086 }
1087 POSTUPGRADE("Upgrade_Traffic_FS")
1088 {
1089  INITIALIZER(runCheckStarted);
1090  INITIALIZER(runPostUpgradeChecks);
1091 }
1092 TESTCASE("Upgrade_Traffic_one",
1093  "Test upgrade with traffic, *one* table and restart --initial")
1094 {
1095  INITIALIZER(runCheckStarted);
1096  INITIALIZER(runCreateOneTable);
1097  STEP(runUpgrade_Traffic);
1098  STEP(runBasic);
1099  VERIFIER(startPostUpgradeChecks);
1100 }
1101 POSTUPGRADE("Upgrade_Traffic_one")
1102 {
1103  INITIALIZER(runCheckStarted);
1104  INITIALIZER(runPostUpgradeChecks);
1105 }
1106 TESTCASE("Upgrade_Traffic_FS_one",
1107  "Test upgrade with traffic, all tables and restart using FS")
1108 {
1109  TC_PROPERTY("KeepFS", 1);
1110  INITIALIZER(runCheckStarted);
1111  INITIALIZER(runCreateOneTable);
1112  STEP(runUpgrade_Traffic);
1113  STEP(runBasic);
1114  VERIFIER(startPostUpgradeChecks);
1115 }
1116 POSTUPGRADE("Upgrade_Traffic_FS_one")
1117 {
1118  INITIALIZER(runCheckStarted);
1119  INITIALIZER(runPostUpgradeChecks);
1120 }
1121 TESTCASE("Upgrade_Api_Only",
1122  "Test that upgrading the Api node only works")
1123 {
1124  INITIALIZER(runCheckStarted);
1125  INITIALIZER(runCreateAllTables);
1126  VERIFIER(startPostUpgradeChecksApiFirst);
1127 }
1128 POSTUPGRADE("Upgrade_Api_Only")
1129 {
1130  INITIALIZER(runCheckStarted);
1131  INITIALIZER(runPostUpgradeDecideDDL);
1132  INITIALIZER(runGetTableList);
1133  TC_PROPERTY("WaitSeconds", 30);
1134  STEP(runBasic);
1135  STEP(runPostUpgradeChecks);
1136  STEP(runWait);
1137  FINALIZER(runClearAll);
1138 }
1139 TESTCASE("Upgrade_Api_Before_NR1",
1140  "Test that upgrading the Api node before the kernel works")
1141 {
1142  /* Api, then MGMD(s), then NDBDs */
1143  INITIALIZER(runCheckStarted);
1144  INITIALIZER(runCreateAllTables);
1145  VERIFIER(startPostUpgradeChecksApiFirst);
1146 }
1147 POSTUPGRADE("Upgrade_Api_Before_NR1")
1148 {
1149  INITIALIZER(runCheckStarted);
1150  INITIALIZER(runPostUpgradeDecideDDL);
1151  INITIALIZER(runGetTableList);
1152  STEP(runBasic);
1153  STEP(runUpgrade_NR1); /* Upgrade kernel nodes using NR1 */
1154  FINALIZER(runPostUpgradeChecks);
1155  FINALIZER(runClearAll);
1156 }
1157 TESTCASE("Upgrade_Api_NDBD_MGMD",
1158  "Test that updating in reverse order works")
1159 {
1160  INITIALIZER(runCheckStarted);
1161  INITIALIZER(runCreateAllTables);
1162  VERIFIER(startPostUpgradeChecksApiFirst);
1163 }
1164 POSTUPGRADE("Upgrade_Api_NDBD_MGMD")
1165 {
1166  INITIALIZER(runCheckStarted);
1167  INITIALIZER(runPostUpgradeDecideDDL);
1168  INITIALIZER(runGetTableList);
1169  STEP(runBasic);
1170  STEP(runUpgrade_NdbdFirst);
1171  FINALIZER(runPostUpgradeChecks);
1172  FINALIZER(runClearAll);
1173 }
1174 TESTCASE("Upgrade_Mixed_MGMD_API_NDBD",
1175  "Test that upgrading MGMD/API partially before data nodes works")
1176 {
1177  INITIALIZER(runCheckStarted);
1178  INITIALIZER(runCreateAllTables);
1179  STEP(runUpgrade_NotAllMGMD); /* Upgrade an MGMD */
1180  STEP(runBasic);
1181  VERIFIER(startPostUpgradeChecksApiFirst); /* Upgrade Api */
1182 }
1183 POSTUPGRADE("Upgrade_Mixed_MGMD_API_NDBD")
1184 {
1185  INITIALIZER(runCheckStarted);
1186  INITIALIZER(runPostUpgradeDecideDDL);
1187  INITIALIZER(runGetTableList);
1188  INITIALIZER(runClearAll); /* Clear rows from old-ver basic run */
1189  STEP(runBasic);
1190  STEP(runUpgrade_NdbdFirst); /* Upgrade all Ndbds, then MGMDs finally */
1191  FINALIZER(runPostUpgradeChecks);
1192  FINALIZER(runClearAll);
1193 }
1194 
1195 NDBT_TESTSUITE_END(testUpgrade);
1196 
1197 int main(int argc, const char** argv){
1198  ndb_init();
1199  NDBT_TESTSUITE_INSTANCE(testUpgrade);
1200  testUpgrade.setCreateAllTables(true);
1201  return testUpgrade.execute(argc, argv);
1202 }
1203 
1204 template class Vector<NodeInfo>;