diff options
author | tomas@poseidon.mysql.com <> | 2007-03-09 00:55:46 +0700 |
---|---|---|
committer | tomas@poseidon.mysql.com <> | 2007-03-09 00:55:46 +0700 |
commit | cb4e5fbe00437c9d27ce50272614cc23edbada73 (patch) | |
tree | e2c451c8a5be685cf1ff69ad5b7fe75df34bf2b6 /ndb/tools | |
parent | 46c2981e0532644eebda0ead67aa146194a2b632 (diff) | |
parent | 30c58170fd627da7d37af95a08f509cc9c692efe (diff) | |
download | mariadb-git-cb4e5fbe00437c9d27ce50272614cc23edbada73.tar.gz |
Merge poseidon.mysql.com:/home/tomas/mysql-5.0-telco-gca-ndb_restore
into poseidon.mysql.com:/home/tomas/mysql-5.0-ndb
Diffstat (limited to 'ndb/tools')
-rw-r--r-- | ndb/tools/restore/Restore.cpp | 60 | ||||
-rw-r--r-- | ndb/tools/restore/Restore.hpp | 18 | ||||
-rw-r--r-- | ndb/tools/restore/consumer_printer.cpp | 22 | ||||
-rw-r--r-- | ndb/tools/restore/restore_main.cpp | 401 |
4 files changed, 418 insertions, 83 deletions
diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp index 8b2e9a799a4..7ca7e91acf0 100644 --- a/ndb/tools/restore/Restore.cpp +++ b/ndb/tools/restore/Restore.cpp @@ -23,6 +23,8 @@ #include <SimpleProperties.hpp> #include <signaldata/DictTabInfo.hpp> +extern NdbRecordPrintFormat g_ndbrecord_print_format; + Uint16 Twiddle16(Uint16 in); // Byte shift 16-bit data Uint32 Twiddle32(Uint32 in); // Byte shift 32-bit data Uint64 Twiddle64(Uint64 in); // Byte shift 64-bit data @@ -118,6 +120,8 @@ RestoreMetaData::loadContent() return 0; } } + if (! markSysTables()) + return 0; if(!readGCPEntry()) return 0; @@ -176,6 +180,49 @@ RestoreMetaData::readMetaTableDesc() { } bool +RestoreMetaData::markSysTables() +{ + Uint32 i; + for (i = 0; i < getNoOfTables(); i++) { + TableS* table = allTables[i]; + table->m_local_id = i; + const char* tableName = table->getTableName(); + if ( // XXX should use type + 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) + table->isSysTable = true; + } + for (i = 0; i < getNoOfTables(); i++) { + TableS* blobTable = allTables[i]; + const char* blobTableName = blobTable->getTableName(); + // yet another match blob + int cnt, id1, id2; + char buf[256]; + cnt = sscanf(blobTableName, "%[^/]/%[^/]/NDB$BLOB_%d_%d", + buf, buf, &id1, &id2); + if (cnt == 4) { + Uint32 j; + for (j = 0; j < getNoOfTables(); j++) { + TableS* table = allTables[j]; + if (table->getTableId() == (Uint32) id1) { + if (table->isSysTable) + blobTable->isSysTable = true; + blobTable->m_main_table = table; + break; + } + } + if (j == getNoOfTables()) { + err << "Restore: Bad primary table id in " << blobTableName << endl; + return false; + } + } + } + return true; +} + +bool RestoreMetaData::readGCPEntry() { Uint32 data[4]; @@ -259,6 +306,8 @@ TableS::TableS(Uint32 version, NdbTableImpl* tableImpl) m_max_auto_val= 0; m_noOfRecords= 0; backupVersion = version; + isSysTable = false; + m_main_table = NULL; for (int i = 0; i < tableImpl->getNoOfColumns(); i++) createAttr(tableImpl->getColumn(i)); @@ -704,6 +753,7 @@ bool RestoreDataIterator::readFragmentHeader(int & ret) return false; } + info.setLevel(254); info << "_____________________________________________________" << endl << "Processing data in table: " << m_currentTable->getTableName() << "(" << Header.TableId << ") fragment " @@ -924,13 +974,13 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){ if (data.null) { - ndbout << "<NULL>"; + ndbout << g_ndbrecord_print_format.null_string; return ndbout; } NdbRecAttr tmprec(0); tmprec.setup(desc.m_column, (char *)data.void_value); - ndbout << tmprec; + ndbrecattr_print_formatted(ndbout, tmprec, g_ndbrecord_print_format); return ndbout; } @@ -939,17 +989,15 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){ NdbOut& operator<<(NdbOut& ndbout, const TupleS& tuple) { - ndbout << tuple.getTable()->getTableName() << "; "; for (int i = 0; i < tuple.getNoOfAttributes(); i++) { + if (i > 0) + ndbout << g_ndbrecord_print_format.fields_terminated_by; AttributeData * attr_data = tuple.getData(i); const AttributeDesc * attr_desc = tuple.getDesc(i); const AttributeS attr = {attr_desc, *attr_data}; debug << i << " " << attr_desc->m_column->getName(); ndbout << attr; - - if (i != (tuple.getNoOfAttributes() - 1)) - ndbout << delimiter << " "; } // for return ndbout; } diff --git a/ndb/tools/restore/Restore.hpp b/ndb/tools/restore/Restore.hpp index 8b660698d1a..66e00d88dfe 100644 --- a/ndb/tools/restore/Restore.hpp +++ b/ndb/tools/restore/Restore.hpp @@ -25,8 +25,6 @@ #include <ndb_version.h> #include <version.h> -#define delimiter ";" - const int FileNameLenC = 256; const int TableNameLenC = 256; const int AttrNameLenC = 256; @@ -143,6 +141,10 @@ class TableS { int pos; + bool isSysTable; + TableS *m_main_table; + Uint32 m_local_id; + Uint64 m_noOfRecords; Vector<FragmentInfo *> m_fragmentInfo; @@ -156,6 +158,9 @@ public: Uint32 getTableId() const { return m_dictTable->getTableId(); } + Uint32 getLocalId() const { + return m_local_id; + } Uint32 getNoOfRecords() const { return m_noOfRecords; } @@ -235,6 +240,14 @@ public: return allAttributesDesc[attributeId]; } + bool getSysTable() const { + return isSysTable; + } + + const TableS *getMainTable() const { + return m_main_table; + } + TableS& operator=(TableS& org) ; }; // TableS; @@ -285,6 +298,7 @@ class RestoreMetaData : public BackupFile { Vector<TableS *> allTables; bool readMetaFileHeader(); bool readMetaTableDesc(); + bool markSysTables(); bool readGCPEntry(); bool readFragmentInfo(); diff --git a/ndb/tools/restore/consumer_printer.cpp b/ndb/tools/restore/consumer_printer.cpp index 8fe9805c39c..e0525522284 100644 --- a/ndb/tools/restore/consumer_printer.cpp +++ b/ndb/tools/restore/consumer_printer.cpp @@ -14,6 +14,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "consumer_printer.hpp" +extern FilteredNdbOut info; +extern NdbRecordPrintFormat g_ndbrecord_print_format; +extern const char *tab_path; bool BackupPrinter::table(const TableS & tab) @@ -21,7 +24,8 @@ BackupPrinter::table(const TableS & tab) if (m_print || m_print_meta) { m_ndbout << tab; - ndbout_c("Successfully printed table: %s", tab.m_dictTable->getName()); + info.setLevel(254); + info << "Successfully printed table: ", tab.m_dictTable->getName(); } return true; } @@ -31,7 +35,14 @@ BackupPrinter::tuple(const TupleS & tup) { m_dataCount++; if (m_print || m_print_data) - m_ndbout << tup << endl; + { + if (m_ndbout.m_out == info.m_out) + { + info.setLevel(254); + info << tup.getTable()->getTableName() << "; "; + } + m_ndbout << tup << g_ndbrecord_print_format.lines_terminated_by; + } } void @@ -47,8 +58,9 @@ BackupPrinter::endOfLogEntrys() { if (m_print || m_print_log) { - ndbout << "Printed " << m_dataCount << " tuples and " - << m_logCount << " log entries" - << " to stdout." << endl; + info.setLevel(254); + info << "Printed " << m_dataCount << " tuples and " + << m_logCount << " log entries" + << " to stdout." << endl; } } diff --git a/ndb/tools/restore/restore_main.cpp b/ndb/tools/restore/restore_main.cpp index c17e3fbabe2..52a913d73b4 100644 --- a/ndb/tools/restore/restore_main.cpp +++ b/ndb/tools/restore/restore_main.cpp @@ -18,7 +18,9 @@ #include <Vector.hpp> #include <ndb_limits.h> #include <NdbTCP.h> +#include <NdbMem.h> #include <NdbOut.hpp> +#include <OutputStream.hpp> #include <NDBT_ReturnCodes.h> #include "consumer_restore.hpp" @@ -33,8 +35,18 @@ static int ga_nParallelism = 128; static int ga_backupId = 0; static bool ga_dont_ignore_systab_0 = false; static Vector<class BackupConsumer *> g_consumers; +static BackupPrinter* g_printer = NULL; -static const char* ga_backupPath = "." DIR_SEPARATOR; +static const char* default_backupPath = "." DIR_SEPARATOR; +static const char* ga_backupPath = default_backupPath; + +const char *opt_ndb_database= NULL; +const char *opt_ndb_table= NULL; +unsigned int opt_verbose; +unsigned int opt_hex_format; +Vector<BaseString> g_databases; +Vector<BaseString> g_tables; +NdbRecordPrintFormat g_ndbrecord_print_format; NDB_STD_OPTS_VARS; @@ -53,6 +65,28 @@ BaseString g_options("ndb_restore"); const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 }; +enum ndb_restore_options { + OPT_PRINT= NDB_STD_OPTIONS_LAST, + OPT_PRINT_DATA, + OPT_PRINT_LOG, + OPT_PRINT_META, + OPT_BACKUP_PATH, + OPT_HEX_FORMAT, + OPT_FIELDS_ENCLOSED_BY, + OPT_FIELDS_TERMINATED_BY, + OPT_FIELDS_OPTIONALLY_ENCLOSED_BY, + OPT_LINES_TERMINATED_BY, + OPT_APPEND, + OPT_VERBOSE +}; +static const char *opt_fields_enclosed_by= NULL; +static const char *opt_fields_terminated_by= NULL; +static const char *opt_fields_optionally_enclosed_by= NULL; +static const char *opt_lines_terminated_by= NULL; + +static const char *tab_path= NULL; +static int opt_append; + static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_restore"), @@ -78,22 +112,56 @@ static struct my_option my_long_options[] = "(parallelism can be 1 to 1024)", (gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0, GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 }, - { "print", 256, "Print data and log to stdout", + { "print", OPT_PRINT, "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", + { "print_data", OPT_PRINT_DATA, "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", + { "print_meta", OPT_PRINT_META, "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", + { "print_log", OPT_PRINT_LOG, "Print log to stdout", (gptr*) &_print_log, (gptr*) &_print_log, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "backup_path", OPT_BACKUP_PATH, "Path to backup files", + (gptr*) &ga_backupPath, (gptr*) &ga_backupPath, 0, + GET_STR, REQUIRED_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 }, + { "fields-enclosed-by", OPT_FIELDS_ENCLOSED_BY, + "Fields are enclosed by ...", + (gptr*) &opt_fields_enclosed_by, (gptr*) &opt_fields_enclosed_by, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "fields-terminated-by", OPT_FIELDS_TERMINATED_BY, + "Fields are terminated by ...", + (gptr*) &opt_fields_terminated_by, + (gptr*) &opt_fields_terminated_by, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "fields-optionally-enclosed-by", OPT_FIELDS_OPTIONALLY_ENCLOSED_BY, + "Fields are optionally enclosed by ...", + (gptr*) &opt_fields_optionally_enclosed_by, + (gptr*) &opt_fields_optionally_enclosed_by, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "hex", OPT_HEX_FORMAT, "print binary types in hex format", + (gptr*) &opt_hex_format, (gptr*) &opt_hex_format, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "tab", 'T', "Creates tab separated textfile for each table to " + "given path. (creates .txt files)", + (gptr*) &tab_path, (gptr*) &tab_path, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "append", OPT_APPEND, "for --tab append data to file", + (gptr*) &opt_append, (gptr*) &opt_append, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "lines-terminated-by", OPT_LINES_TERMINATED_BY, "", + (gptr*) &opt_lines_terminated_by, (gptr*) &opt_lines_terminated_by, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "verbose", OPT_VERBOSE, + "verbosity", + (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, + GET_INT, REQUIRED_ARG, 1, 0, 255, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -119,19 +187,26 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif ndb_std_get_one_option(optid, opt, argument); switch (optid) { + case OPT_VERBOSE: + info.setThreshold(255-opt_verbose); + break; case 'n': if (ga_nodeId == 0) { - printf("Error in --nodeid,-n setting, see --help\n"); + err << "Error in --nodeid,-n setting, see --help"; exit(NDBT_ProgramExit(NDBT_WRONGARGS)); } + info.setLevel(254); + info << "Nodeid = " << ga_nodeId << endl; break; case 'b': if (ga_backupId == 0) { - printf("Error in --backupid,-b setting, see --help\n"); + err << "Error in --backupid,-b setting, see --help"; exit(NDBT_ProgramExit(NDBT_WRONGARGS)); } + info.setLevel(254); + info << "Backup Id = " << ga_backupId << endl; break; } return 0; @@ -139,20 +214,26 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), bool readArguments(int *pargc, char*** pargv) { + Uint32 i; + debug << "Load defaults" << endl; + const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 }; + load_defaults("my",load_default_groups,pargc,pargv); + debug << "handle_options" << endl; if (handle_options(pargc, pargv, my_long_options, get_one_option)) { exit(NDBT_ProgramExit(NDBT_WRONGARGS)); } - BackupPrinter* printer = new BackupPrinter(); - if (printer == NULL) + g_printer = new BackupPrinter(); + if (g_printer == NULL) return false; BackupRestore* restore = new BackupRestore(ga_nParallelism); if (restore == NULL) { - delete printer; + delete g_printer; + g_printer = NULL; return false; } @@ -160,22 +241,22 @@ readArguments(int *pargc, char*** pargv) { ga_print = true; ga_restore = true; - printer->m_print = true; + g_printer->m_print = true; } if (_print_meta) { ga_print = true; - printer->m_print_meta = true; + g_printer->m_print_meta = true; } if (_print_data) { ga_print = true; - printer->m_print_data = true; + g_printer->m_print_data = true; } if (_print_log) { ga_print = true; - printer->m_print_log = true; + g_printer->m_print_log = true; } if (_restore_data) @@ -191,19 +272,64 @@ readArguments(int *pargc, char*** pargv) } { - BackupConsumer * c = printer; + BackupConsumer * c = g_printer; g_consumers.push_back(c); } { BackupConsumer * c = restore; g_consumers.push_back(c); } - // Set backup file path - if (*pargv[0] != NULL) + for (;;) { - ga_backupPath = *pargv[0]; + int i= 0; + if (ga_backupPath == default_backupPath) + { + // Set backup file path + if ((*pargv)[i] == NULL) + break; + ga_backupPath = (*pargv)[i++]; + } + if ((*pargv)[i] == NULL) + break; + g_databases.push_back((*pargv)[i++]); + while ((*pargv)[i] != NULL) + { + g_tables.push_back((*pargv)[i++]); + } + break; } - + info.setLevel(254); + info << "backup path = " << ga_backupPath << endl; + if (g_databases.size() > 0) + { + info << "Restoring only from database " << g_databases[0].c_str() << endl; + if (g_tables.size() > 0) + info << "Restoring only tables:"; + for (unsigned i= 0; i < g_tables.size(); i++) + { + info << " " << g_tables[i].c_str(); + } + if (g_tables.size() > 0) + info << endl; + } + /* + the below formatting follows the formatting from mysqldump + do not change unless to adopt to changes in mysqldump + */ + g_ndbrecord_print_format.fields_enclosed_by= + opt_fields_enclosed_by ? opt_fields_enclosed_by : ""; + g_ndbrecord_print_format.fields_terminated_by= + opt_fields_terminated_by ? opt_fields_terminated_by : "\t"; + g_ndbrecord_print_format.fields_optionally_enclosed_by= + opt_fields_optionally_enclosed_by ? opt_fields_optionally_enclosed_by : ""; + g_ndbrecord_print_format.lines_terminated_by= + opt_lines_terminated_by ? opt_lines_terminated_by : "\n"; + if (g_ndbrecord_print_format.fields_optionally_enclosed_by[0] == '\0') + g_ndbrecord_print_format.null_string= "\\N"; + else + g_ndbrecord_print_format.null_string= ""; + g_ndbrecord_print_format.hex_prefix= ""; + g_ndbrecord_print_format.hex_format= opt_hex_format; return true; } @@ -215,14 +341,81 @@ clearConsumers() g_consumers.clear(); } -static bool -checkSysTable(const char *tableName) +static inline bool +checkSysTable(const TableS* table) +{ + return ga_dont_ignore_systab_0 || ! table->getSysTable(); +} + +static inline bool +checkSysTable(const RestoreMetaData& metaData, uint i) { - 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); + assert(i < metaData.getNoOfTables()); + return checkSysTable(metaData[i]); +} + +static inline bool +isBlobTable(const TableS* table) +{ + return table->getMainTable() != NULL; +} + +static inline bool +isIndex(const TableS* table) +{ + const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* table->m_dictTable); + return (int) tmptab.m_indexType != (int) NdbDictionary::Index::Undefined; +} + +static inline bool +checkDbAndTableName(const TableS* table) +{ + if (g_tables.size() == 0 && + g_databases.size() == 0) + return true; + if (g_databases.size() == 0) + g_databases.push_back("TEST_DB"); + + // Filter on the main table name for indexes and blobs + const char *table_name; + if (isBlobTable(table)) + table_name= table->getMainTable()->getTableName(); + else if (isIndex(table)) + table_name= + NdbTableImpl::getImpl(*table->m_dictTable).m_primaryTable.c_str(); + else + table_name= table->getTableName(); + + unsigned i; + for (i= 0; i < g_databases.size(); i++) + { + if (strncmp(table_name, g_databases[i].c_str(), + g_databases[i].length()) == 0 && + table_name[g_databases[i].length()] == '/') + { + // we have a match + if (g_databases.size() > 1 || g_tables.size() == 0) + return true; + break; + } + } + if (i == g_databases.size()) + return false; // no match found + + while (*table_name != '/') table_name++; + table_name++; + while (*table_name != '/') table_name++; + table_name++; + + for (i= 0; i < g_tables.size(); i++) + { + if (strcmp(table_name, g_tables[i].c_str()) == 0) + { + // we have a match + return true; + } + } + return false; } static void @@ -247,6 +440,7 @@ main(int argc, char** argv) { NDB_INIT(argv[0]); + debug << "Start readArguments" << endl; if (!readArguments(&argc, &argv)) { exitHandler(NDBT_FAILED); @@ -265,10 +459,11 @@ main(int argc, char** argv) /** * we must always load meta data, even if we will only print it to stdout */ + debug << "Start restoring meta data" << endl; RestoreMetaData metaData(ga_backupPath, ga_nodeId, ga_backupId); if (!metaData.readHeader()) { - ndbout << "Failed to read " << metaData.getFilename() << endl << endl; + err << "Failed to read " << metaData.getFilename() << endl << endl; exitHandler(NDBT_FAILED); } @@ -276,66 +471,108 @@ main(int argc, char** argv) const Uint32 version = tmp.NdbVersion; char buf[NDB_VERSION_STRING_BUF_SZ]; - ndbout << "Ndb version in backup files: " - << getVersionString(version, 0, buf, sizeof(buf)) << endl; + info.setLevel(254); + info << "Ndb version in backup files: " + << getVersionString(version, 0, buf, sizeof(buf)) << endl; /** * check wheater we can restore the backup (right version). */ + if (version > NDB_VERSION) + { + err << "Restore program older than backup version. Not supported. " + << "Use new restore program" << endl; + exitHandler(NDBT_FAILED); + } + + debug << "Load content" << endl; int res = metaData.loadContent(); if (res == 0) { - ndbout_c("Restore: Failed to load content"); + err << "Restore: Failed to load content" << endl; exitHandler(NDBT_FAILED); } - + debug << "Get no of Tables" << endl; if (metaData.getNoOfTables() == 0) { - ndbout_c("Restore: The backup contains no tables "); + err << "The backup contains no tables" << endl; exitHandler(NDBT_FAILED); } - + debug << "Validate Footer" << endl; if (!metaData.validateFooter()) { - ndbout_c("Restore: Failed to validate footer."); + err << "Restore: Failed to validate footer." << endl; exitHandler(NDBT_FAILED); } - + debug << "Init Backup objects" << endl; Uint32 i; for(i= 0; i < g_consumers.size(); i++) { if (!g_consumers[i]->init()) { clearConsumers(); + err << "Failed to initialize consumers" << endl; exitHandler(NDBT_FAILED); } } + Vector<OutputStream *> table_output(metaData.getNoOfTables()); + debug << "Restoring tables" << endl; for(i = 0; i<metaData.getNoOfTables(); i++) { - if (checkSysTable(metaData[i]->getTableName())) + const TableS *table= metaData[i]; + table_output.push_back(NULL); + if (!checkDbAndTableName(table)) + continue; + if (checkSysTable(table)) { + if (!tab_path || isBlobTable(table) || isIndex(table)) + { + table_output[i]= ndbout.m_out; + } + else + { + FILE* res; + char filename[FN_REFLEN], tmp_path[FN_REFLEN]; + const char *table_name; + table_name= table->getTableName(); + while (*table_name != '/') table_name++; + table_name++; + while (*table_name != '/') table_name++; + table_name++; + convert_dirname(tmp_path, tab_path, NullS); + res= my_fopen(fn_format(filename, table_name, tmp_path, ".txt", 4), + opt_append ? + O_WRONLY|O_APPEND|O_CREAT : + O_WRONLY|O_TRUNC|O_CREAT, + MYF(MY_WME)); + if (res == 0) + { + exitHandler(NDBT_FAILED); + } + FileOutputStream *f= new FileOutputStream(res); + table_output[i]= f; + } for(Uint32 j= 0; j < g_consumers.size(); j++) - if (!g_consumers[j]->table(* metaData[i])) + if (!g_consumers[j]->table(* table)) { - ndbout_c("Restore: Failed to restore table: %s. " - "Exiting...", - metaData[i]->getTableName()); + err << "Restore: Failed to restore table: "; + err << table->getTableName() << " ... Exiting " << endl; exitHandler(NDBT_FAILED); - } + } } } - + debug << "Close tables" << endl; for(i= 0; i < g_consumers.size(); i++) if (!g_consumers[i]->endOfTables()) { - ndbout_c("Restore: Failed while closing tables"); + err << "Restore: Failed while closing tables" << endl; exitHandler(NDBT_FAILED); } - + debug << "Iterate over data" << endl; if (ga_restore || ga_print) { if(_restore_data || _print_data) @@ -345,7 +582,7 @@ main(int argc, char** argv) // Read data file header if (!dataIter.readHeader()) { - ndbout << "Failed to read header of data file. Exiting..." ; + err << "Failed to read header of data file. Exiting..." << endl; exitHandler(NDBT_FAILED); } @@ -355,20 +592,26 @@ main(int argc, char** argv) const TupleS* tuple; while ((tuple = dataIter.getNextTuple(res= 1)) != 0) { - if (checkSysTable(tuple->getTable()->getTableName())) - for(Uint32 j= 0; j < g_consumers.size(); j++) - g_consumers[j]->tuple(* tuple); + const TableS* table = tuple->getTable(); + OutputStream *output = table_output[table->getLocalId()]; + if (!output) + continue; + OutputStream *tmp = ndbout.m_out; + ndbout.m_out = output; + for(Uint32 j= 0; j < g_consumers.size(); j++) + g_consumers[j]->tuple(* tuple); + ndbout.m_out = tmp; } // while (tuple != NULL); if (res < 0) { - ndbout_c("Restore: An error occured while restoring data. " - "Exiting..."); + err <<" Restore: An error occured while restoring data. Exiting..."; + err << endl; exitHandler(NDBT_FAILED); } if (!dataIter.validateFragmentFooter()) { - ndbout_c("Restore: Error validating fragment footer. " - "Exiting..."); + err << "Restore: Error validating fragment footer. "; + err << "Exiting..." << endl; exitHandler(NDBT_FAILED); } } // while (dataIter.readFragmentHeader(res)) @@ -376,7 +619,7 @@ main(int argc, char** argv) if (res < 0) { err << "Restore: An error occured while restoring data. Exiting... " - << "res=" << res << endl; + << "res= " << res << endl; exitHandler(NDBT_FAILED); } @@ -399,9 +642,12 @@ main(int argc, char** argv) const LogEntry * logEntry = 0; while ((logEntry = logIter.getNextLogEntry(res= 0)) != 0) { - if (checkSysTable(logEntry->m_table->getTableName())) - for(Uint32 j= 0; j < g_consumers.size(); j++) - g_consumers[j]->logEntry(* logEntry); + const TableS* table = logEntry->m_table; + OutputStream *output = table_output[table->getLocalId()]; + if (!output) + continue; + for(Uint32 j= 0; j < g_consumers.size(); j++) + g_consumers[j]->logEntry(* logEntry); } if (res < 0) { @@ -418,17 +664,17 @@ main(int argc, char** argv) { 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()); - exitHandler(NDBT_FAILED); - } - } + const TableS* table = metaData[i]; + OutputStream *output = table_output[table->getLocalId()]; + if (!output) + continue; + for(Uint32 j= 0; j < g_consumers.size(); j++) + if (!g_consumers[j]->finalize_table(*table)) + { + err << "Restore: Failed to finalize restore table: %s. "; + err << "Exiting... " << metaData[i]->getTableName() << endl; + exitHandler(NDBT_FAILED); + } } } } @@ -439,12 +685,27 @@ main(int argc, char** argv) clearConsumers(); ndbout_c("\nRestore successful, but encountered temporary error, " "please look at configuration."); - return NDBT_ProgramExit(NDBT_TEMPORARY); + } + } + + clearConsumers(); + + for(i = 0; i < metaData.getNoOfTables(); i++) + { + if (table_output[i] && + table_output[i] != ndbout.m_out) + { + my_fclose(((FileOutputStream *)table_output[i])->getFile(), MYF(MY_WME)); + delete table_output[i]; + table_output[i] = NULL; } } - clearConsumers(); - return NDBT_ProgramExit(NDBT_OK); + if (opt_verbose) + return NDBT_ProgramExit(NDBT_OK); + else + return 0; } // main template class Vector<BackupConsumer*>; +template class Vector<OutputStream*>; |