BUG#24363 If the table structure has been changed, the default action about the restore will fail.

          You can skip the table structure check with --skip-table-check (-s) option. 
parent 328a8cca
...@@ -41,6 +41,7 @@ public: ...@@ -41,6 +41,7 @@ public:
NODE_GROUP_MAP *m_nodegroup_map; NODE_GROUP_MAP *m_nodegroup_map;
uint m_nodegroup_map_len; uint m_nodegroup_map_len;
virtual bool has_temp_error() {return false;} virtual bool has_temp_error() {return false;}
virtual bool table_equal(const TableS &) {return true;}
}; };
#endif #endif
...@@ -666,6 +666,62 @@ BackupRestore::update_apply_status(const RestoreMetaData &metaData) ...@@ -666,6 +666,62 @@ BackupRestore::update_apply_status(const RestoreMetaData &metaData)
return result; return result;
} }
bool
BackupRestore::table_equal(const TableS &tableS){
const char *tablename = tableS.getTableName();
if(tableS.m_dictTable == NULL){
ndbout<<"Table %s has no m_dictTable " << tablename << endl;
return false;
}
/**
* Ignore blob tables
*/
if(match_blob(tablename) >= 0)
return true;
const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* tableS.m_dictTable);
if ((int) tmptab.m_indexType != (int) NdbDictionary::Index::Undefined){
return true;
}
BaseString tmp(tablename);
Vector<BaseString> split;
if(tmp.split(split, "/") != 3){
err << "Invalid table name format " << tablename << endl;
return false;
}
m_ndb->setDatabaseName(split[0].c_str());
m_ndb->setSchemaName(split[1].c_str());
NdbDictionary::Dictionary* dict = m_ndb->getDictionary();
const NdbDictionary::Table* tab = dict->getTable(split[2].c_str());
if(tab == 0){
err << "Unable to find table: " << split[2].c_str() << endl;
return false;
}
if(tab->getNoOfColumns() != tableS.m_dictTable->getNoOfColumns())
{
ndbout_c("m_columns.size %d != %d",tab->getNoOfColumns(),
tableS.m_dictTable->getNoOfColumns());
return false;
}
for(int i = 0; i<tab->getNoOfColumns(); i++)
{
if(!tab->getColumn(i)->equal(*(tableS.m_dictTable->getColumn(i))))
{
ndbout_c("m_columns %s != %s",tab->getColumn(i)->getName(),
tableS.m_dictTable->getColumn(i)->getName());
return false;
}
}
return true;
}
bool bool
BackupRestore::createSystable(const TableS & tables){ BackupRestore::createSystable(const TableS & tables){
const char *tablename = tables.getTableName(); const char *tablename = tables.getTableName();
......
...@@ -74,6 +74,7 @@ public: ...@@ -74,6 +74,7 @@ public:
virtual bool finalize_table(const TableS &); virtual bool finalize_table(const TableS &);
virtual bool has_temp_error(); virtual bool has_temp_error();
virtual bool createSystable(const TableS & table); virtual bool createSystable(const TableS & table);
virtual bool table_equal(const TableS & table);
virtual bool update_apply_status(const RestoreMetaData &metaData); virtual bool update_apply_status(const RestoreMetaData &metaData);
void connectToMysql(); void connectToMysql();
bool map_in_frm(char *new_data, const char *data, bool map_in_frm(char *new_data, const char *data,
......
...@@ -51,6 +51,7 @@ NDB_STD_OPTS_VARS; ...@@ -51,6 +51,7 @@ NDB_STD_OPTS_VARS;
static bool ga_restore_epoch = false; static bool ga_restore_epoch = false;
static bool ga_restore = false; static bool ga_restore = false;
static bool ga_print = false; static bool ga_print = false;
static bool ga_skip_table_check = false;
static int _print = 0; static int _print = 0;
static int _print_meta = 0; static int _print_meta = 0;
static int _print_data = 0; static int _print_data = 0;
...@@ -92,6 +93,9 @@ static struct my_option my_long_options[] = ...@@ -92,6 +93,9 @@ static struct my_option my_long_options[] =
NDB_REP_DB "." NDB_APPLY_TABLE " with id 0 will be updated/inserted.", NDB_REP_DB "." NDB_APPLY_TABLE " with id 0 will be updated/inserted.",
(gptr*) &ga_restore_epoch, (gptr*) &ga_restore_epoch, 0, (gptr*) &ga_restore_epoch, (gptr*) &ga_restore_epoch, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "skip-table-check", 's', "Skip table structure check during restore of data",
(gptr*) &ga_skip_table_check, (gptr*) &ga_skip_table_check, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "parallelism", 'p', { "parallelism", 'p',
"No of parallel transactions during restore of data." "No of parallel transactions during restore of data."
"(parallelism can be 1 to 1024)", "(parallelism can be 1 to 1024)",
...@@ -460,6 +464,8 @@ main(int argc, char** argv) ...@@ -460,6 +464,8 @@ main(int argc, char** argv)
g_options.appfmt(" -n %d", ga_nodeId); g_options.appfmt(" -n %d", ga_nodeId);
if (_restore_meta) if (_restore_meta)
g_options.appfmt(" -m"); g_options.appfmt(" -m");
if (ga_skip_table_check)
g_options.appfmt(" -s");
if (_restore_data) if (_restore_data)
g_options.appfmt(" -r"); g_options.appfmt(" -r");
if (ga_restore_epoch) if (ga_restore_epoch)
...@@ -590,6 +596,20 @@ main(int argc, char** argv) ...@@ -590,6 +596,20 @@ main(int argc, char** argv)
{ {
if(_restore_data || _print_data) if(_restore_data || _print_data)
{ {
if (!ga_skip_table_check){
for(i=0; i < metaData.getNoOfTables(); i++){
if (checkSysTable(metaData, i))
{
for(Uint32 j= 0; j < g_consumers.size(); j++)
if (!g_consumers[j]->table_equal(* metaData[i]))
{
err << "Restore: Failed to restore data, ";
err << metaData[i]->getTableName() << " table structure doesn't match backup ... Exiting " << endl;
exitHandler(NDBT_FAILED);
}
}
}
}
RestoreDataIterator dataIter(metaData, &free_data_callback); RestoreDataIterator dataIter(metaData, &free_data_callback);
// Read data file header // Read data file header
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment