summaryrefslogtreecommitdiff
path: root/ndb/tools
diff options
context:
space:
mode:
authortomas@poseidon.mysql.com <>2007-03-09 00:55:46 +0700
committertomas@poseidon.mysql.com <>2007-03-09 00:55:46 +0700
commitcb4e5fbe00437c9d27ce50272614cc23edbada73 (patch)
treee2c451c8a5be685cf1ff69ad5b7fe75df34bf2b6 /ndb/tools
parent46c2981e0532644eebda0ead67aa146194a2b632 (diff)
parent30c58170fd627da7d37af95a08f509cc9c692efe (diff)
downloadmariadb-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.cpp60
-rw-r--r--ndb/tools/restore/Restore.hpp18
-rw-r--r--ndb/tools/restore/consumer_printer.cpp22
-rw-r--r--ndb/tools/restore/restore_main.cpp401
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*>;