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;