diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 1690712d48c..b3e9ff735ac 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -885,7 +885,7 @@ Backup::execBACKUP_REQ(Signal* signal) }//if 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.setState(DEFINING); @@ -2484,8 +2484,7 @@ Backup::execLIST_TABLES_CONF(Signal* signal) jam(); Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]); Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]); - if (tableType != DictTabInfo::SystemTable && - tableType != DictTabInfo::UserTable) { + if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){ jam(); continue; }//if @@ -2864,7 +2863,12 @@ Backup::execGET_TABINFO_CONF(Signal* signal) return; }//if + TablePtr tmp = tabPtr; ptr.p->tables.next(tabPtr); + if(DictTabInfo::isIndex(tmp.p->tableType)){ + ptr.p->tables.release(tmp); + } + if(tabPtr.i == RNIL) { jam(); @@ -2906,7 +2910,11 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len) TablePtr tabPtr; ndbrequire(findTable(ptr, tabPtr, tmpTab.TableId)); - + if(DictTabInfo::isIndex(tabPtr.p->tableType)){ + jam(); + return tabPtr; + } + /** * Initialize table object */ diff --git a/ndb/src/kernel/blocks/backup/Backup.hpp b/ndb/src/kernel/blocks/backup/Backup.hpp index ed01331fe15..4dc2cd13ae0 100644 --- a/ndb/src/kernel/blocks/backup/Backup.hpp +++ b/ndb/src/kernel/blocks/backup/Backup.hpp @@ -441,7 +441,7 @@ public: Uint32 startGCP; Uint32 currGCP; Uint32 stopGCP; - SLList tables; + DLList
tables; SLList triggers; SLList files; diff --git a/ndb/src/kernel/blocks/backup/restore/consumer.hpp b/ndb/src/kernel/blocks/backup/restore/consumer.hpp index e3ba2041a22..0b7b517c666 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer.hpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer.hpp @@ -24,6 +24,7 @@ public: virtual ~BackupConsumer() { } virtual bool init() { return true;} virtual bool table(const TableS &){return true;} + virtual bool endOfTables() { return true; } virtual void tuple(const TupleS &){} virtual void tuple_free(){} virtual void endOfTuples(){} diff --git a/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp b/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp index e607a05d1ea..c132bccee75 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp @@ -16,6 +16,7 @@ #include "consumer_restore.hpp" #include +#include extern FilteredNdbOut err; extern FilteredNdbOut info; @@ -141,7 +142,13 @@ BackupRestore::table(const TableS & table){ */ if(match_blob(name) >= 0) 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); Vector split; if(tmp.split(split, "/") != 3){ @@ -178,6 +185,65 @@ BackupRestore::table(const TableS & table){ return true; } +bool +BackupRestore::endOfTables(){ + if(!m_restore_meta) + return true; + + NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); + for(size_t i = 0; i 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) { if (!m_restore) diff --git a/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp b/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp index 12fe954915a..ca336eeea4f 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp @@ -49,6 +49,7 @@ public: virtual bool init(); virtual void release(); virtual bool table(const TableS &); + virtual bool endOfTables(); virtual void tuple(const TupleS &); virtual void tuple_free(); virtual void tuple_a(restore_callback_t *cb); @@ -83,6 +84,8 @@ public: const NdbDictionary::Table* m_new_table; } m_cache; const NdbDictionary::Table* get_table(const NdbDictionary::Table* ); + + Vector m_indexes; }; #endif diff --git a/ndb/src/kernel/blocks/backup/restore/main.cpp b/ndb/src/kernel/blocks/backup/restore/main.cpp index 24043fd634d..a330aa51373 100644 --- a/ndb/src/kernel/blocks/backup/restore/main.cpp +++ b/ndb/src/kernel/blocks/backup/restore/main.cpp @@ -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) + if (ga_restore) + { + RestoreDataIterator dataIter(metaData, &free_data_callback); + + // Read data file header + if (!dataIter.readHeader()) { - RestoreDataIterator dataIter(metaData, &free_data_callback); - - // Read data file header - if (!dataIter.readHeader()) - { - 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) - { - if (checkSysTable(tuple->getTable()->getTableName())) - 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) - { - 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(); + 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) + { + if (checkSysTable(tuple->getTable()->getTableName())) + 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) + { + 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(); return 1; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index fd90b2b9ee3..566ebdfb141 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1773,7 +1773,7 @@ NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl) */ NdbIndexImpl* NdbDictionaryImpl::getIndexImpl(const char * externalName, - const char * internalName) + const char * internalName) { NdbTableImpl* tab = getTableImpl(internalName); if(tab == 0){ @@ -1796,14 +1796,30 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, /** * 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_status = tab->m_status; idx->m_indexId = tab->m_tableId; - idx->m_internalName.assign(internalName); - idx->m_externalName.assign(externalName); + idx->m_externalName.assign(tab->getName()); idx->m_tableName.assign(prim->m_externalName); idx->m_type = tab->m_indexType; + idx->m_logging = tab->m_logging; // skip last attribute (NDB$PK or NDB$TNODE) for(unsigned i = 0; i+1m_columns.size(); i++){ NdbColumnImpl* col = new NdbColumnImpl; @@ -1819,12 +1835,9 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, idx->m_key_ids[key_id] = i; col->m_keyInfoPos = key_id; } - - idx->m_table = tab; - // 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; + + * dst = idx; + return 0; } /***************************************************************** diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index d05c34520b8..8f197856f57 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -304,6 +304,10 @@ public: const Uint32 * data, Uint32 len, bool fullyQualifiedNames); + static int create_index_obj_from_table(NdbIndexImpl ** dst, + const NdbTableImpl*, + const NdbTableImpl*); + NdbError & m_error; private: Uint32 m_reference;