mariadb/ndb/tools/restore/restore_main.cpp

408 lines
10 KiB
C++
Raw Normal View History

2004-04-14 10:53:21 +02:00
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
#include <ndb_opts.h>
2004-04-14 10:53:21 +02:00
#include <Vector.hpp>
#include <ndb_limits.h>
Merge NDB patches into 4.1-clone, below is list of changesets # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.1 # Removal of NDBT_Table # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.2 # Removal of NDBT_Table # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.3 # Fix for crashing AT # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1858.1.4 # Bug fixes in testIndex # -------------------------------------------- # 04/04/13 joreland@mysql.com 1.1866.1.5 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/tmp # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.1.5 # Fix for takeover when accessing indexes. # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1866.1.6 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/tmp # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.1 # Fixed error handling of fire_trigger_ord + lqhkeyref w.r.t indexes # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.2 # Simple retry mechanism in UTIL # Helps testIndex -n BuildDuring _a lot_ # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.3 # Misc fixes to test prg. # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.4 # Allow more retires on application errors # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1858.2.5 # Pass no of rows fetched in SUB_SYNC_CONTINUE_REQ # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1869 # wl1714 # Improve parallellism # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1870 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/wl1714 # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1866.1.7 # Merge # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1871 # Merge mysql.com:/home/jonas/src/wl1714 # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1872 # Fix for testScan -n ScanReadError5030 # -------------------------------------------- # 04/04/14 joreland@mysql.com 1.1873 # fix testDict -n FragmentType* # -------------------------------------------- # 04/04/14 johan@stingray.(none) 1.1866.2.1 # small fixes # -------------------------------------------- # 04/04/14 johan@stingray.(none) 1.1874 # Merge jandersson@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into stingray.(none):/space/bk/rep/mysql-4.1-ndb # -------------------------------------------- # 04/04/14 johan@stingray.(none) 1.1875 # handle rep node as an api node # -------------------------------------------- # 04/04/14 pekka@mysql.com 1.1873.1.1 # Fix for NDBT_Table removal # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1873.1.2 # Uninitialized var. # -------------------------------------------- # 04/04/15 johan@stingray.(none) 1.1876 # Merge jandersson@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into stingray.(none):/space/bk/rep/mysql-4.1-ndb # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1873.1.3 # Write pid before changing user # (as runas user probably doesn't have permissions on pid-dir) # -------------------------------------------- # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1862.1.3 # Fix printout of varchars # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1877 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mc03.ndb.mysql.com:/space/ndb/tmp # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1862.1.4 # Hmm.. don't print attr as many times as length of array # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1878 # Merge mc03.ndb.mysql.com:/space/ndb/mysql-4.1-ndb # into mc03.ndb.mysql.com:/space/ndb/tmp # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1876.1.1 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/04/15 joreland@mysql.com 1.1877.1.1 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/04/15 ndb@mc03.ndb.mysql.com 1.1879 # Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1-ndb # into mc03.ndb.mysql.com:/space/ndb/tmp # -------------------------------------------- # 04/04/17 joreland@mysql.com 1.1880 # LCP bug when restarting ops take's longer than DIH sending a new lcp ord # Solution: # Send LCP_FRAG_REP after restarting all ops # -------------------------------------------- # 04/04/18 joreland@mysql.com 1.1881 # Missspelled ERROR_INSERT # -------------------------------------------- # 04/04/18 joreland@mysql.com 1.1882 # Added possibility to log only distributed signals # -------------------------------------------- # 04/04/22 joreland@mysql.com 1.1883 # Removed dependancy to libstdc++ # * pure virtual functions "__cxa_pure_virtual" is defined in libstd++ -> # remove all pure virtual functions # -------------------------------------------- # 04/04/23 joreland@mysql.com 1.1884 # Various minor bug fixes for problems found while compiling # with icc # -------------------------------------------- # -------------------------------------------- # 04/04/25 joreland@mysql.com 1.1885 # Removed debug code (joreland:1.1875) # -------------------------------------------- # 04/04/26 ejonore@mc03.ndb.mysql.com 1.1862.1.5 # Lock pages in memory _after_ daemon-mode (exec/fork) # -------------------------------------------- # 04/04/27 ejonore@mc03.ndb.mysql.com 1.1862.1.6 # 1) Trap abort() # 2) StopStart/StopAborted events # 3) warning if memlock fails # 4) use g_logger more often (instead of ndbout) # # -------------------------------------------- # 04/04/27 joreland@mysql.com 1.1886 # bug fix for a bug in wl1714 + software upgrade # -------------------------------------------- # 04/04/27 joreland@mysql.com 1.1887 # Cset exclude: joreland@mysql.com|ChangeSet|20040422160720|05374 # -------------------------------------------- # 04/04/27 joreland@mysql.com 1.1888 # removed libstc++ second try... # -------------------------------------------- # 04/04/28 ejonore@mc03.ndb.mysql.com 1.1862.1.7 # 1) Don't lock FUTURE pages but only current # 2) Do this when SIZEALT has completed # -------------------------------------------- # 04/04/30 joreland@mysql.com 1.1889 # Merge jonas@orca:/home/ndb/releases/mysql-4.1-ndb-3.4.x # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- # 04/05/03 ndb@mc03.ndb.mysql.com 1.1862.1.8 # Version update # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.3.1 # Changed restart behavior. # Use "angel" process which monitor "real" process # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.1.9 # Merge jonas@orca:/home/ndb/releases/mysql-4.1-ndb-3.4.x # into mysql.com:/home/jonas/src/mysql-4.1-ndb-3.4.x # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1890 # Merge B2 fixes # -------------------------------------------- # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.1.10 # Better handling of children terminations # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1862.1.11 # Fixes for angel-restarting # -------------------------------------------- # 04/05/03 joreland@mysql.com 1.1891 # Merge mysql.com:/home/jonas/src/mysql-4.1-ndb-3.4.x # into mysql.com:/home/jonas/src/mysql-4.1-ndb # -------------------------------------------- #
2004-05-04 11:19:19 +02:00
#include <NdbTCP.h>
#include <NdbOut.hpp>
#include "consumer_restore.hpp"
#include "consumer_printer.hpp"
2004-04-14 10:53:21 +02:00
extern FilteredNdbOut err;
extern FilteredNdbOut info;
extern FilteredNdbOut debug;
static int ga_nodeId = 0;
static int ga_nParallelism = 128;
2004-04-14 10:53:21 +02:00
static int ga_backupId = 0;
static bool ga_dont_ignore_systab_0 = false;
2004-06-10 12:01:47 +00:00
static Vector<class BackupConsumer *> g_consumers;
2004-04-14 10:53:21 +02:00
static const char* ga_backupPath = "." DIR_SEPARATOR;
2004-04-14 10:53:21 +02:00
NDB_STD_OPTS_VARS;
2004-04-14 10:53:21 +02:00
/**
* print and restore flags
*/
static bool ga_restore = false;
static bool ga_print = false;
static int _print = 0;
static int _print_meta = 0;
static int _print_data = 0;
static int _print_log = 0;
static int _restore_data = 0;
static int _restore_meta = 0;
2004-04-14 10:53:21 +02:00
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_restore"),
{ "connect", 'c', "same as --connect-string",
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "nodeid", 'n', "Backup files from node with id",
(gptr*) &ga_nodeId, (gptr*) &ga_nodeId, 0,
GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "backupid", 'b', "Backup id",
(gptr*) &ga_backupId, (gptr*) &ga_backupId, 0,
GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "restore_data", 'r',
"Restore table data/logs into NDB Cluster using NDBAPI",
(gptr*) &_restore_data, (gptr*) &_restore_data, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "restore_meta", 'm',
"Restore meta data into NDB Cluster using NDBAPI",
(gptr*) &_restore_meta, (gptr*) &_restore_meta, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "parallelism", 'p',
"No of parallel transactions during restore of data."
"(parallelism can be 1 to 1024)",
(gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0,
2004-11-18 21:15:18 +00:00
GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 },
{ "print", 256, "Print data and log to stdout",
(gptr*) &_print, (gptr*) &_print, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "print_data", 257, "Print data to stdout",
(gptr*) &_print_data, (gptr*) &_print_data, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "print_meta", 258, "Print meta data to stdout",
(gptr*) &_print_meta, (gptr*) &_print_meta, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "print_log", 259, "Print log to stdout",
(gptr*) &_print_log, (gptr*) &_print_log, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "dont_ignore_systab_0", 'f',
"Experimental. Do not ignore system table during restore.",
(gptr*) &ga_dont_ignore_systab_0, (gptr*) &ga_dont_ignore_systab_0, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
2004-04-14 10:53:21 +02:00
static void short_usage_sub(void)
{
printf("Usage: %s [OPTIONS] [<path to backup files>]\n", my_progname);
}
static void usage()
{
short_usage_sub();
ndb_std_print_version();
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
ndb_std_get_one_option(optid, opt, argument ? argument :
"d:t:O,/tmp/ndb_restore.trace");
switch (optid) {
2004-11-18 21:15:18 +00:00
case 'n':
if (ga_nodeId == 0)
{
printf("Error in --nodeid,-n setting, see --help\n");
2004-11-18 21:15:18 +00:00
exit(1);
}
break;
2004-11-18 21:15:18 +00:00
case 'b':
if (ga_backupId == 0)
{
printf("Error in --backupid,-b setting, see --help\n");
2004-11-18 21:15:18 +00:00
exit(1);
}
break;
}
return 0;
}
bool
readArguments(int *pargc, char*** pargv)
{
const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 };
load_defaults("my",load_default_groups,pargc,pargv);
2004-11-18 21:15:18 +00:00
if (handle_options(pargc, pargv, my_long_options, get_one_option))
{
exit(1);
}
BackupPrinter* printer = new BackupPrinter();
if (printer == NULL)
return false;
BackupRestore* restore = new BackupRestore(ga_nParallelism);
if (restore == NULL)
{
2004-04-14 10:53:21 +02:00
delete printer;
return false;
}
if (_print)
{
ga_print = true;
ga_restore = true;
printer->m_print = true;
}
if (_print_meta)
{
ga_print = true;
printer->m_print_meta = true;
}
if (_print_data)
{
ga_print = true;
printer->m_print_data = true;
}
if (_print_log)
{
ga_print = true;
printer->m_print_log = true;
}
if (_restore_data)
{
ga_restore = true;
restore->m_restore = true;
}
if (_restore_meta)
{
// ga_restore = true;
restore->m_restore_meta = true;
}
{
2004-06-10 01:38:38 +00:00
BackupConsumer * c = printer;
2004-04-14 10:53:21 +02:00
g_consumers.push_back(c);
}
{
2004-06-10 01:38:38 +00:00
BackupConsumer * c = restore;
2004-04-14 10:53:21 +02:00
g_consumers.push_back(c);
}
// Set backup file path
if (*pargv[0] != NULL)
2004-04-14 10:53:21 +02:00
{
ga_backupPath = *pargv[0];
2004-04-14 10:53:21 +02:00
}
return true;
}
void
clearConsumers()
{
2004-06-10 12:01:47 +00:00
for(Uint32 i= 0; i<g_consumers.size(); i++)
2004-04-14 10:53:21 +02:00
delete g_consumers[i];
g_consumers.clear();
}
static bool
2004-04-14 10:53:21 +02:00
checkSysTable(const char *tableName)
{
return ga_dont_ignore_systab_0 ||
(strcmp(tableName, "SYSTAB_0") != 0 &&
strcmp(tableName, "NDB$EVENTS_0") != 0 &&
strcmp(tableName, "sys/def/SYSTAB_0") != 0 &&
strcmp(tableName, "sys/def/NDB$EVENTS_0") != 0);
}
static void
free_data_callback()
{
2004-06-10 12:01:47 +00:00
for(Uint32 i= 0; i < g_consumers.size(); i++)
g_consumers[i]->tuple_free();
}
2004-04-14 10:53:21 +02:00
int
main(int argc, char** argv)
2004-04-14 10:53:21 +02:00
{
NDB_INIT(argv[0]);
if (!readArguments(&argc, &argv))
2004-04-14 10:53:21 +02:00
{
return -1;
}
Ndb::setConnectString(opt_connect_str);
2004-04-14 10:53:21 +02:00
/**
* we must always load meta data, even if we will only print it to stdout
*/
RestoreMetaData metaData(ga_backupPath, ga_nodeId, ga_backupId);
if (!metaData.readHeader())
{
ndbout << "Failed to read " << metaData.getFilename() << endl << endl;
return -1;
}
const BackupFormat::FileHeader & tmp = metaData.getFileHeader();
const Uint32 version = tmp.NdbVersion;
ndbout << "Ndb version in backup files: "
<< getVersionString(version, 0) << endl;
2004-04-14 10:53:21 +02:00
/**
* check wheater we can restore the backup (right version).
2004-04-14 10:53:21 +02:00
*/
int res = metaData.loadContent();
if (res == 0)
2004-04-14 10:53:21 +02:00
{
ndbout_c("Restore: Failed to load content");
return -1;
}
if (metaData.getNoOfTables() == 0)
2004-04-14 10:53:21 +02:00
{
ndbout_c("Restore: The backup contains no tables ");
2004-04-14 10:53:21 +02:00
return -1;
}
if (!metaData.validateFooter())
{
ndbout_c("Restore: Failed to validate footer.");
return -1;
}
2004-07-09 12:48:32 +02:00
Uint32 i;
for(i= 0; i < g_consumers.size(); i++)
2004-04-14 10:53:21 +02:00
{
if (!g_consumers[i]->init())
{
clearConsumers();
return -11;
}
}
2004-07-09 12:48:32 +02:00
for(i = 0; i<metaData.getNoOfTables(); i++)
2004-04-14 10:53:21 +02:00
{
if (checkSysTable(metaData[i]->getTableName()))
{
2004-06-10 12:01:47 +00:00
for(Uint32 j= 0; j < g_consumers.size(); j++)
2004-06-10 01:38:38 +00:00
if (!g_consumers[j]->table(* metaData[i]))
{
ndbout_c("Restore: Failed to restore table: %s. "
"Exiting...",
metaData[i]->getTableName());
return -11;
}
2004-04-14 10:53:21 +02:00
}
}
2004-09-08 22:30:05 +02:00
for(i= 0; i < g_consumers.size(); i++)
if (!g_consumers[i]->endOfTables())
{
ndbout_c("Restore: Failed while closing tables");
return -11;
}
2004-04-14 10:53:21 +02:00
if (ga_restore || ga_print)
{
2004-09-08 22:30:05 +02:00
if (ga_restore)
{
RestoreDataIterator dataIter(metaData, &free_data_callback);
// Read data file header
if (!dataIter.readHeader())
2004-04-14 10:53:21 +02:00
{
2004-09-08 22:30:05 +02:00
ndbout << "Failed to read header of data file. Exiting..." ;
return -11;
}
while (dataIter.readFragmentHeader(res= 0))
{
const TupleS* tuple;
while ((tuple = dataIter.getNextTuple(res= 1)) != 0)
2004-04-14 10:53:21 +02:00
{
2004-09-08 22:30:05 +02:00
if (checkSysTable(tuple->getTable()->getTableName()))
for(Uint32 i= 0; i < g_consumers.size(); i++)
g_consumers[i]->tuple(* tuple);
} // while (tuple != NULL);
2004-04-14 10:53:21 +02:00
if (res < 0)
{
2004-09-08 22:30:05 +02:00
ndbout_c("Restore: An error occured while restoring data. "
"Exiting...");
2004-04-14 10:53:21 +02:00
return -1;
}
2004-09-08 22:30:05 +02:00
if (!dataIter.validateFragmentFooter()) {
ndbout_c("Restore: Error validating fragment footer. "
"Exiting...");
2004-04-14 10:53:21 +02:00
return -1;
}
2004-09-08 22:30:05 +02:00
} // while (dataIter.readFragmentHeader(res))
if (res < 0)
{
2004-11-18 21:15:18 +00:00
err << "Restore: An error occured while restoring data. Exiting... "
<< "res=" << res << endl;
2004-09-08 22:30:05 +02:00
return -1;
}
dataIter.validateFooter(); //not implemented
for (i= 0; i < g_consumers.size(); i++)
g_consumers[i]->endOfTuples();
2004-09-08 22:30:05 +02:00
RestoreLogIterator logIter(metaData);
if (!logIter.readHeader())
{
err << "Failed to read header of data file. Exiting..." << endl;
return -1;
}
const LogEntry * logEntry = 0;
while ((logEntry = logIter.getNextLogEntry(res= 0)) != 0)
{
if (checkSysTable(logEntry->m_table->getTableName()))
for(Uint32 i= 0; i < g_consumers.size(); i++)
g_consumers[i]->logEntry(* logEntry);
}
if (res < 0)
{
2004-11-18 21:15:18 +00:00
err << "Restore: An restoring the data log. Exiting... res="
<< res << endl;
2004-09-08 22:30:05 +02:00
return -1;
2004-04-14 10:53:21 +02:00
}
2004-09-08 22:30:05 +02:00
logIter.validateFooter(); //not implemented
for (i= 0; i < g_consumers.size(); i++)
g_consumers[i]->endOfLogEntrys();
2004-10-01 02:38:03 +00:00
for(i = 0; i<metaData.getNoOfTables(); i++)
{
if (checkSysTable(metaData[i]->getTableName()))
{
for(Uint32 j= 0; j < g_consumers.size(); j++)
if (!g_consumers[j]->finalize_table(* metaData[i]))
{
ndbout_c("Restore: Failed to finalize restore table: %s. "
"Exiting...",
metaData[i]->getTableName());
return -11;
}
}
}
2004-09-08 22:30:05 +02:00
}
2004-04-14 10:53:21 +02:00
}
clearConsumers();
return 0;
2004-04-14 10:53:21 +02:00
} // main
2004-08-18 14:26:39 +00:00
template class Vector<BackupConsumer*>;