From: Date: June 8 2005 4:49pm Subject: bk commit into 4.1 tree (joreland:1.2277) BUG#11166 List-Archive: http://lists.mysql.com/internals/25757 X-Bug: 11166 Message-Id: <20050608144903.67101DCB92@eel.ndb.mysql.com.ndb.mysql.com> Below is the list of changes that have just been committed into a local 4.1 repository of jonas. When jonas does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2277 05/06/08 16:48:57 joreland@stripped +4 -0 bug#11166 - ndb Fix potential inconsistency when running ndb_restore due to faulty parsing of backup log wrt inserts ndb/tools/restore/consumer_restore.cpp 1.11 05/06/08 16:48:54 joreland@stripped +31 -5 Handle insert in log Only allow certain errors ndb/tools/restore/Restore.hpp 1.19 05/06/08 16:48:54 joreland@stripped +1 -0 Keep track of last gci to next iteration ndb/tools/restore/Restore.cpp 1.23 05/06/08 16:48:54 joreland@stripped +4 -4 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/src/kernel/blocks/backup/Backup.cpp 1.17 05/06/08 16:48:54 joreland@stripped +21 -4 Make sure that entire stopGCP is in log # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: joreland # Host: eel.ndb.mysql.com.ndb.mysql.com # Root: /home/jonas/src/mysql-4.1 --- 1.16/ndb/src/kernel/blocks/backup/Backup.cpp Mon Apr 25 08:35:15 2005 +++ 1.17/ndb/src/kernel/blocks/backup/Backup.cpp Wed Jun 8 16:48:54 2005 @@ -1676,13 +1676,30 @@ 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 --- 1.22/ndb/tools/restore/Restore.cpp Thu Dec 16 14:16:24 2004 +++ 1.23/ndb/tools/restore/Restore.cpp Wed Jun 8 16:48:54 2005 @@ -765,6 +765,7 @@ setLogFile(md, 0); m_count = 0; + m_last_gci = 0; } const LogEntry * @@ -772,7 +773,6 @@ // 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 @@ 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: --- 1.18/ndb/tools/restore/Restore.hpp Mon Jan 17 12:29:32 2005 +++ 1.19/ndb/tools/restore/Restore.hpp Wed Jun 8 16:48:54 2005 @@ -361,6 +361,7 @@ const RestoreMetaData & m_metaData; Uint32 m_count; + Uint32 m_last_gci; LogEntry m_logEntry; public: RestoreLogIterator(const RestoreMetaData &); --- 1.10/ndb/tools/restore/consumer_restore.cpp Fri Dec 17 10:27:55 2004 +++ 1.11/ndb/tools/restore/consumer_restore.cpp Wed Jun 8 16:48:54 2005 @@ -512,7 +512,14 @@ << " 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 @@ 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 @@ // 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); } }