Commit d933be79 authored by joreland@mysql.com's avatar joreland@mysql.com

Ndb backup/restore also handle indexes

parent 9b5efa4c
...@@ -885,7 +885,7 @@ Backup::execBACKUP_REQ(Signal* signal) ...@@ -885,7 +885,7 @@ Backup::execBACKUP_REQ(Signal* signal)
}//if }//if
ndbrequire(ptr.p->pages.empty()); ndbrequire(ptr.p->pages.empty());
ndbrequire(ptr.p->tables.empty()); ndbrequire(ptr.p->tables.isEmpty());
ptr.p->masterData.state.forceState(INITIAL); ptr.p->masterData.state.forceState(INITIAL);
ptr.p->masterData.state.setState(DEFINING); ptr.p->masterData.state.setState(DEFINING);
...@@ -2484,8 +2484,7 @@ Backup::execLIST_TABLES_CONF(Signal* signal) ...@@ -2484,8 +2484,7 @@ Backup::execLIST_TABLES_CONF(Signal* signal)
jam(); jam();
Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]); Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]); Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
if (tableType != DictTabInfo::SystemTable && if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){
tableType != DictTabInfo::UserTable) {
jam(); jam();
continue; continue;
}//if }//if
...@@ -2864,7 +2863,12 @@ Backup::execGET_TABINFO_CONF(Signal* signal) ...@@ -2864,7 +2863,12 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
return; return;
}//if }//if
TablePtr tmp = tabPtr;
ptr.p->tables.next(tabPtr); ptr.p->tables.next(tabPtr);
if(DictTabInfo::isIndex(tmp.p->tableType)){
ptr.p->tables.release(tmp);
}
if(tabPtr.i == RNIL) { if(tabPtr.i == RNIL) {
jam(); jam();
...@@ -2906,7 +2910,11 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len) ...@@ -2906,7 +2910,11 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len)
TablePtr tabPtr; TablePtr tabPtr;
ndbrequire(findTable(ptr, tabPtr, tmpTab.TableId)); ndbrequire(findTable(ptr, tabPtr, tmpTab.TableId));
if(DictTabInfo::isIndex(tabPtr.p->tableType)){
jam();
return tabPtr;
}
/** /**
* Initialize table object * Initialize table object
*/ */
......
...@@ -441,7 +441,7 @@ public: ...@@ -441,7 +441,7 @@ public:
Uint32 startGCP; Uint32 startGCP;
Uint32 currGCP; Uint32 currGCP;
Uint32 stopGCP; Uint32 stopGCP;
SLList<Table> tables; DLList<Table> tables;
SLList<TriggerRecord> triggers; SLList<TriggerRecord> triggers;
SLList<BackupFile> files; SLList<BackupFile> files;
......
...@@ -24,6 +24,7 @@ public: ...@@ -24,6 +24,7 @@ public:
virtual ~BackupConsumer() { } virtual ~BackupConsumer() { }
virtual bool init() { return true;} virtual bool init() { return true;}
virtual bool table(const TableS &){return true;} virtual bool table(const TableS &){return true;}
virtual bool endOfTables() { return true; }
virtual void tuple(const TupleS &){} virtual void tuple(const TupleS &){}
virtual void tuple_free(){} virtual void tuple_free(){}
virtual void endOfTuples(){} virtual void endOfTuples(){}
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "consumer_restore.hpp" #include "consumer_restore.hpp"
#include <NdbSleep.h> #include <NdbSleep.h>
#include <NdbDictionaryImpl.hpp>
extern FilteredNdbOut err; extern FilteredNdbOut err;
extern FilteredNdbOut info; extern FilteredNdbOut info;
...@@ -141,7 +142,13 @@ BackupRestore::table(const TableS & table){ ...@@ -141,7 +142,13 @@ BackupRestore::table(const TableS & table){
*/ */
if(match_blob(name) >= 0) if(match_blob(name) >= 0)
return true; return true;
const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* table.m_dictTable);
if(tmptab.m_indexType != NdbDictionary::Index::Undefined){
m_indexes.push_back(table.m_dictTable);
return true;
}
BaseString tmp(name); BaseString tmp(name);
Vector<BaseString> split; Vector<BaseString> split;
if(tmp.split(split, "/") != 3){ if(tmp.split(split, "/") != 3){
...@@ -178,6 +185,65 @@ BackupRestore::table(const TableS & table){ ...@@ -178,6 +185,65 @@ BackupRestore::table(const TableS & table){
return true; return true;
} }
bool
BackupRestore::endOfTables(){
if(!m_restore_meta)
return true;
NdbDictionary::Dictionary* dict = m_ndb->getDictionary();
for(size_t i = 0; i<m_indexes.size(); i++){
const NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]);
BaseString tmp(indtab.m_primaryTable.c_str());
Vector<BaseString> split;
if(tmp.split(split, "/") != 3){
err << "Invalid table name format " << indtab.m_primaryTable.c_str()
<< endl;
return false;
}
m_ndb->setDatabaseName(split[0].c_str());
m_ndb->setSchemaName(split[1].c_str());
const NdbDictionary::Table * prim = dict->getTable(split[2].c_str());
if(prim == 0){
err << "Unable to find base table \"" << split[2].c_str()
<< "\" for index "
<< indtab.getName() << endl;
return false;
}
NdbTableImpl& base = NdbTableImpl::getImpl(*prim);
NdbIndexImpl* idx;
int id;
char idxName[255], buf[255];
if(sscanf(indtab.getName(), "%[^/]/%[^/]/%d/%s",
buf, buf, &id, idxName) != 4){
err << "Invalid index name format " << indtab.getName() << endl;
return false;
}
if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base))
{
err << "Failed to create index " << idxName
<< " on " << split[2].c_str() << endl;
return false;
}
idx->setName(idxName);
if(dict->createIndex(* idx) != 0)
{
delete idx;
err << "Failed to create index " << idxName
<< " on " << split[2].c_str() << endl
<< dict->getNdbError() << endl;
return false;
}
delete idx;
info << "Successfully created index " << idxName
<< " on " << split[2].c_str() << endl;
}
return true;
}
void BackupRestore::tuple(const TupleS & tup) void BackupRestore::tuple(const TupleS & tup)
{ {
if (!m_restore) if (!m_restore)
......
...@@ -49,6 +49,7 @@ public: ...@@ -49,6 +49,7 @@ public:
virtual bool init(); virtual bool init();
virtual void release(); virtual void release();
virtual bool table(const TableS &); virtual bool table(const TableS &);
virtual bool endOfTables();
virtual void tuple(const TupleS &); virtual void tuple(const TupleS &);
virtual void tuple_free(); virtual void tuple_free();
virtual void tuple_a(restore_callback_t *cb); virtual void tuple_a(restore_callback_t *cb);
...@@ -83,6 +84,8 @@ public: ...@@ -83,6 +84,8 @@ public:
const NdbDictionary::Table* m_new_table; const NdbDictionary::Table* m_new_table;
} m_cache; } m_cache;
const NdbDictionary::Table* get_table(const NdbDictionary::Table* ); const NdbDictionary::Table* get_table(const NdbDictionary::Table* );
Vector<const NdbDictionary::Table*> m_indexes;
}; };
#endif #endif
...@@ -276,78 +276,85 @@ main(int argc, const char** argv) ...@@ -276,78 +276,85 @@ main(int argc, const char** argv)
} }
} }
for(i= 0; i < g_consumers.size(); i++)
if (!g_consumers[i]->endOfTables())
{
ndbout_c("Restore: Failed while closing tables");
return -11;
}
if (ga_restore || ga_print) if (ga_restore || ga_print)
{ {
if (ga_restore) if (ga_restore)
{
RestoreDataIterator dataIter(metaData, &free_data_callback);
// Read data file header
if (!dataIter.readHeader())
{ {
RestoreDataIterator dataIter(metaData, &free_data_callback); ndbout << "Failed to read header of data file. Exiting..." ;
return -11;
// Read data file header }
if (!dataIter.readHeader())
{
ndbout << "Failed to read header of data file. Exiting..." ; while (dataIter.readFragmentHeader(res= 0))
return -11; {
} const TupleS* tuple;
while ((tuple = dataIter.getNextTuple(res= 1)) != 0)
while (dataIter.readFragmentHeader(res= 0))
{ {
const TupleS* tuple; if (checkSysTable(tuple->getTable()->getTableName()))
while ((tuple = dataIter.getNextTuple(res= 1)) != 0) for(Uint32 i= 0; i < g_consumers.size(); i++)
{ g_consumers[i]->tuple(* tuple);
if (checkSysTable(tuple->getTable()->getTableName())) } // while (tuple != NULL);
for(Uint32 i= 0; i < g_consumers.size(); i++)
g_consumers[i]->tuple(* tuple);
} // while (tuple != NULL);
if (res < 0)
{
ndbout_c("Restore: An error occured while restoring data. "
"Exiting...");
return -1;
}
if (!dataIter.validateFragmentFooter()) {
ndbout_c("Restore: Error validating fragment footer. "
"Exiting...");
return -1;
}
} // while (dataIter.readFragmentHeader(res))
if (res < 0) if (res < 0)
{ {
err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl; ndbout_c("Restore: An error occured while restoring data. "
"Exiting...");
return -1; return -1;
} }
if (!dataIter.validateFragmentFooter()) {
ndbout_c("Restore: Error validating fragment footer. "
dataIter.validateFooter(); //not implemented "Exiting...");
for (i= 0; i < g_consumers.size(); i++)
g_consumers[i]->endOfTuples();
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)
{
err << "Restore: An restoring the data log. Exiting... res=" << res << endl;
return -1; return -1;
} }
logIter.validateFooter(); //not implemented } // while (dataIter.readFragmentHeader(res))
for (i= 0; i < g_consumers.size(); i++)
g_consumers[i]->endOfLogEntrys(); if (res < 0)
{
err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl;
return -1;
}
dataIter.validateFooter(); //not implemented
for (i= 0; i < g_consumers.size(); i++)
g_consumers[i]->endOfTuples();
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)
{
err << "Restore: An restoring the data log. Exiting... res=" << res << endl;
return -1;
} }
logIter.validateFooter(); //not implemented
for (i= 0; i < g_consumers.size(); i++)
g_consumers[i]->endOfLogEntrys();
}
} }
clearConsumers(); clearConsumers();
return 1; return 1;
......
...@@ -1773,7 +1773,7 @@ NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl) ...@@ -1773,7 +1773,7 @@ NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl)
*/ */
NdbIndexImpl* NdbIndexImpl*
NdbDictionaryImpl::getIndexImpl(const char * externalName, NdbDictionaryImpl::getIndexImpl(const char * externalName,
const char * internalName) const char * internalName)
{ {
NdbTableImpl* tab = getTableImpl(internalName); NdbTableImpl* tab = getTableImpl(internalName);
if(tab == 0){ if(tab == 0){
...@@ -1796,14 +1796,30 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, ...@@ -1796,14 +1796,30 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName,
/** /**
* Create index impl * Create index impl
*/ */
NdbIndexImpl* idx = new NdbIndexImpl(); NdbIndexImpl* idx;
if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){
idx->m_table = tab;
idx->m_internalName.assign(internalName);
// TODO Assign idx to tab->m_index
// Don't do it right now since assign can't asign a table with index
// tab->m_index = idx;
return idx;
}
return 0;
}
int
NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
const NdbTableImpl* tab,
const NdbTableImpl* prim){
NdbIndexImpl *idx = new NdbIndexImpl();
idx->m_version = tab->m_version; idx->m_version = tab->m_version;
idx->m_status = tab->m_status; idx->m_status = tab->m_status;
idx->m_indexId = tab->m_tableId; idx->m_indexId = tab->m_tableId;
idx->m_internalName.assign(internalName); idx->m_externalName.assign(tab->getName());
idx->m_externalName.assign(externalName);
idx->m_tableName.assign(prim->m_externalName); idx->m_tableName.assign(prim->m_externalName);
idx->m_type = tab->m_indexType; idx->m_type = tab->m_indexType;
idx->m_logging = tab->m_logging;
// skip last attribute (NDB$PK or NDB$TNODE) // skip last attribute (NDB$PK or NDB$TNODE)
for(unsigned i = 0; i+1<tab->m_columns.size(); i++){ for(unsigned i = 0; i+1<tab->m_columns.size(); i++){
NdbColumnImpl* col = new NdbColumnImpl; NdbColumnImpl* col = new NdbColumnImpl;
...@@ -1819,12 +1835,9 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, ...@@ -1819,12 +1835,9 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName,
idx->m_key_ids[key_id] = i; idx->m_key_ids[key_id] = i;
col->m_keyInfoPos = key_id; col->m_keyInfoPos = key_id;
} }
idx->m_table = tab; * dst = idx;
// TODO Assign idx to tab->m_index return 0;
// Don't do it right now since assign can't asign a table with index
// tab->m_index = idx;
return idx;
} }
/***************************************************************** /*****************************************************************
......
...@@ -304,6 +304,10 @@ public: ...@@ -304,6 +304,10 @@ public:
const Uint32 * data, Uint32 len, const Uint32 * data, Uint32 len,
bool fullyQualifiedNames); bool fullyQualifiedNames);
static int create_index_obj_from_table(NdbIndexImpl ** dst,
const NdbTableImpl*,
const NdbTableImpl*);
NdbError & m_error; NdbError & m_error;
private: private:
Uint32 m_reference; Uint32 m_reference;
......
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