restore_main.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:11k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <ndb_opts.h>
  15. #include <Vector.hpp>
  16. #include <ndb_limits.h>
  17. #include <NdbTCP.h>
  18. #include <NdbOut.hpp>
  19. #include <NDBT_ReturnCodes.h>
  20. #include "consumer_restore.hpp"
  21. #include "consumer_printer.hpp"
  22. extern FilteredNdbOut err;
  23. extern FilteredNdbOut info;
  24. extern FilteredNdbOut debug;
  25. static int ga_nodeId = 0;
  26. static int ga_nParallelism = 128;
  27. static int ga_backupId = 0;
  28. static bool ga_dont_ignore_systab_0 = false;
  29. static Vector<class BackupConsumer *> g_consumers;
  30. static const char* ga_backupPath = "." DIR_SEPARATOR;
  31. NDB_STD_OPTS_VARS;
  32. /**
  33.  * print and restore flags
  34.  */
  35. static bool ga_restore = false;
  36. static bool ga_print = false;
  37. static int _print = 0;
  38. static int _print_meta = 0;
  39. static int _print_data = 0;
  40. static int _print_log = 0;
  41. static int _restore_data = 0;
  42. static int _restore_meta = 0;
  43.   
  44. static struct my_option my_long_options[] =
  45. {
  46.   NDB_STD_OPTS("ndb_restore"),
  47.   { "connect", 'c', "same as --connect-string",
  48.     (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
  49.     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
  50.   { "nodeid", 'n', "Backup files from node with id",
  51.     (gptr*) &ga_nodeId, (gptr*) &ga_nodeId, 0,
  52.     GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
  53.   { "backupid", 'b', "Backup id",
  54.     (gptr*) &ga_backupId, (gptr*) &ga_backupId, 0,
  55.     GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
  56.   { "restore_data", 'r', 
  57.     "Restore table data/logs into NDB Cluster using NDBAPI", 
  58.     (gptr*) &_restore_data, (gptr*) &_restore_data,  0,
  59.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  60.   { "restore_meta", 'm',
  61.     "Restore meta data into NDB Cluster using NDBAPI",
  62.     (gptr*) &_restore_meta, (gptr*) &_restore_meta,  0,
  63.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  64.   { "parallelism", 'p',
  65.     "No of parallel transactions during restore of data."
  66.     "(parallelism can be 1 to 1024)", 
  67.     (gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0,
  68.     GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 },
  69.   { "print", 256, "Print data and log to stdout",
  70.     (gptr*) &_print, (gptr*) &_print, 0,
  71.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  72.   { "print_data", 257, "Print data to stdout", 
  73.     (gptr*) &_print_data, (gptr*) &_print_data, 0,
  74.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  75.   { "print_meta", 258, "Print meta data to stdout",
  76.     (gptr*) &_print_meta, (gptr*) &_print_meta,  0,
  77.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  78.   { "print_log", 259, "Print log to stdout",
  79.     (gptr*) &_print_log, (gptr*) &_print_log,  0,
  80.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  81.   { "dont_ignore_systab_0", 'f',
  82.     "Experimental. Do not ignore system table during restore.", 
  83.     (gptr*) &ga_dont_ignore_systab_0, (gptr*) &ga_dont_ignore_systab_0, 0,
  84.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  85.   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
  86. };
  87. static void short_usage_sub(void)
  88. {
  89.   printf("Usage: %s [OPTIONS] [<path to backup files>]n", my_progname);
  90. }
  91. static void usage()
  92. {
  93.   short_usage_sub();
  94.   ndb_std_print_version();
  95.   my_print_help(my_long_options);
  96.   my_print_variables(my_long_options);
  97. }
  98. static my_bool
  99. get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
  100.        char *argument)
  101. {
  102.   ndb_std_get_one_option(optid, opt, argument ? argument :
  103.  "d:t:O,/tmp/ndb_restore.trace");
  104.   switch (optid) {
  105.   case 'n':
  106.     if (ga_nodeId == 0)
  107.     {
  108.       printf("Error in --nodeid,-n setting, see --helpn");
  109.       exit(NDBT_ProgramExit(NDBT_WRONGARGS));
  110.     }
  111.     break;
  112.   case 'b':
  113.     if (ga_backupId == 0)
  114.     {
  115.       printf("Error in --backupid,-b setting, see --helpn");
  116.       exit(NDBT_ProgramExit(NDBT_WRONGARGS));
  117.     }
  118.     break;
  119.   }
  120.   return 0;
  121. }
  122. bool
  123. readArguments(int *pargc, char*** pargv) 
  124. {
  125.   const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 };
  126.   load_defaults("my",load_default_groups,pargc,pargv);
  127.   if (handle_options(pargc, pargv, my_long_options, get_one_option))
  128.   {
  129.     exit(NDBT_ProgramExit(NDBT_WRONGARGS));
  130.   }
  131.   BackupPrinter* printer = new BackupPrinter();
  132.   if (printer == NULL)
  133.     return false;
  134.   BackupRestore* restore = new BackupRestore(ga_nParallelism);
  135.   if (restore == NULL) 
  136.   {
  137.     delete printer;
  138.     return false;
  139.   }
  140.   if (_print) 
  141.   {
  142.     ga_print = true;
  143.     ga_restore = true;
  144.     printer->m_print = true;
  145.   } 
  146.   if (_print_meta) 
  147.   {
  148.     ga_print = true;
  149.     printer->m_print_meta = true;
  150.   }
  151.   if (_print_data) 
  152.   {
  153.     ga_print = true;
  154.     printer->m_print_data = true;
  155.   }
  156.   if (_print_log) 
  157.   {
  158.     ga_print = true;
  159.     printer->m_print_log = true;
  160.   }
  161.   if (_restore_data)
  162.   {
  163.     ga_restore = true;
  164.     restore->m_restore = true; 
  165.   }
  166.   if (_restore_meta)
  167.   {
  168.     //    ga_restore = true;
  169.     restore->m_restore_meta = true;
  170.   }
  171.   {
  172.     BackupConsumer * c = printer;
  173.     g_consumers.push_back(c);
  174.   }
  175.   {
  176.     BackupConsumer * c = restore;
  177.     g_consumers.push_back(c);
  178.   }
  179.   // Set backup file path
  180.   if (*pargv[0] != NULL) 
  181.   {
  182.     ga_backupPath = *pargv[0];
  183.   }
  184.   return true;
  185. }
  186. void
  187. clearConsumers()
  188. {
  189.   for(Uint32 i= 0; i<g_consumers.size(); i++)
  190.     delete g_consumers[i];
  191.   g_consumers.clear();
  192. }
  193. static bool
  194. checkSysTable(const char *tableName) 
  195. {
  196.   return ga_dont_ignore_systab_0 ||
  197.     (strcmp(tableName, "SYSTAB_0") != 0 &&
  198.      strcmp(tableName, "NDB$EVENTS_0") != 0 &&
  199.      strcmp(tableName, "sys/def/SYSTAB_0") != 0 &&
  200.      strcmp(tableName, "sys/def/NDB$EVENTS_0") != 0);
  201. }
  202. static void
  203. free_data_callback()
  204. {
  205.   for(Uint32 i= 0; i < g_consumers.size(); i++) 
  206.     g_consumers[i]->tuple_free();
  207. }
  208. static void exitHandler(int code)
  209. {
  210.   NDBT_ProgramExit(code);
  211.   if (opt_core)
  212.     abort();
  213.   else
  214.     exit(code);
  215. }
  216. int
  217. main(int argc, char** argv)
  218. {
  219.   NDB_INIT(argv[0]);
  220.   if (!readArguments(&argc, &argv))
  221.   {
  222.     exitHandler(NDBT_FAILED);
  223.   }
  224.   Ndb::setConnectString(opt_connect_str);
  225.   /**
  226.    * we must always load meta data, even if we will only print it to stdout
  227.    */
  228.   RestoreMetaData metaData(ga_backupPath, ga_nodeId, ga_backupId);
  229.   if (!metaData.readHeader())
  230.   {
  231.     ndbout << "Failed to read " << metaData.getFilename() << endl << endl;
  232.     exitHandler(NDBT_FAILED);
  233.   }
  234.   const BackupFormat::FileHeader & tmp = metaData.getFileHeader();
  235.   const Uint32 version = tmp.NdbVersion;
  236.   
  237.   char buf[NDB_VERSION_STRING_BUF_SZ];
  238.   ndbout << "Ndb version in backup files: " 
  239.  <<  getVersionString(version, 0, buf, sizeof(buf)) << endl;
  240.   
  241.   /**
  242.    * check wheater we can restore the backup (right version).
  243.    */
  244.   int res  = metaData.loadContent();
  245.   
  246.   if (res == 0)
  247.   {
  248.     ndbout_c("Restore: Failed to load content");
  249.     exitHandler(NDBT_FAILED);
  250.   }
  251.   
  252.   if (metaData.getNoOfTables() == 0) 
  253.   {
  254.     ndbout_c("Restore: The backup contains no tables ");
  255.     exitHandler(NDBT_FAILED);
  256.   }
  257.   if (!metaData.validateFooter()) 
  258.   {
  259.     ndbout_c("Restore: Failed to validate footer.");
  260.     exitHandler(NDBT_FAILED);
  261.   }
  262.   Uint32 i;
  263.   for(i= 0; i < g_consumers.size(); i++)
  264.   {
  265.     if (!g_consumers[i]->init())
  266.     {
  267.       clearConsumers();
  268.       exitHandler(NDBT_FAILED);
  269.     }
  270.   }
  271.   for(i = 0; i<metaData.getNoOfTables(); i++)
  272.   {
  273.     if (checkSysTable(metaData[i]->getTableName()))
  274.     {
  275.       for(Uint32 j= 0; j < g_consumers.size(); j++)
  276. if (!g_consumers[j]->table(* metaData[i]))
  277. {
  278.   ndbout_c("Restore: Failed to restore table: %s. "
  279.    "Exiting...", 
  280.    metaData[i]->getTableName());
  281.   exitHandler(NDBT_FAILED);
  282.     }
  283.   }
  284.   
  285.   for(i= 0; i < g_consumers.size(); i++)
  286.     if (!g_consumers[i]->endOfTables())
  287.     {
  288.       ndbout_c("Restore: Failed while closing tables");
  289.       exitHandler(NDBT_FAILED);
  290.     } 
  291.   
  292.   if (ga_restore || ga_print) 
  293.   {
  294.     if (ga_restore) 
  295.     {
  296.       RestoreDataIterator dataIter(metaData, &free_data_callback);
  297.       
  298.       // Read data file header
  299.       if (!dataIter.readHeader())
  300.       {
  301. ndbout << "Failed to read header of data file. Exiting..." ;
  302. exitHandler(NDBT_FAILED);
  303.       }
  304.       
  305.       
  306.       while (dataIter.readFragmentHeader(res= 0))
  307.       {
  308. const TupleS* tuple;
  309. while ((tuple = dataIter.getNextTuple(res= 1)) != 0)
  310. {
  311.   if (checkSysTable(tuple->getTable()->getTableName()))
  312.     for(Uint32 i= 0; i < g_consumers.size(); i++) 
  313.       g_consumers[i]->tuple(* tuple);
  314. } // while (tuple != NULL);
  315. if (res < 0)
  316. {
  317.   ndbout_c("Restore: An error occured while restoring data. "
  318.    "Exiting...");
  319.   exitHandler(NDBT_FAILED);
  320. }
  321. if (!dataIter.validateFragmentFooter()) {
  322.   ndbout_c("Restore: Error validating fragment footer. "
  323.    "Exiting...");
  324.   exitHandler(NDBT_FAILED);
  325. }
  326.       } // while (dataIter.readFragmentHeader(res))
  327.       
  328.       if (res < 0)
  329.       {
  330. err << "Restore: An error occured while restoring data. Exiting... "
  331.     << "res=" << res << endl;
  332. exitHandler(NDBT_FAILED);
  333.       }
  334.       
  335.       
  336.       dataIter.validateFooter(); //not implemented
  337.       
  338.       for (i= 0; i < g_consumers.size(); i++)
  339. g_consumers[i]->endOfTuples();
  340.       RestoreLogIterator logIter(metaData);
  341.       if (!logIter.readHeader())
  342.       {
  343. err << "Failed to read header of data file. Exiting..." << endl;
  344. exitHandler(NDBT_FAILED);
  345.       }
  346.       
  347.       const LogEntry * logEntry = 0;
  348.       while ((logEntry = logIter.getNextLogEntry(res= 0)) != 0)
  349.       {
  350. if (checkSysTable(logEntry->m_table->getTableName()))
  351.   for(Uint32 i= 0; i < g_consumers.size(); i++)
  352.     g_consumers[i]->logEntry(* logEntry);
  353.       }
  354.       if (res < 0)
  355.       {
  356. err << "Restore: An restoring the data log. Exiting... res=" 
  357.     << res << endl;
  358. exitHandler(NDBT_FAILED);
  359.       }
  360.       logIter.validateFooter(); //not implemented
  361.       for (i= 0; i < g_consumers.size(); i++)
  362. g_consumers[i]->endOfLogEntrys();
  363.       for(i = 0; i<metaData.getNoOfTables(); i++)
  364.       {
  365. if (checkSysTable(metaData[i]->getTableName()))
  366. {
  367.   for(Uint32 j= 0; j < g_consumers.size(); j++)
  368.     if (!g_consumers[j]->finalize_table(* metaData[i]))
  369.     {
  370.       ndbout_c("Restore: Failed to finalize restore table: %s. "
  371.        "Exiting...", 
  372.        metaData[i]->getTableName());
  373.       exitHandler(NDBT_FAILED);
  374.     } 
  375. }
  376.       }
  377.     }
  378.   }
  379.   clearConsumers();
  380.   return NDBT_ProgramExit(NDBT_OK);
  381. } // main
  382. template class Vector<BackupConsumer*>;