Commit b181f610 authored by unknown's avatar unknown

bug#7379 & bug#7346 - ndb_restore


ndb/tools/restore/consumer_restore.cpp:
  1) Fix bug when blobs and multiple databases bug#7379
  2) Fix bug #7346
ndb/tools/restore/consumer_restore.hpp:
  Moved tuple handle into callback object 
    instead of having separate array
  Declared m_transactions volatile
parent 4935b27c
...@@ -52,19 +52,10 @@ BackupRestore::init() ...@@ -52,19 +52,10 @@ BackupRestore::init()
return false; return false;
} }
m_tuples = new TupleS[m_parallelism];
if (m_tuples == 0)
{
err << "Failed to allocate tuples" << endl;
return false;
}
m_free_callback= m_callback; m_free_callback= m_callback;
for (Uint32 i= 0; i < m_parallelism; i++) { for (Uint32 i= 0; i < m_parallelism; i++) {
m_callback[i].restore= this; m_callback[i].restore= this;
m_callback[i].connection= 0; m_callback[i].connection= 0;
m_callback[i].tup= &m_tuples[i];
if (i > 0) if (i > 0)
m_callback[i-1].next= &(m_callback[i]); m_callback[i-1].next= &(m_callback[i]);
} }
...@@ -86,12 +77,6 @@ void BackupRestore::release() ...@@ -86,12 +77,6 @@ void BackupRestore::release()
delete [] m_callback; delete [] m_callback;
m_callback= 0; m_callback= 0;
} }
if (m_tuples)
{
delete [] m_tuples;
m_tuples= 0;
}
} }
BackupRestore::~BackupRestore() BackupRestore::~BackupRestore()
...@@ -118,14 +103,21 @@ BackupRestore::get_table(const NdbDictionary::Table* tab){ ...@@ -118,14 +103,21 @@ BackupRestore::get_table(const NdbDictionary::Table* tab){
m_cache.m_old_table = tab; m_cache.m_old_table = tab;
int cnt, id1, id2; int cnt, id1, id2;
char buf[256]; char db[256], schema[256];
if((cnt = sscanf(tab->getName(), "%[^/]/%[^/]/NDB$BLOB_%d_%d", buf, buf, &id1, &id2)) == 4){ if((cnt = sscanf(tab->getName(), "%[^/]/%[^/]/NDB$BLOB_%d_%d",
BaseString::snprintf(buf, sizeof(buf), "NDB$BLOB_%d_%d", m_new_tables[id1]->getTableId(), id2); db, schema, &id1, &id2)) == 4){
m_cache.m_new_table = m_ndb->getDictionary()->getTable(buf); m_ndb->setDatabaseName(db);
m_ndb->setSchemaName(schema);
BaseString::snprintf(db, sizeof(db), "NDB$BLOB_%d_%d",
m_new_tables[id1]->getTableId(), id2);
m_cache.m_new_table = m_ndb->getDictionary()->getTable(db);
} else { } else {
m_cache.m_new_table = m_new_tables[tab->getTableId()]; m_cache.m_new_table = m_new_tables[tab->getTableId()];
} }
assert(m_cache.m_new_table);
return m_cache.m_new_table; return m_cache.m_new_table;
} }
...@@ -266,6 +258,14 @@ void BackupRestore::tuple(const TupleS & tup) ...@@ -266,6 +258,14 @@ void BackupRestore::tuple(const TupleS & tup)
if (!m_restore) if (!m_restore)
return; return;
while (m_free_callback == 0)
{
assert(m_transactions == m_parallelism);
// send-poll all transactions
// close transaction is done in callback
m_ndb->sendPollNdb(3000, 1);
}
restore_callback_t * cb = m_free_callback; restore_callback_t * cb = m_free_callback;
if (cb == 0) if (cb == 0)
...@@ -273,15 +273,9 @@ void BackupRestore::tuple(const TupleS & tup) ...@@ -273,15 +273,9 @@ void BackupRestore::tuple(const TupleS & tup)
m_free_callback = cb->next; m_free_callback = cb->next;
cb->retries = 0; cb->retries = 0;
*(cb->tup) = tup; // must do copy! cb->tup = tup; // must do copy!
tuple_a(cb); tuple_a(cb);
if (m_free_callback == 0)
{
// send-poll all transactions
// close transaction is done in callback
m_ndb->sendPollNdb(3000, 1);
}
} }
void BackupRestore::tuple_a(restore_callback_t *cb) void BackupRestore::tuple_a(restore_callback_t *cb)
...@@ -303,7 +297,7 @@ void BackupRestore::tuple_a(restore_callback_t *cb) ...@@ -303,7 +297,7 @@ void BackupRestore::tuple_a(restore_callback_t *cb)
exitHandler(); exitHandler();
} // if } // if
const TupleS &tup = *(cb->tup); const TupleS &tup = cb->tup;
const NdbDictionary::Table * table = get_table(tup.getTable()->m_dictTable); const NdbDictionary::Table * table = get_table(tup.getTable()->m_dictTable);
NdbOperation * op = cb->connection->getNdbOperation(table); NdbOperation * op = cb->connection->getNdbOperation(table);
...@@ -372,7 +366,9 @@ void BackupRestore::tuple_a(restore_callback_t *cb) ...@@ -372,7 +366,9 @@ void BackupRestore::tuple_a(restore_callback_t *cb)
m_transactions++; m_transactions++;
return; return;
} }
err << "Unable to recover from errors. Exiting..." << endl; err << "Retried transaction " << cb->retries << " times.\nLast error"
<< m_ndb->getNdbError(cb->error_code) << endl
<< "...Unable to recover from errors. Exiting..." << endl;
exitHandler(); exitHandler();
} }
...@@ -416,7 +412,12 @@ bool BackupRestore::errorHandler(restore_callback_t *cb) ...@@ -416,7 +412,12 @@ bool BackupRestore::errorHandler(restore_callback_t *cb)
NdbError error= cb->connection->getNdbError(); NdbError error= cb->connection->getNdbError();
m_ndb->closeTransaction(cb->connection); m_ndb->closeTransaction(cb->connection);
cb->connection= 0; cb->connection= 0;
Uint32 sleepTime = 100 + cb->retries * 300;
cb->retries++; cb->retries++;
cb->error_code = error.code;
switch(error.status) switch(error.status)
{ {
case NdbError::Success: case NdbError::Success:
...@@ -425,7 +426,7 @@ bool BackupRestore::errorHandler(restore_callback_t *cb) ...@@ -425,7 +426,7 @@ bool BackupRestore::errorHandler(restore_callback_t *cb)
break; break;
case NdbError::TemporaryError: case NdbError::TemporaryError:
NdbSleep_MilliSleep(10); NdbSleep_MilliSleep(sleepTime);
return true; return true;
// RETRY // RETRY
break; break;
...@@ -438,15 +439,6 @@ bool BackupRestore::errorHandler(restore_callback_t *cb) ...@@ -438,15 +439,6 @@ bool BackupRestore::errorHandler(restore_callback_t *cb)
default: default:
case NdbError::PermanentError: case NdbError::PermanentError:
switch (error.code)
{
case 499:
case 250:
NdbSleep_MilliSleep(10);
return true; //temp errors?
default:
break;
}
//ERROR //ERROR
err << error << endl; err << error << endl;
return false; return false;
...@@ -468,13 +460,10 @@ BackupRestore::tuple_free() ...@@ -468,13 +460,10 @@ BackupRestore::tuple_free()
if (!m_restore) if (!m_restore)
return; return;
if (m_transactions > 0) {
// Send all transactions to NDB
m_ndb->sendPreparedTransactions(0);
// Poll all transactions // Poll all transactions
while (m_transactions > 0) while (m_transactions)
m_ndb->pollNdb(3000, m_transactions); {
m_ndb->sendPollNdb(3000);
} }
} }
......
...@@ -21,9 +21,10 @@ ...@@ -21,9 +21,10 @@
struct restore_callback_t { struct restore_callback_t {
class BackupRestore *restore; class BackupRestore *restore;
class TupleS *tup; class TupleS tup;
class NdbConnection *connection; class NdbConnection *connection;
int retries; int retries;
int error_code;
restore_callback_t *next; restore_callback_t *next;
}; };
...@@ -39,7 +40,6 @@ public: ...@@ -39,7 +40,6 @@ public:
m_restore_meta = false; m_restore_meta = false;
m_parallelism = parallelism; m_parallelism = parallelism;
m_callback = 0; m_callback = 0;
m_tuples = 0;
m_free_callback = 0; m_free_callback = 0;
m_transactions = 0; m_transactions = 0;
m_cache.m_old_table = 0; m_cache.m_old_table = 0;
...@@ -68,9 +68,8 @@ public: ...@@ -68,9 +68,8 @@ public:
Uint32 m_dataCount; Uint32 m_dataCount;
Uint32 m_parallelism; Uint32 m_parallelism;
Uint32 m_transactions; volatile Uint32 m_transactions;
TupleS *m_tuples;
restore_callback_t *m_callback; restore_callback_t *m_callback;
restore_callback_t *m_free_callback; restore_callback_t *m_free_callback;
......
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