summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2005-06-08 16:48:57 +0200
committerunknown <joreland@mysql.com>2005-06-08 16:48:57 +0200
commita7917b1e8aa10bf57c97443273771929dbadfd1d (patch)
tree42177a1f3346e87538ba6ad54bef296929cb7d21 /ndb
parentd4e921d639f102fa697d88529be40442e44b60c6 (diff)
downloadmariadb-git-a7917b1e8aa10bf57c97443273771929dbadfd1d.tar.gz
bug#11166 - ndb
Fix potential inconsistency when running ndb_restore due to faulty parsing of backup log wrt inserts ndb/src/kernel/blocks/backup/Backup.cpp: Make sure that entire stopGCP is in log ndb/tools/restore/Restore.cpp: Notice: this will not group and commit the deltas listed below into a ChangeSet, because there are no ChangeSet comments. Click [Checkin] again to check in only the commented deltas, or type Control-l to go back and provide ChangeSet comments. ndb/tools/restore/Restore.hpp: Keep track of last gci to next iteration ndb/tools/restore/consumer_restore.cpp: Handle insert in log Only allow certain errors
Diffstat (limited to 'ndb')
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp25
-rw-r--r--ndb/tools/restore/Restore.cpp8
-rw-r--r--ndb/tools/restore/Restore.hpp1
-rw-r--r--ndb/tools/restore/consumer_restore.cpp36
4 files changed, 57 insertions, 13 deletions
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index 3ef73beb8d2..b0ce5c390cb 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -1676,13 +1676,30 @@ Backup::execWAIT_GCP_CONF(Signal* signal){
ptr.p->masterData.sendCounter= 0;
ptr.p->masterData.gsn = GSN_BACKUP_FRAGMENT_REQ;
nextFragment(signal, ptr);
+ return;
} else {
jam();
- CRASH_INSERTION((10009));
- ptr.p->stopGCP = gcp;
- sendDropTrig(signal, ptr); // regular dropping of triggers
- }//if
+ if(gcp >= ptr.p->startGCP + 3)
+ {
+ CRASH_INSERTION((10009));
+ ptr.p->stopGCP = gcp;
+ sendDropTrig(signal, ptr); // regular dropping of triggers
+ return;
+ }//if
+
+ /**
+ * Make sure that we got entire stopGCP
+ */
+ WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
+ req->senderRef = reference();
+ req->senderData = ptr.i;
+ req->requestType = WaitGCPReq::CompleteForceStart;
+ sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
+ WaitGCPReq::SignalLength,JBB);
+ return;
+ }
}
+
/*****************************************************************************
*
* Master functionallity - Backup fragment
diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp
index fa616ee8fee..26bc08c63a9 100644
--- a/ndb/tools/restore/Restore.cpp
+++ b/ndb/tools/restore/Restore.cpp
@@ -765,6 +765,7 @@ RestoreLogIterator::RestoreLogIterator(const RestoreMetaData & md)
setLogFile(md, 0);
m_count = 0;
+ m_last_gci = 0;
}
const LogEntry *
@@ -772,7 +773,6 @@ RestoreLogIterator::getNextLogEntry(int & res) {
// Read record length
typedef BackupFormat::LogFile::LogEntry LogE;
- Uint32 gcp= 0;
LogE * logE= 0;
Uint32 len= ~0;
const Uint32 stopGCP = m_metaData.getStopGCP();
@@ -802,10 +802,10 @@ RestoreLogIterator::getNextLogEntry(int & res) {
if(hasGcp){
len--;
- gcp = ntohl(logE->Data[len-2]);
+ m_last_gci = ntohl(logE->Data[len-2]);
}
- } while(gcp > stopGCP + 1);
-
+ } while(m_last_gci > stopGCP + 1);
+
m_logEntry.m_table = m_metaData.getTable(logE->TableId);
switch(logE->TriggerEvent){
case TriggerEvent::TE_INSERT:
diff --git a/ndb/tools/restore/Restore.hpp b/ndb/tools/restore/Restore.hpp
index d7f6e3b7799..85793baf9df 100644
--- a/ndb/tools/restore/Restore.hpp
+++ b/ndb/tools/restore/Restore.hpp
@@ -361,6 +361,7 @@ private:
const RestoreMetaData & m_metaData;
Uint32 m_count;
+ Uint32 m_last_gci;
LogEntry m_logEntry;
public:
RestoreLogIterator(const RestoreMetaData &);
diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp
index fbe96cb2a71..9d161773bd2 100644
--- a/ndb/tools/restore/consumer_restore.cpp
+++ b/ndb/tools/restore/consumer_restore.cpp
@@ -512,7 +512,14 @@ BackupRestore::logEntry(const LogEntry & tup)
<< " Exiting...";
exit(-1);
}
+
+ if (check != 0)
+ {
+ err << "Error defining op: " << trans->getNdbError() << endl;
+ exit(-1);
+ } // if
+ Bitmask<4096> keys;
for (Uint32 i= 0; i < tup.size(); i++)
{
const AttributeS * attr = tup[i];
@@ -525,9 +532,21 @@ BackupRestore::logEntry(const LogEntry & tup)
const Uint32 length = (size / 8) * arraySize;
if (attr->Desc->m_column->getPrimaryKey())
- op->equal(attr->Desc->attrId, dataPtr, length);
+ {
+ if(!keys.get(attr->Desc->attrId))
+ {
+ keys.set(attr->Desc->attrId);
+ check= op->equal(attr->Desc->attrId, dataPtr, length);
+ }
+ }
else
- op->setValue(attr->Desc->attrId, dataPtr, length);
+ check= op->setValue(attr->Desc->attrId, dataPtr, length);
+
+ if (check != 0)
+ {
+ err << "Error defining op: " << trans->getNdbError() << endl;
+ exit(-1);
+ } // if
}
const int ret = trans->execute(Commit);
@@ -536,18 +555,25 @@ BackupRestore::logEntry(const LogEntry & tup)
// Both insert update and delete can fail during log running
// and it's ok
// TODO: check that the error is either tuple exists or tuple does not exist?
+ bool ok= false;
+ NdbError errobj= trans->getNdbError();
switch(tup.m_type)
{
case LogEntry::LE_INSERT:
+ if(errobj.status == NdbError::PermanentError &&
+ errobj.classification == NdbError::ConstraintViolation)
+ ok= true;
break;
case LogEntry::LE_UPDATE:
- break;
case LogEntry::LE_DELETE:
+ if(errobj.status == NdbError::PermanentError &&
+ errobj.classification == NdbError::NoDataFound)
+ ok= true;
break;
}
- if (false)
+ if (!ok)
{
- err << "execute failed: " << trans->getNdbError() << endl;
+ err << "execute failed: " << errobj << endl;
exit(-1);
}
}