#include <consumer_restore.hpp>
Inheritance diagram for BackupRestore:


Definition at line 35 of file consumer_restore.hpp.
| BackupRestore::BackupRestore | ( | NODE_GROUP_MAP * | ng_map, | |
| uint | ng_map_len, | |||
| Uint32 | parallelism = 1 | |||
| ) | [inline] |
Definition at line 38 of file consumer_restore.hpp.
References m_cache, m_callback, m_cluster_connection, m_dataCount, m_free_callback, m_logCount, m_ndb, m_no_restore_disk, BackupConsumer::m_nodegroup_map, BackupConsumer::m_nodegroup_map_len, m_parallelism, m_restore, m_restore_epoch, m_restore_meta, m_transactions, and parallelism.
00041 { 00042 m_ndb = 0; 00043 m_cluster_connection = 0; 00044 m_nodegroup_map = ng_map; 00045 m_nodegroup_map_len = ng_map_len; 00046 m_logCount = m_dataCount = 0; 00047 m_restore = false; 00048 m_restore_meta = false; 00049 m_no_restore_disk = false; 00050 m_restore_epoch = false; 00051 m_parallelism = parallelism; 00052 m_callback = 0; 00053 m_free_callback = 0; 00054 m_transactions = 0; 00055 m_cache.m_old_table = 0; 00056 }
| BackupRestore::~BackupRestore | ( | ) | [virtual] |
Definition at line 104 of file consumer_restore.cpp.
References release().
00105 { 00106 release(); 00107 }
Here is the call graph for this function:

| void BackupRestore::cback | ( | int | result, | |
| restore_callback_t * | cb | |||
| ) | [virtual] |
Definition at line 1040 of file consumer_restore.cpp.
References Ndb::closeTransaction(), restore_callback_t::connection, err, errorHandler(), exitHandler(), m_dataCount, m_free_callback, m_ndb, m_transactions, restore_callback_t::next, and tuple_a().
01041 { 01042 m_transactions--; 01043 01044 if (result < 0) 01045 { 01049 if (errorHandler(cb)) 01050 tuple_a(cb); // retry 01051 else 01052 { 01053 err << "Restore: Failed to restore data due to a unrecoverable error. Exiting..." << endl; 01054 exitHandler(); 01055 } 01056 } 01057 else 01058 { 01062 m_ndb->closeTransaction(cb->connection); 01063 cb->connection= 0; 01064 cb->next= m_free_callback; 01065 m_free_callback= cb; 01066 m_dataCount++; 01067 } 01068 }
Here is the call graph for this function:

| void BackupRestore::connectToMysql | ( | ) |
| void BackupRestore::endOfLogEntrys | ( | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 1303 of file consumer_restore.cpp.
References info, m_dataCount, m_logCount, and m_restore.
01304 { 01305 if (!m_restore) 01306 return; 01307 01308 info << "Restored " << m_dataCount << " tuples and " 01309 << m_logCount << " log entries" << endl; 01310 }
| bool BackupRestore::endOfTables | ( | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 830 of file consumer_restore.cpp.
References buf, NdbDictInterface::create_index_obj_from_table(), NdbDictionary::Dictionary::createIndex(), err, Ndb::getDictionary(), NdbTableImpl::getImpl(), NdbDictionary::Dictionary::getNdbError(), NdbDictionary::Dictionary::getTable(), id, info, m_indexes, m_ndb, m_restore_meta, Ndb::setDatabaseName(), Ndb::setSchemaName(), Vector< T >::size(), and split().
00830 { 00831 if(!m_restore_meta) 00832 return true; 00833 00834 NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); 00835 for(size_t i = 0; i<m_indexes.size(); i++){ 00836 NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]); 00837 00838 BaseString tmp(indtab.m_primaryTable.c_str()); 00839 Vector<BaseString> split; 00840 if(tmp.split(split, "/") != 3){ 00841 err << "Invalid table name format " << indtab.m_primaryTable.c_str() 00842 << endl; 00843 return false; 00844 } 00845 00846 m_ndb->setDatabaseName(split[0].c_str()); 00847 m_ndb->setSchemaName(split[1].c_str()); 00848 00849 const NdbDictionary::Table * prim = dict->getTable(split[2].c_str()); 00850 if(prim == 0){ 00851 err << "Unable to find base table \"" << split[2].c_str() 00852 << "\" for index " 00853 << indtab.getName() << endl; 00854 return false; 00855 } 00856 NdbTableImpl& base = NdbTableImpl::getImpl(*prim); 00857 NdbIndexImpl* idx; 00858 int id; 00859 char idxName[255], buf[255]; 00860 if(sscanf(indtab.getName(), "%[^/]/%[^/]/%d/%s", 00861 buf, buf, &id, idxName) != 4){ 00862 err << "Invalid index name format " << indtab.getName() << endl; 00863 return false; 00864 } 00865 if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base)) 00866 { 00867 err << "Failed to create index " << idxName 00868 << " on " << split[2].c_str() << endl; 00869 return false; 00870 } 00871 idx->setName(idxName); 00872 if(dict->createIndex(* idx) != 0) 00873 { 00874 delete idx; 00875 err << "Failed to create index " << idxName 00876 << " on " << split[2].c_str() << endl 00877 << dict->getNdbError() << endl; 00878 00879 return false; 00880 } 00881 delete idx; 00882 info << "Successfully created index " << idxName 00883 << " on " << split[2].c_str() << endl; 00884 } 00885 return true; 00886 }
Here is the call graph for this function:

| void BackupRestore::endOfTuples | ( | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 1147 of file consumer_restore.cpp.
References tuple_free().
01148 { 01149 tuple_free(); 01150 }
Here is the call graph for this function:

| bool BackupRestore::errorHandler | ( | restore_callback_t * | cb | ) | [virtual] |
returns true if is recoverable, Error handling based on hugo false if it is an error that generates an abort.
Definition at line 1075 of file consumer_restore.cpp.
References Ndb::closeTransaction(), restore_callback_t::connection, err, error, restore_callback_t::error_code, Ndb::getNdbError(), NdbTransaction::getNdbError(), m_ndb, NdbSleep_MilliSleep(), NdbError::PermanentError, restore_callback_t::retries, NdbError::Success, NdbError::TemporaryError, and NdbError::UnknownResult.
Referenced by cback(), and tuple_a().
01076 { 01077 NdbError error; 01078 if(cb->connection) 01079 { 01080 error= cb->connection->getNdbError(); 01081 m_ndb->closeTransaction(cb->connection); 01082 cb->connection= 0; 01083 } 01084 else 01085 { 01086 error= m_ndb->getNdbError(); 01087 } 01088 01089 Uint32 sleepTime = 100 + cb->retries * 300; 01090 01091 cb->retries++; 01092 cb->error_code = error.code; 01093 01094 switch(error.status) 01095 { 01096 case NdbError::Success: 01097 err << "Success error: " << error << endl; 01098 return false; 01099 // ERROR! 01100 01101 case NdbError::TemporaryError: 01102 err << "Temporary error: " << error << endl; 01103 NdbSleep_MilliSleep(sleepTime); 01104 return true; 01105 // RETRY 01106 01107 case NdbError::UnknownResult: 01108 err << "Unknown: " << error << endl; 01109 return false; 01110 // ERROR! 01111 01112 default: 01113 case NdbError::PermanentError: 01114 //ERROR 01115 err << "Permanent: " << error << endl; 01116 return false; 01117 } 01118 err << "No error status" << endl; 01119 return false; 01120 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void BackupRestore::exitHandler | ( | ) | [virtual] |
Definition at line 1122 of file consumer_restore.cpp.
References abort(), exit, opt_core, and release().
Referenced by cback(), logEntry(), and tuple_a().
01123 { 01124 release(); 01125 NDBT_ProgramExit(NDBT_FAILED); 01126 if (opt_core) 01127 abort(); 01128 else 01129 exit(NDBT_FAILED); 01130 }
Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from BackupConsumer.
Definition at line 147 of file consumer_restore.cpp.
References NdbError::code, get_table(), Ndb::getNdbError(), m_ndb, m_restore, m_restore_meta, NdbSleep_MilliSleep(), Ndb::readAutoIncrementValue(), Ndb::setAutoIncrementValue(), NdbError::status, table(), and NdbError::TemporaryError.
00147 { 00148 bool ret= true; 00149 if (!m_restore && !m_restore_meta) 00150 return ret; 00151 if (!table.have_auto_inc()) 00152 return ret; 00153 00154 Uint64 max_val= table.get_max_auto_val(); 00155 do 00156 { 00157 Uint64 auto_val = ~(Uint64)0; 00158 int r= m_ndb->readAutoIncrementValue(get_table(table.m_dictTable), auto_val); 00159 if (r == -1 && m_ndb->getNdbError().status == NdbError::TemporaryError) 00160 { 00161 NdbSleep_MilliSleep(50); 00162 continue; // retry 00163 } 00164 else if (r == -1 && m_ndb->getNdbError().code != 626) 00165 { 00166 ret= false; 00167 } 00168 else if ((r == -1 && m_ndb->getNdbError().code == 626) || 00169 max_val+1 > auto_val || auto_val == ~(Uint64)0) 00170 { 00171 r= m_ndb->setAutoIncrementValue(get_table(table.m_dictTable), 00172 max_val+1, false); 00173 if (r == -1 && 00174 m_ndb->getNdbError().status == NdbError::TemporaryError) 00175 { 00176 NdbSleep_MilliSleep(50); 00177 continue; // retry 00178 } 00179 ret = (r == 0); 00180 } 00181 return (ret); 00182 } while (1); 00183 }
Here is the call graph for this function:

| const NdbDictionary::Table * BackupRestore::get_table | ( | const NdbDictionary::Table * | ) |
Definition at line 122 of file consumer_restore.cpp.
References assert, db, Ndb::getDictionary(), NdbDictionary::Table::getName(), NdbDictionary::Dictionary::getTable(), NdbDictionary::Table::getTableId(), m_cache, m_ndb, m_new_tables, Ndb::setDatabaseName(), Ndb::setSchemaName(), and BaseString::snprintf().
Referenced by finalize_table(), logEntry(), and tuple_a().
00122 { 00123 if(m_cache.m_old_table == tab) 00124 return m_cache.m_new_table; 00125 m_cache.m_old_table = tab; 00126 00127 int cnt, id1, id2; 00128 char db[256], schema[256]; 00129 if((cnt = sscanf(tab->getName(), "%[^/]/%[^/]/NDB$BLOB_%d_%d", 00130 db, schema, &id1, &id2)) == 4){ 00131 m_ndb->setDatabaseName(db); 00132 m_ndb->setSchemaName(schema); 00133 00134 BaseString::snprintf(db, sizeof(db), "NDB$BLOB_%d_%d", 00135 m_new_tables[id1]->getTableId(), id2); 00136 00137 m_cache.m_new_table = m_ndb->getDictionary()->getTable(db); 00138 00139 } else { 00140 m_cache.m_new_table = m_new_tables[tab->getTableId()]; 00141 } 00142 assert(m_cache.m_new_table); 00143 return m_cache.m_new_table; 00144 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool BackupRestore::init | ( | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 36 of file consumer_restore.cpp.
References BaseString::c_str(), Ndb_cluster_connection::connect(), restore_callback_t::connection, err, g_connect_string, info, Ndb::init(), m_callback, m_cluster_connection, m_free_callback, m_ndb, m_parallelism, m_restore, m_restore_epoch, m_restore_meta, restore_callback_t::next, NULL, release(), Ndb_cluster_connection::set_name(), and Ndb::waitUntilReady().
00037 { 00038 release(); 00039 00040 if (!m_restore && !m_restore_meta && !m_restore_epoch) 00041 return true; 00042 00043 m_cluster_connection = new Ndb_cluster_connection(g_connect_string); 00044 m_cluster_connection->set_name(g_options.c_str()); 00045 if(m_cluster_connection->connect(12, 5, 1) != 0) 00046 { 00047 return false; 00048 } 00049 00050 m_ndb = new Ndb(m_cluster_connection); 00051 00052 if (m_ndb == NULL) 00053 return false; 00054 00055 m_ndb->init(1024); 00056 if (m_ndb->waitUntilReady(30) != 0) 00057 { 00058 err << "Failed to connect to ndb!!" << endl; 00059 return false; 00060 } 00061 info << "Connected to ndb!!" << endl; 00062 00063 m_callback = new restore_callback_t[m_parallelism]; 00064 00065 if (m_callback == 0) 00066 { 00067 err << "Failed to allocate callback structs" << endl; 00068 return false; 00069 } 00070 00071 m_free_callback= m_callback; 00072 for (Uint32 i= 0; i < m_parallelism; i++) { 00073 m_callback[i].restore= this; 00074 m_callback[i].connection= 0; 00075 if (i > 0) 00076 m_callback[i-1].next= &(m_callback[i]); 00077 } 00078 m_callback[m_parallelism-1].next = 0; 00079 00080 return true; 00081 }
Here is the call graph for this function:

| void BackupRestore::logEntry | ( | const LogEntry & | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 1182 of file consumer_restore.cpp.
References check(), NdbError::classification, Ndb::closeTransaction(), NdbTransaction::Commit, NdbError::ConstraintViolation, NdbOperation::deleteTuple(), NdbOperation::equal(), err, NdbTransaction::execute(), exitHandler(), get_part_id(), get_table(), NdbTransaction::getNdbError(), NdbTransaction::getNdbOperation(), TableS::have_auto_inc(), NdbOperation::insertTuple(), keys, LogEntry::LE_DELETE, LogEntry::LE_INSERT, LogEntry::LE_UPDATE, TableS::m_dictTable, LogEntry::m_frag_id, m_logCount, m_ndb, m_restore, LogEntry::m_table, LogEntry::m_type, NdbError::NoDataFound, NULL, ok(), NdbError::PermanentError, NdbOperation::setPartitionId(), NdbOperation::setValue(), LogEntry::size(), Ndb::startTransaction(), NdbError::status, table(), TableS::update_max_auto_val(), NdbOperation::updateTuple(), and NdbDictionary::Object::UserDefined.
01183 { 01184 if (!m_restore) 01185 return; 01186 01187 NdbTransaction * trans = m_ndb->startTransaction(); 01188 if (trans == NULL) 01189 { 01190 // Deep shit, TODO: handle the error 01191 err << "Cannot start transaction" << endl; 01192 exitHandler(); 01193 } // if 01194 01195 const NdbDictionary::Table * table = get_table(tup.m_table->m_dictTable); 01196 NdbOperation * op = trans->getNdbOperation(table); 01197 if (op == NULL) 01198 { 01199 err << "Cannot get operation: " << trans->getNdbError() << endl; 01200 exitHandler(); 01201 } // if 01202 01203 int check = 0; 01204 switch(tup.m_type) 01205 { 01206 case LogEntry::LE_INSERT: 01207 check = op->insertTuple(); 01208 break; 01209 case LogEntry::LE_UPDATE: 01210 check = op->updateTuple(); 01211 break; 01212 case LogEntry::LE_DELETE: 01213 check = op->deleteTuple(); 01214 break; 01215 default: 01216 err << "Log entry has wrong operation type." 01217 << " Exiting..."; 01218 exitHandler(); 01219 } 01220 01221 if (check != 0) 01222 { 01223 err << "Error defining op: " << trans->getNdbError() << endl; 01224 exitHandler(); 01225 } // if 01226 01227 if (table->getFragmentType() == NdbDictionary::Object::UserDefined) 01228 { 01229 if (table->getDefaultNoPartitionsFlag()) 01230 { 01231 const AttributeS * attr = tup[tup.size()-1]; 01232 Uint32 hash_value = *(Uint32*)attr->Data.string_value; 01233 op->setPartitionId(get_part_id(table, hash_value)); 01234 } 01235 else 01236 op->setPartitionId(tup.m_frag_id); 01237 } 01238 01239 Bitmask<4096> keys; 01240 for (Uint32 i= 0; i < tup.size(); i++) 01241 { 01242 const AttributeS * attr = tup[i]; 01243 int size = attr->Desc->size; 01244 int arraySize = attr->Desc->arraySize; 01245 const char * dataPtr = attr->Data.string_value; 01246 01247 if (tup.m_table->have_auto_inc(attr->Desc->attrId)) 01248 tup.m_table->update_max_auto_val(dataPtr,size); 01249 01250 const Uint32 length = (size / 8) * arraySize; 01251 if (attr->Desc->m_column->getPrimaryKey()) 01252 { 01253 if(!keys.get(attr->Desc->attrId)) 01254 { 01255 keys.set(attr->Desc->attrId); 01256 check= op->equal(attr->Desc->attrId, dataPtr, length); 01257 } 01258 } 01259 else 01260 check= op->setValue(attr->Desc->attrId, dataPtr, length); 01261 01262 if (check != 0) 01263 { 01264 err << "Error defining op: " << trans->getNdbError() << endl; 01265 exitHandler(); 01266 } // if 01267 } 01268 01269 const int ret = trans->execute(NdbTransaction::Commit); 01270 if (ret != 0) 01271 { 01272 // Both insert update and delete can fail during log running 01273 // and it's ok 01274 // TODO: check that the error is either tuple exists or tuple does not exist? 01275 bool ok= false; 01276 NdbError errobj= trans->getNdbError(); 01277 switch(tup.m_type) 01278 { 01279 case LogEntry::LE_INSERT: 01280 if(errobj.status == NdbError::PermanentError && 01281 errobj.classification == NdbError::ConstraintViolation) 01282 ok= true; 01283 break; 01284 case LogEntry::LE_UPDATE: 01285 case LogEntry::LE_DELETE: 01286 if(errobj.status == NdbError::PermanentError && 01287 errobj.classification == NdbError::NoDataFound) 01288 ok= true; 01289 break; 01290 } 01291 if (!ok) 01292 { 01293 err << "execute failed: " << errobj << endl; 01294 exitHandler(); 01295 } 01296 } 01297 01298 m_ndb->closeTransaction(trans); 01299 m_logCount++; 01300 }
Here is the call graph for this function:

| bool BackupRestore::map_in_frm | ( | char * | new_data, | |
| const char * | data, | |||
| uint | data_len, | |||
| uint * | new_data_len | |||
| ) |
Definition at line 380 of file consumer_restore.cpp.
References copy_byte(), DBUG_ENTER, DBUG_RETURN, error, FALSE, search_replace(), TRUE, uint2korr, and uint4korr.
Referenced by translate_frm().
00382 { 00383 const char *end_data= data + data_len; 00384 const char *end_part_data; 00385 const char *part_data; 00386 char *extra_ptr; 00387 uint start_key_definition_len = uint2korr(data + 6); 00388 uint key_definition_len = uint4korr(data + 47); 00389 uint part_info_len; 00390 DBUG_ENTER("map_in_frm"); 00391 00392 if (data_len < 4096) goto error; 00393 extra_ptr = (char*)data + start_key_definition_len + key_definition_len; 00394 if ((int)data_len < ((extra_ptr - data) + 2)) goto error; 00395 extra_ptr = extra_ptr + 2 + uint2korr(extra_ptr); 00396 if ((int)data_len < ((extra_ptr - data) + 2)) goto error; 00397 extra_ptr = extra_ptr + 2 + uint2korr(extra_ptr); 00398 if ((int)data_len < ((extra_ptr - data) + 4)) goto error; 00399 part_info_len = uint4korr(extra_ptr); 00400 part_data = extra_ptr + 4; 00401 if ((int)data_len < ((part_data + part_info_len) - data)) goto error; 00402 00403 do 00404 { 00405 copy_byte(&data, &new_data, new_data_len); 00406 } while (data < part_data); 00407 end_part_data = part_data + part_info_len; 00408 do 00409 { 00410 if (search_replace((char*)" NODEGROUP = ", &new_data, &data, 00411 end_part_data, new_data_len)) 00412 goto error; 00413 } while (data != end_part_data); 00414 do 00415 { 00416 copy_byte(&data, &new_data, new_data_len); 00417 } while (data < end_data); 00418 DBUG_RETURN(FALSE); 00419 error: 00420 DBUG_RETURN(TRUE); 00421 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 236 of file consumer_restore.cpp.
References assert, node_group_map::curr_index, BackupConsumer::m_nodegroup_map, node_group_map::map_array, MAX_MAPS_PER_NODE_GROUP, MAX_NDB_PARTITIONS, and UNDEF_NODEGROUP.
Referenced by map_nodegroups(), and search_replace().
00237 { 00238 NODE_GROUP_MAP *ng_map = m_nodegroup_map; 00239 00240 if (ng == UNDEF_NODEGROUP || 00241 ng_map[ng].map_array[0] == UNDEF_NODEGROUP) 00242 { 00243 return ng; 00244 } 00245 else 00246 { 00247 Uint32 new_ng; 00248 Uint32 curr_inx = ng_map[ng].curr_index; 00249 Uint32 new_curr_inx = curr_inx + 1; 00250 00251 assert(ng < MAX_NDB_PARTITIONS); 00252 assert(curr_inx < MAX_MAPS_PER_NODE_GROUP); 00253 assert(new_curr_inx < MAX_MAPS_PER_NODE_GROUP); 00254 00255 if (new_curr_inx >= MAX_MAPS_PER_NODE_GROUP) 00256 new_curr_inx = 0; 00257 else if (ng_map[ng].map_array[new_curr_inx] == UNDEF_NODEGROUP) 00258 new_curr_inx = 0; 00259 new_ng = ng_map[ng].map_array[curr_inx]; 00260 ng_map[ng].curr_index = new_curr_inx; 00261 return new_ng; 00262 } 00263 }
Here is the caller graph for this function:

Definition at line 266 of file consumer_restore.cpp.
References assert, DBUG_ENTER, DBUG_RETURN, FALSE, map_ng(), MAX_NDB_PARTITIONS, and TRUE.
Referenced by table().
00267 { 00268 Uint32 i; 00269 bool mapped = FALSE; 00270 DBUG_ENTER("map_nodegroups"); 00271 00272 assert(no_parts < MAX_NDB_PARTITIONS); 00273 for (i = 0; i < no_parts; i++) 00274 { 00275 Uint32 ng; 00276 ng = map_ng((Uint32)ng_array[i]); 00277 if (ng != ng_array[i]) 00278 mapped = TRUE; 00279 ng_array[i] = ng; 00280 } 00281 DBUG_RETURN(mapped); 00282 }
Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from BackupConsumer.
Definition at line 466 of file consumer_restore.cpp.
References NdbError::classification, NdbDictionary::Dictionary::createDatafile(), NdbDictionary::Dictionary::createLogfileGroup(), NdbDictionary::Dictionary::createTablespace(), NdbDictionary::Dictionary::createUndofile(), DictTabInfo::Datafile, debug, err, NdbDictionary::Tablespace::getDefaultLogfileGroupId(), Ndb::getDictionary(), NdbDictionary::Dictionary::getLogfileGroup(), NdbDictionary::Undofile::getLogfileGroupId(), NdbDictionary::LogfileGroup::getName(), NdbDictionary::Tablespace::getName(), NdbDictionary::Dictionary::getNdbError(), NdbDictionary::ObjectId::getObjectId(), NdbDictionary::LogfileGroup::getObjectId(), NdbDictionary::Tablespace::getObjectId(), NdbDictionary::Undofile::getPath(), NdbDictionary::Datafile::getPath(), NdbDictionary::Dictionary::getTablespace(), NdbDictionary::Datafile::getTablespaceId(), info, DictTabInfo::LogfileGroup, m_logfilegroups, m_ndb, m_no_restore_disk, m_restore_meta, m_tablespaces, ndberror_cl_none, Vector< T >::set(), NdbDictionary::Tablespace::setDefaultLogfileGroup(), NdbDictionary::Undofile::setLogfileGroup(), NdbDictionary::Datafile::setTablespace(), DictTabInfo::Tablespace, and DictTabInfo::Undofile.
00467 { 00468 if (!m_restore_meta) 00469 return true; 00470 00471 NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); 00472 switch(type){ 00473 case DictTabInfo::Tablespace: 00474 { 00475 NdbDictionary::Tablespace old(*(NdbDictionary::Tablespace*)ptr); 00476 00477 Uint32 id = old.getObjectId(); 00478 00479 if (!m_no_restore_disk) 00480 { 00481 NdbDictionary::LogfileGroup * lg = m_logfilegroups[old.getDefaultLogfileGroupId()]; 00482 old.setDefaultLogfileGroup(* lg); 00483 info << "Creating tablespace: " << old.getName() << "..." << flush; 00484 int ret = dict->createTablespace(old); 00485 if (ret) 00486 { 00487 NdbError errobj= dict->getNdbError(); 00488 info << "FAILED" << endl; 00489 err << "Create tablespace failed: " << old.getName() << ": " << errobj << endl; 00490 return false; 00491 } 00492 info << "done" << endl; 00493 } 00494 00495 NdbDictionary::Tablespace curr = dict->getTablespace(old.getName()); 00496 NdbError errobj = dict->getNdbError(); 00497 if(errobj.classification == ndberror_cl_none) 00498 { 00499 NdbDictionary::Tablespace* currptr = new NdbDictionary::Tablespace(curr); 00500 NdbDictionary::Tablespace * null = 0; 00501 m_tablespaces.set(currptr, id, null); 00502 debug << "Retreived tablespace: " << currptr->getName() 00503 << " oldid: " << id << " newid: " << currptr->getObjectId() 00504 << " " << (void*)currptr << endl; 00505 return true; 00506 } 00507 00508 err << "Failed to retrieve tablespace \"" << old.getName() << "\": " 00509 << errobj << endl; 00510 00511 return false; 00512 break; 00513 } 00514 case DictTabInfo::LogfileGroup: 00515 { 00516 NdbDictionary::LogfileGroup old(*(NdbDictionary::LogfileGroup*)ptr); 00517 00518 Uint32 id = old.getObjectId(); 00519 00520 if (!m_no_restore_disk) 00521 { 00522 info << "Creating logfile group: " << old.getName() << "..." << flush; 00523 int ret = dict->createLogfileGroup(old); 00524 if (ret) 00525 { 00526 NdbError errobj= dict->getNdbError(); 00527 info << "FAILED" << endl; 00528 err << "Create logfile group failed: " << old.getName() << ": " << errobj << endl; 00529 return false; 00530 } 00531 info << "done" << endl; 00532 } 00533 00534 NdbDictionary::LogfileGroup curr = dict->getLogfileGroup(old.getName()); 00535 NdbError errobj = dict->getNdbError(); 00536 if(errobj.classification == ndberror_cl_none) 00537 { 00538 NdbDictionary::LogfileGroup* currptr = 00539 new NdbDictionary::LogfileGroup(curr); 00540 NdbDictionary::LogfileGroup * null = 0; 00541 m_logfilegroups.set(currptr, id, null); 00542 debug << "Retreived logfile group: " << currptr->getName() 00543 << " oldid: " << id << " newid: " << currptr->getObjectId() 00544 << " " << (void*)currptr << endl; 00545 return true; 00546 } 00547 00548 err << "Failed to retrieve logfile group \"" << old.getName() << "\": " 00549 << errobj << endl; 00550 00551 return false; 00552 break; 00553 } 00554 case DictTabInfo::Datafile: 00555 { 00556 if (!m_no_restore_disk) 00557 { 00558 NdbDictionary::Datafile old(*(NdbDictionary::Datafile*)ptr); 00559 NdbDictionary::ObjectId objid; 00560 old.getTablespaceId(&objid); 00561 NdbDictionary::Tablespace * ts = m_tablespaces[objid.getObjectId()]; 00562 debug << "Connecting datafile " << old.getPath() 00563 << " to tablespace: oldid: " << objid.getObjectId() 00564 << " newid: " << ts->getObjectId() << endl; 00565 old.setTablespace(* ts); 00566 info << "Creating datafile \"" << old.getPath() << "\"..." << flush; 00567 if (dict->createDatafile(old)) 00568 { 00569 NdbError errobj= dict->getNdbError(); 00570 info << "FAILED" << endl; 00571 err << "Create datafile failed: " << old.getPath() << ": " << errobj << endl; 00572 return false; 00573 } 00574 info << "done" << endl; 00575 } 00576 return true; 00577 break; 00578 } 00579 case DictTabInfo::Undofile: 00580 { 00581 if (!m_no_restore_disk) 00582 { 00583 NdbDictionary::Undofile old(*(NdbDictionary::Undofile*)ptr); 00584 NdbDictionary::ObjectId objid; 00585 old.getLogfileGroupId(&objid); 00586 NdbDictionary::LogfileGroup * lg = m_logfilegroups[objid.getObjectId()]; 00587 debug << "Connecting undofile " << old.getPath() 00588 << " to logfile group: oldid: " << objid.getObjectId() 00589 << " newid: " << lg->getObjectId() 00590 << " " << (void*)lg << endl; 00591 old.setLogfileGroup(* lg); 00592 info << "Creating undofile \"" << old.getPath() << "\"..." << flush; 00593 if (dict->createUndofile(old)) 00594 { 00595 NdbError errobj= dict->getNdbError(); 00596 info << "FAILED" << endl; 00597 err << "Create undofile failed: " << old.getPath() << ": " << errobj << endl; 00598 return false; 00599 } 00600 info << "done" << endl; 00601 } 00602 return true; 00603 break; 00604 } 00605 } 00606 return true; 00607 }
Here is the call graph for this function:

| void BackupRestore::release | ( | ) | [virtual] |
Definition at line 83 of file consumer_restore.cpp.
References m_callback, m_cluster_connection, and m_ndb.
Referenced by exitHandler(), init(), and ~BackupRestore().
00084 { 00085 if (m_ndb) 00086 { 00087 delete m_ndb; 00088 m_ndb= 0; 00089 } 00090 00091 if (m_callback) 00092 { 00093 delete [] m_callback; 00094 m_callback= 0; 00095 } 00096 00097 if (m_cluster_connection) 00098 { 00099 delete m_cluster_connection; 00100 m_cluster_connection= 0; 00101 } 00102 }
Here is the caller graph for this function:

| bool BackupRestore::search_replace | ( | char * | search_str, | |
| char ** | new_data, | |||
| const char ** | data, | |||
| const char * | end_data, | |||
| uint * | new_data_len | |||
| ) |
Definition at line 294 of file consumer_restore.cpp.
References copy_byte(), DBUG_ENTER, DBUG_RETURN, FALSE, map_ng(), MAX_NDB_NODES, strlen(), and TRUE.
Referenced by map_in_frm().
00297 { 00298 uint search_str_len = strlen(search_str); 00299 uint inx = 0; 00300 bool in_delimiters = FALSE; 00301 bool escape_char = FALSE; 00302 char start_delimiter = 0; 00303 DBUG_ENTER("search_replace"); 00304 00305 do 00306 { 00307 char c = **data; 00308 copy_byte(data, new_data, new_data_len); 00309 if (escape_char) 00310 { 00311 escape_char = FALSE; 00312 } 00313 else if (in_delimiters) 00314 { 00315 if (c == start_delimiter) 00316 in_delimiters = FALSE; 00317 } 00318 else if (c == '\'' || c == '\"') 00319 { 00320 in_delimiters = TRUE; 00321 start_delimiter = c; 00322 } 00323 else if (c == '\\') 00324 { 00325 escape_char = TRUE; 00326 } 00327 else if (c == search_str[inx]) 00328 { 00329 inx++; 00330 if (inx == search_str_len) 00331 { 00332 bool found = FALSE; 00333 uint number = 0; 00334 while (*data != end_data) 00335 { 00336 if (isdigit(**data)) 00337 { 00338 found = TRUE; 00339 number = (10 * number) + (**data); 00340 if (number > MAX_NDB_NODES) 00341 break; 00342 } 00343 else if (found) 00344 { 00345 /* 00346 After long and tedious preparations we have actually found 00347 a node group identifier to convert. We'll use the mapping 00348 table created for node groups and then insert the new number 00349 instead of the old number. 00350 */ 00351 uint temp = map_ng(number); 00352 int no_digits = 0; 00353 char digits[10]; 00354 while (temp != 0) 00355 { 00356 digits[no_digits] = temp % 10; 00357 no_digits++; 00358 temp/=10; 00359 } 00360 for (no_digits--; no_digits >= 0; no_digits--) 00361 { 00362 **new_data = digits[no_digits]; 00363 *new_data_len+=1; 00364 } 00365 DBUG_RETURN(FALSE); 00366 } 00367 else 00368 break; 00369 (*data)++; 00370 } 00371 DBUG_RETURN(TRUE); 00372 } 00373 } 00374 else 00375 inx = 0; 00376 } while (*data < end_data); 00377 DBUG_RETURN(FALSE); 00378 }
Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from BackupConsumer.
Definition at line 665 of file consumer_restore.cpp.
References NdbDictionary::Column::Blob, NdbError::classification, NdbError::code, mySTL::copy(), NdbDictionary::Dictionary::createEvent(), NdbDictionary::Dictionary::createTable(), debug, NdbDictionary::Dictionary::dropEvent(), NdbDictionary::Dictionary::dropTable(), err, Vector< T >::fill(), get_no_fragments(), NdbDictionary::Table::getColumn(), Ndb::getDictionary(), NdbDictionary::Table::getFrmData(), NdbTableImpl::getImpl(), NdbDictionary::Dictionary::getNdbError(), NdbDictionary::Table::getNoOfColumns(), NdbDictionary::Tablespace::getObjectId(), NdbDictionary::Dictionary::getTable(), id, info, m_cluster_connection, m_indexes, NdbTableImpl::m_indexType, m_ndb, m_new_tables, m_restore, m_restore_meta, m_tablespaces, map_nodegroups(), match_blob(), name, Ndb_cluster_connection::no_db_nodes(), Vector< T >::push_back(), NdbError::SchemaObjectExists, set_default_nodegroups(), Ndb::setDatabaseName(), Ndb::setSchemaName(), BaseString::split(), split(), NdbDictionary::Event::TE_ALL, NdbDictionary::Column::Text, translate_frm(), and NdbDictionary::Index::Undefined.
Referenced by finalize_table(), logEntry(), translate_frm(), and tuple_a().
00665 { 00666 if (!m_restore && !m_restore_meta) 00667 return true; 00668 00669 const char * name = table.getTableName(); 00670 00674 if(match_blob(name) >= 0) 00675 return true; 00676 00677 const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* table.m_dictTable); 00678 if(tmptab.m_indexType != NdbDictionary::Index::Undefined){ 00679 m_indexes.push_back(table.m_dictTable); 00680 return true; 00681 } 00682 00683 BaseString tmp(name); 00684 Vector<BaseString> split; 00685 if(tmp.split(split, "/") != 3){ 00686 err << "Invalid table name format " << name << endl; 00687 return false; 00688 } 00689 00690 m_ndb->setDatabaseName(split[0].c_str()); 00691 m_ndb->setSchemaName(split[1].c_str()); 00692 00693 NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); 00694 if(m_restore_meta) 00695 { 00696 NdbDictionary::Table copy(*table.m_dictTable); 00697 00698 copy.setName(split[2].c_str()); 00699 Uint32 id; 00700 if (copy.getTablespace(&id)) 00701 { 00702 debug << "Connecting " << name << " to tablespace oldid: " << id << flush; 00703 NdbDictionary::Tablespace* ts = m_tablespaces[id]; 00704 debug << " newid: " << ts->getObjectId() << endl; 00705 copy.setTablespace(* ts); 00706 } 00707 00708 if (copy.getDefaultNoPartitionsFlag()) 00709 { 00710 /* 00711 Table was defined with default number of partitions. We can restore 00712 it with whatever is the default in this cluster. 00713 We use the max_rows parameter in calculating the default number. 00714 */ 00715 Uint32 no_nodes = m_cluster_connection->no_db_nodes(); 00716 copy.setFragmentCount(get_no_fragments(copy.getMaxRows(), 00717 no_nodes)); 00718 set_default_nodegroups(©); 00719 } 00720 else 00721 { 00722 /* 00723 Table was defined with specific number of partitions. It should be 00724 restored with the same number of partitions. It will either be 00725 restored in the same node groups as when backup was taken or by 00726 using a node group map supplied to the ndb_restore program. 00727 */ 00728 Uint16 *ng_array = (Uint16*)copy.getFragmentData(); 00729 Uint16 no_parts = copy.getFragmentCount(); 00730 if (map_nodegroups(ng_array, no_parts)) 00731 { 00732 if (translate_frm(©)) 00733 { 00734 err << "Create table " << table.getTableName() << " failed: "; 00735 err << "Translate frm error" << endl; 00736 return false; 00737 } 00738 } 00739 copy.setFragmentData((const void *)ng_array, no_parts << 1); 00740 } 00741 00742 /* 00743 update min and max rows to reflect the table, this to 00744 ensure that memory is allocated properly in the ndb kernel 00745 */ 00746 copy.setMinRows(table.getNoOfRecords()); 00747 if (table.getNoOfRecords() > copy.getMaxRows()) 00748 { 00749 copy.setMaxRows(table.getNoOfRecords()); 00750 } 00751 00752 if (dict->createTable(copy) == -1) 00753 { 00754 err << "Create table " << table.getTableName() << " failed: " 00755 << dict->getNdbError() << endl; 00756 if (dict->getNdbError().code == 771) 00757 { 00758 /* 00759 The user on the cluster where the backup was created had specified 00760 specific node groups for partitions. Some of these node groups 00761 didn't exist on this cluster. We will warn the user of this and 00762 inform him of his option. 00763 */ 00764 err << "The node groups defined in the table didn't exist in this"; 00765 err << " cluster." << endl << "There is an option to use the"; 00766 err << " the parameter ndb-nodegroup-map to define a mapping from"; 00767 err << endl << "the old nodegroups to new nodegroups" << endl; 00768 } 00769 return false; 00770 } 00771 info << "Successfully restored table " << table.getTableName()<< endl ; 00772 } 00773 00774 const NdbDictionary::Table* tab = dict->getTable(split[2].c_str()); 00775 if(tab == 0){ 00776 err << "Unable to find table: " << split[2].c_str() << endl; 00777 return false; 00778 } 00779 if(m_restore_meta) 00780 { 00781 if (tab->getFrmData()) 00782 { 00783 // a MySQL Server table is restored, thus an event should be created 00784 BaseString event_name("REPL$"); 00785 event_name.append(split[0].c_str()); 00786 event_name.append("/"); 00787 event_name.append(split[2].c_str()); 00788 00789 NdbDictionary::Event my_event(event_name.c_str()); 00790 my_event.setTable(*tab); 00791 my_event.addTableEvent(NdbDictionary::Event::TE_ALL); 00792 00793 // add all columns to the event 00794 bool has_blobs = false; 00795 for(int a= 0; a < tab->getNoOfColumns(); a++) 00796 { 00797 my_event.addEventColumn(a); 00798 NdbDictionary::Column::Type t = tab->getColumn(a)->getType(); 00799 if (t == NdbDictionary::Column::Blob || 00800 t == NdbDictionary::Column::Text) 00801 has_blobs = true; 00802 } 00803 if (has_blobs) 00804 my_event.mergeEvents(true); 00805 00806 while ( dict->createEvent(my_event) ) // Add event to database 00807 { 00808 if (dict->getNdbError().classification == NdbError::SchemaObjectExists) 00809 { 00810 info << "Event for table " << table.getTableName() 00811 << " already exists, removing.\n"; 00812 if (!dict->dropEvent(my_event.getName())) 00813 continue; 00814 } 00815 err << "Create table event for " << table.getTableName() << " failed: " 00816 << dict->getNdbError() << endl; 00817 dict->dropTable(split[2].c_str()); 00818 return false; 00819 } 00820 info << "Successfully restored table event " << event_name << endl ; 00821 } 00822 } 00823 const NdbDictionary::Table* null = 0; 00824 m_new_tables.fill(table.m_dictTable->getTableId(), null); 00825 m_new_tables[table.m_dictTable->getTableId()] = tab; 00826 return true; 00827 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool BackupRestore::translate_frm | ( | NdbDictionary::Table * | table | ) |
Definition at line 424 of file consumer_restore.cpp.
References data, DBUG_ENTER, DBUG_RETURN, FALSE, map_in_frm(), my_free, my_malloc(), MYF, packfrm(), table(), TRUE, and unpackfrm().
Referenced by table().
00425 { 00426 const void *pack_data, *data, *new_pack_data; 00427 char *new_data; 00428 uint data_len, pack_len, new_data_len, new_pack_len; 00429 uint no_parts, extra_growth; 00430 DBUG_ENTER("translate_frm"); 00431 00432 pack_data = table->getFrmData(); 00433 no_parts = table->getFragmentCount(); 00434 /* 00435 Add max 4 characters per partition to handle worst case 00436 of mapping from single digit to 5-digit number. 00437 Fairly future-proof, ok up to 99999 node groups. 00438 */ 00439 extra_growth = no_parts * 4; 00440 if (unpackfrm(&data, &data_len, pack_data)) 00441 { 00442 DBUG_RETURN(TRUE); 00443 } 00444 if ((new_data = my_malloc(data_len + extra_growth, MYF(0)))) 00445 { 00446 DBUG_RETURN(TRUE); 00447 } 00448 if (map_in_frm(new_data, (const char*)data, data_len, &new_data_len)) 00449 { 00450 my_free(new_data, MYF(0)); 00451 DBUG_RETURN(TRUE); 00452 } 00453 if (packfrm((const void*)new_data, new_data_len, 00454 &new_pack_data, &new_pack_len)) 00455 { 00456 my_free(new_data, MYF(0)); 00457 DBUG_RETURN(TRUE); 00458 } 00459 table->setFrm(new_pack_data, new_pack_len); 00460 DBUG_RETURN(FALSE); 00461 }
Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from BackupConsumer.
Definition at line 888 of file consumer_restore.cpp.
References assert, restore_callback_t::fragId, m_free_callback, m_ndb, m_parallelism, m_restore, m_transactions, restore_callback_t::next, restore_callback_t::retries, Ndb::sendPollNdb(), restore_callback_t::tup, and tuple_a().
00889 { 00890 if (!m_restore) 00891 return; 00892 00893 while (m_free_callback == 0) 00894 { 00895 assert(m_transactions == m_parallelism); 00896 // send-poll all transactions 00897 // close transaction is done in callback 00898 m_ndb->sendPollNdb(3000, 1); 00899 } 00900 00901 restore_callback_t * cb = m_free_callback; 00902 00903 if (cb == 0) 00904 assert(false); 00905 00906 m_free_callback = cb->next; 00907 cb->retries = 0; 00908 cb->fragId = fragmentId; 00909 cb->tup = tup; // must do copy! 00910 tuple_a(cb); 00911 00912 }
Here is the call graph for this function:

| void BackupRestore::tuple_a | ( | restore_callback_t * | cb | ) | [virtual] |
Definition at line 914 of file consumer_restore.cpp.
References callback(), NdbTransaction::Commit, restore_callback_t::connection, err, restore_callback_t::error_code, errorHandler(), NdbTransaction::executeAsynchPrepare(), exitHandler(), restore_callback_t::fragId, get_part_id(), get_table(), TupleS::getData(), TupleS::getDesc(), Ndb::getNdbError(), NdbTransaction::getNdbError(), NdbTransaction::getNdbOperation(), TupleS::getNoOfAttributes(), TupleS::getTable(), TableS::have_auto_inc(), TableS::m_dictTable, m_ndb, m_transactions, ndbout_c(), AttributeData::null, NULL, restore_callback_t::retries, Ndb::sendPollNdb(), AttributeData::size, Ndb::startTransaction(), AttributeData::string_value, table(), restore_callback_t::tup, AttributeData::u_int32_value, TableS::update_max_auto_val(), and NdbDictionary::Object::UserDefined.
Referenced by cback(), and tuple().
00915 { 00916 Uint32 partition_id = cb->fragId; 00917 while (cb->retries < 10) 00918 { 00922 cb->connection = m_ndb->startTransaction(); 00923 if (cb->connection == NULL) 00924 { 00925 if (errorHandler(cb)) 00926 { 00927 m_ndb->sendPollNdb(3000, 1); 00928 continue; 00929 } 00930 err << "Cannot start transaction" << endl; 00931 exitHandler(); 00932 } // if 00933 00934 const TupleS &tup = cb->tup; 00935 const NdbDictionary::Table * table = get_table(tup.getTable()->m_dictTable); 00936 00937 NdbOperation * op = cb->connection->getNdbOperation(table); 00938 00939 if (op == NULL) 00940 { 00941 if (errorHandler(cb)) 00942 continue; 00943 err << "Cannot get operation: " << cb->connection->getNdbError() << endl; 00944 exitHandler(); 00945 } // if 00946 00947 if (op->writeTuple() == -1) 00948 { 00949 if (errorHandler(cb)) 00950 continue; 00951 err << "Error defining op: " << cb->connection->getNdbError() << endl; 00952 exitHandler(); 00953 } // if 00954 00955 if (table->getFragmentType() == NdbDictionary::Object::UserDefined) 00956 { 00957 if (table->getDefaultNoPartitionsFlag()) 00958 { 00959 /* 00960 This can only happen for HASH partitioning with 00961 user defined hash function where user hasn't 00962 specified the number of partitions and we 00963 have to calculate it. We use the hash value 00964 stored in the record to calculate the partition 00965 to use. 00966 */ 00967 int i = tup.getNoOfAttributes() - 1; 00968 const AttributeData *attr_data = tup.getData(i); 00969 Uint32 hash_value = *attr_data->u_int32_value; 00970 op->setPartitionId(get_part_id(table, hash_value)); 00971 } 00972 else 00973 { 00974 /* 00975 Either RANGE or LIST (with or without subparts) 00976 OR HASH partitioning with user defined hash 00977 function but with fixed set of partitions. 00978 */ 00979 op->setPartitionId(partition_id); 00980 } 00981 } 00982 int ret = 0; 00983 for (int j = 0; j < 2; j++) 00984 { 00985 for (int i = 0; i < tup.getNoOfAttributes(); i++) 00986 { 00987 const AttributeDesc * attr_desc = tup.getDesc(i); 00988 const AttributeData * attr_data = tup.getData(i); 00989 int size = attr_desc->size; 00990 int arraySize = attr_desc->arraySize; 00991 char * dataPtr = attr_data->string_value; 00992 Uint32 length = attr_data->size; 00993 00994 if (j == 0 && tup.getTable()->have_auto_inc(i)) 00995 tup.getTable()->update_max_auto_val(dataPtr,size); 00996 00997 if (attr_desc->m_column->getPrimaryKey()) 00998 { 00999 if (j == 1) continue; 01000 ret = op->equal(i, dataPtr, length); 01001 } 01002 else 01003 { 01004 if (j == 0) continue; 01005 if (attr_data->null) 01006 ret = op->setValue(i, NULL, 0); 01007 else 01008 ret = op->setValue(i, dataPtr, length); 01009 } 01010 if (ret < 0) { 01011 ndbout_c("Column: %d type %d %d %d %d",i, 01012 attr_desc->m_column->getType(), 01013 size, arraySize, attr_data->size); 01014 break; 01015 } 01016 } 01017 if (ret < 0) 01018 break; 01019 } 01020 if (ret < 0) 01021 { 01022 if (errorHandler(cb)) 01023 continue; 01024 err << "Error defining op: " << cb->connection->getNdbError() << endl; 01025 exitHandler(); 01026 } 01027 01028 // Prepare transaction (the transaction is NOT yet sent to NDB) 01029 cb->connection->executeAsynchPrepare(NdbTransaction::Commit, 01030 &callback, cb); 01031 m_transactions++; 01032 return; 01033 } 01034 err << "Retried transaction " << cb->retries << " times.\nLast error" 01035 << m_ndb->getNdbError(cb->error_code) << endl 01036 << "...Unable to recover from errors. Exiting..." << endl; 01037 exitHandler(); 01038 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void BackupRestore::tuple_free | ( | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 1134 of file consumer_restore.cpp.
References m_ndb, m_restore, m_transactions, and Ndb::sendPollNdb().
Referenced by endOfTuples().
01135 { 01136 if (!m_restore) 01137 return; 01138 01139 // Poll all transactions 01140 while (m_transactions) 01141 { 01142 m_ndb->sendPollNdb(3000); 01143 } 01144 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool BackupRestore::update_apply_status | ( | const RestoreMetaData & | metaData | ) | [virtual] |
Reimplemented from BackupConsumer.
Definition at line 610 of file consumer_restore.cpp.
References Ndb::closeTransaction(), NdbTransaction::Commit, NdbOperation::equal(), err, NdbTransaction::execute(), Ndb::getDictionary(), NdbOperation::getNdbError(), NdbTransaction::getNdbError(), Ndb::getNdbError(), NdbDictionary::Dictionary::getNdbError(), NdbTransaction::getNdbOperation(), RestoreMetaData::getStopGCP(), NdbDictionary::Dictionary::getTable(), m_ndb, m_restore_epoch, Ndb_apply_table, NDB_REP_DB, server_id, Ndb::setDatabaseName(), Ndb::setSchemaName(), NdbOperation::setValue(), Ndb::startTransaction(), and NdbOperation::writeTuple().
00611 { 00612 if (!m_restore_epoch) 00613 return true; 00614 00615 bool result= false; 00616 00617 m_ndb->setDatabaseName(NDB_REP_DB); 00618 m_ndb->setSchemaName("def"); 00619 00620 NdbDictionary::Dictionary *dict= m_ndb->getDictionary(); 00621 const NdbDictionary::Table *ndbtab= dict->getTable(Ndb_apply_table); 00622 if (!ndbtab) 00623 { 00624 err << Ndb_apply_table << ": " 00625 << dict->getNdbError() << endl; 00626 return false; 00627 } 00628 Uint32 server_id= 0; 00629 Uint64 epoch= metaData.getStopGCP(); 00630 NdbTransaction * trans= m_ndb->startTransaction(); 00631 if (!trans) 00632 { 00633 err << Ndb_apply_table << ": " 00634 << m_ndb->getNdbError() << endl; 00635 return false; 00636 } 00637 NdbOperation * op= trans->getNdbOperation(ndbtab); 00638 if (!op) 00639 { 00640 err << Ndb_apply_table << ": " 00641 << trans->getNdbError() << endl; 00642 goto err; 00643 } 00644 if (op->writeTuple() || 00645 op->equal(0u, (const char *)&server_id, sizeof(server_id)) || 00646 op->setValue(1u, (const char *)&epoch, sizeof(epoch))) 00647 { 00648 err << Ndb_apply_table << ": " 00649 << op->getNdbError() << endl; 00650 goto err; 00651 } 00652 if (trans->execute(NdbTransaction::Commit)) 00653 { 00654 err << Ndb_apply_table << ": " 00655 << trans->getNdbError() << endl; 00656 goto err; 00657 } 00658 result= true; 00659 err: 00660 m_ndb->closeTransaction(trans); 00661 return result; 00662 }
Here is the call graph for this function:

| struct { ... } BackupRestore::m_cache |
Referenced by BackupRestore(), and get_table().
Definition at line 97 of file consumer_restore.hpp.
Referenced by BackupRestore(), init(), and release().
Definition at line 86 of file consumer_restore.hpp.
Referenced by BackupRestore(), init(), release(), and table().
Definition at line 92 of file consumer_restore.hpp.
Referenced by BackupRestore(), cback(), and endOfLogEntrys().
Definition at line 98 of file consumer_restore.hpp.
Referenced by BackupRestore(), cback(), init(), and tuple().
Definition at line 91 of file consumer_restore.hpp.
Referenced by BackupRestore(), endOfLogEntrys(), and logEntry().
Definition at line 85 of file consumer_restore.hpp.
Referenced by BackupRestore(), cback(), endOfTables(), errorHandler(), finalize_table(), get_table(), init(), logEntry(), object(), release(), table(), tuple(), tuple_a(), tuple_free(), and update_apply_status().
Definition at line 108 of file consumer_restore.hpp.
m_new_table_ids[X] = Y; X - old table id Y != 0 - new table
Definition at line 105 of file consumer_restore.hpp.
Referenced by get_table(), and table().
Definition at line 89 of file consumer_restore.hpp.
Referenced by BackupRestore(), object(), and readArguments().
Definition at line 107 of file consumer_restore.hpp.
Definition at line 94 of file consumer_restore.hpp.
Referenced by BackupRestore(), init(), and tuple().
Definition at line 87 of file consumer_restore.hpp.
Referenced by BackupRestore(), endOfLogEntrys(), finalize_table(), init(), logEntry(), readArguments(), table(), tuple(), and tuple_free().
Definition at line 90 of file consumer_restore.hpp.
Referenced by BackupRestore(), init(), readArguments(), and update_apply_status().
Definition at line 88 of file consumer_restore.hpp.
Referenced by BackupRestore(), endOfTables(), finalize_table(), init(), object(), readArguments(), and table().
| volatile Uint32 BackupRestore::m_transactions |
Definition at line 95 of file consumer_restore.hpp.
Referenced by BackupRestore(), cback(), tuple(), tuple_a(), and tuple_free().
1.4.7

