summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2005-06-08 16:55:06 +0200
committerunknown <joreland@mysql.com>2005-06-08 16:55:06 +0200
commitdbfce2a55576b0a55b219110193e8fce32a78981 (patch)
tree76cc090a86aec7dcae3a4d44cc449a1e3bb0cc22
parente595b7ee9db2e1aecadc68a11d821b65c42de1a1 (diff)
parenta7917b1e8aa10bf57c97443273771929dbadfd1d (diff)
downloadmariadb-git-dbfce2a55576b0a55b219110193e8fce32a78981.tar.gz
Merge mysql.com:/home/jonas/src/mysql-4.1
into mysql.com:/home/jonas/src/mysql-5.0 ndb/src/kernel/blocks/backup/Backup.cpp: Auto merged ndb/src/kernel/blocks/dbacc/DbaccMain.cpp: Auto merged ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Auto merged ndb/test/ndbapi/testNdbApi.cpp: Auto merged ndb/test/run-test/daily-basic-tests.txt: Auto merged ndb/tools/restore/Restore.cpp: Auto merged ndb/tools/restore/consumer_restore.cpp: Auto merged
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp25
-rw-r--r--ndb/src/kernel/blocks/dbacc/DbaccMain.cpp13
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp27
-rw-r--r--ndb/test/ndbapi/testNdbApi.cpp239
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt4
-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
8 files changed, 326 insertions, 27 deletions
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index fdff2702bec..327fcc33aff 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/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
index 0054b935cdb..24f9715c8b4 100644
--- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
@@ -1668,7 +1668,7 @@ void Dbacc::initOpRec(Signal* signal)
void Dbacc::sendAcckeyconf(Signal* signal)
{
signal->theData[0] = operationRecPtr.p->userptr;
- signal->theData[1] = operationRecPtr.p->insertIsDone;
+ signal->theData[1] = operationRecPtr.p->operation;
signal->theData[2] = operationRecPtr.p->fid;
signal->theData[3] = operationRecPtr.p->localdata[0];
signal->theData[4] = operationRecPtr.p->localdata[1];
@@ -1754,6 +1754,11 @@ void Dbacc::execACCKEYREQ(Signal* signal)
case ZWRITE:
case ZSCAN_OP:
if (!tgeLocked){
+ if(operationRecPtr.p->operation == ZWRITE)
+ {
+ jam();
+ operationRecPtr.p->operation = ZUPDATE;
+ }
sendAcckeyconf(signal);
if (operationRecPtr.p->dirtyRead == ZFALSE) {
/*---------------------------------------------------------------*/
@@ -2279,6 +2284,12 @@ Uint32 Dbacc::placeWriteInLockQueue(Signal* signal)
return ZWRITE_ERROR;
}//if
+ if(operationRecPtr.p->operation == ZWRITE)
+ {
+ operationRecPtr.p->operation =
+ (mlpqOperPtr.p->operation == ZDELETE) ? ZINSERT : ZUPDATE;
+ }
+
operationRecPtr.p->localdata[0] = queOperPtr.p->localdata[0];
operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1];
operationRecPtr.p->prevParallelQue = mlpqOperPtr.i;
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 138a2526804..725ea04c148 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -3905,20 +3905,21 @@ void Dblqh::execACCKEYCONF(Signal* signal)
* EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
* IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A
* TABLE.
- * ------------------------------------------------------------------------ */
- if (regTcPtr->operation == ZWRITE) {
- if (signal->theData[1] > 0) {
- /* --------------------------------------------------------------------
- * ACC did perform an insert and thus we should indicate that the WRITE
- * is an INSERT otherwise it is an UPDATE.
- * -------------------------------------------------------------------- */
- jam();
- regTcPtr->operation = ZINSERT;
- } else {
- jam();
- tcConnectptr.p->operation = ZUPDATE;
- }//if
+ * ----------------------------------------------------------------------- */
+ if (regTcPtr->operation == ZWRITE)
+ {
+ Uint32 op= signal->theData[1];
+ if(likely(op == ZINSERT || op == ZUPDATE))
+ {
+ regTcPtr->operation = op;
+ }
+ else
+ {
+ warningEvent("Convering %d to ZUPDATE", op);
+ regTcPtr->operation = ZUPDATE;
+ }
}//if
+
ndbrequire(localKeyFlag == 1);
localKey2 = localKey1 & MAX_TUPLES_PER_PAGE;
localKey1 = localKey1 >> MAX_TUPLES_BITS;
diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp
index ad1b1462ae7..65324af6fe6 100644
--- a/ndb/test/ndbapi/testNdbApi.cpp
+++ b/ndb/test/ndbapi/testNdbApi.cpp
@@ -1037,6 +1037,239 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
return result;
}
+int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ const NdbDictionary::Table* pTab = ctx->getTab();
+
+ HugoOperations hugoOps(*pTab);
+
+ Ndb* pNdb = GETNDB(step);
+ Uint32 lm;
+
+ NdbConnection* pCon = pNdb->startTransaction();
+ if (pCon == NULL){
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
+ if (pOp == NULL){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->readTuple(NdbOperation::LM_Exclusive) != 0){
+ pNdb->closeTransaction(pCon);
+ ERR(pOp->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() == true){
+ if(hugoOps.equalForAttr(pOp, a, 1) != 0){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() != true){
+ if (pOp->getValue(pTab->getColumn(a)->getName()) == NULL) {
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ int check = pCon->execute(NoCommit);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
+ }
+
+ pOp = pCon->getNdbOperation(pTab->getName());
+ if (pOp == NULL){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->deleteTuple() != 0){
+ pNdb->closeTransaction(pCon);
+ ERR(pOp->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() == true){
+ if(hugoOps.equalForAttr(pOp, a, 1) != 0){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ check = pCon->execute(NoCommit);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
+ }
+
+ pOp = pCon->getNdbOperation(pTab->getName());
+ if (pOp == NULL){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->writeTuple() != 0){
+ pNdb->closeTransaction(pCon);
+ ERR(pOp->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() == true){
+ if(hugoOps.equalForAttr(pOp, a, 1) != 0){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() != true){
+ if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
+ {
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ check = pCon->execute(NoCommit);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
+ }
+
+ pOp = pCon->getNdbOperation(pTab->getName());
+ if (pOp == NULL){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->writeTuple() != 0){
+ pNdb->closeTransaction(pCon);
+ ERR(pOp->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() == true){
+ if(hugoOps.equalForAttr(pOp, a, 1) != 0){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() != true){
+ if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
+ {
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ check = pCon->execute(NoCommit);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
+ }
+
+ check = pCon->execute(Rollback);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
+ }
+
+ pCon->close();
+
+ pCon = pNdb->startTransaction();
+ if (pCon == NULL){
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ pOp = pCon->getNdbOperation(pTab->getName());
+ if (pOp == NULL){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->writeTuple() != 0){
+ pNdb->closeTransaction(pCon);
+ ERR(pOp->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() == true){
+ if(hugoOps.equalForAttr(pOp, a, 1) != 0){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ for(int a = 0; a<pTab->getNoOfColumns(); a++){
+ if (pTab->getColumn(a)->getPrimaryKey() != true){
+ if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
+ {
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ check = pCon->execute(Commit);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
+ }
+
+ return result;
+}
+
+
NDBT_TESTSUITE(testNdbApi);
TESTCASE("MaxNdb",
@@ -1112,6 +1345,12 @@ TESTCASE("ReadWithoutGetValue",
INITIALIZER(runReadWithoutGetValue);
FINALIZER(runClearTable);
}
+TESTCASE("Bug_11133",
+ "Test ReadEx-Delete-Write\n"){
+ INITIALIZER(runLoadTable);
+ INITIALIZER(runBug_11133);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index e3d7501e6f7..ce9f97a9cb2 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -516,6 +516,10 @@ max-time: 500
cmd: testNdbApi
args: -n ReadWithoutGetValue
+max-time: 500
+cmd: testNdbApi
+args: -n Bug_11133 T1
+
#max-time: 500
#cmd: testInterpreter
#args: T1
diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp
index 81a8d4aba41..b53255820db 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 d72b82569e2..b20f9fd3204 100644
--- a/ndb/tools/restore/consumer_restore.cpp
+++ b/ndb/tools/restore/consumer_restore.cpp
@@ -526,7 +526,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];
@@ -539,9 +546,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(NdbTransaction::Commit);
@@ -550,18 +569,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);
}
}