=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp' --- storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2009-05-26 18:53:34 +0000 +++ storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2009-10-16 12:02:39 +0000 @@ -1342,6 +1342,7 @@ int Dbtup::handleInsertReq(Signal* signa regTabPtr->m_attributes[MM].m_no_of_dynamic); bool varalloc = vardynsize || regTabPtr->m_bits & Tablerec::TR_ForceVarPart; bool rowid = req_struct->m_use_rowid; + bool update_acc = false; Uint32 real_page_id = regOperPtr.p->m_tuple_location.m_page_no; Uint32 frag_page_id = req_struct->frag_page_id; @@ -1543,17 +1544,12 @@ int Dbtup::handleInsertReq(Signal* signa } } real_page_id = regOperPtr.p->m_tuple_location.m_page_no; - regOperPtr.p->m_tuple_location.m_page_no= frag_page_id; - c_lqh->accminupdate(signal, - regOperPtr.p->userpointer, - ®OperPtr.p->m_tuple_location); + update_acc = true; /* Will be updated later once success is known */ base = (Tuple_header*)ptr; base->m_operation_ptr_i= regOperPtr.i; base->m_header_bits= Tuple_header::ALLOC | (vardynsize ? Tuple_header::VAR_PART : 0); - - regOperPtr.p->m_tuple_location.m_page_no = real_page_id; } else { @@ -1610,6 +1606,25 @@ int Dbtup::handleInsertReq(Signal* signa disk_ptr->m_header_bits = 0; disk_ptr->m_base_record_ref= ref.ref(); } + + /* Have been successful with disk + mem, update ACC to point to + * new record if necessary + * Failures in disk alloc will skip this part + */ + if (update_acc) + { + /* Acc stores the local key with the frag_page_id rather + * than the real_page_id + */ + ndbassert(regOperPtr.p->m_tuple_location.m_page_no == real_page_id); + + Local_key accKey = regOperPtr.p->m_tuple_location; + accKey.m_page_no = frag_page_id; + + c_lqh->accminupdate(signal, + regOperPtr.p->userpointer, + &accKey); + } if (regTabPtr->m_bits & Tablerec::TR_Checksum) { === modified file 'storage/ndb/test/ndbapi/testBasic.cpp' --- storage/ndb/test/ndbapi/testBasic.cpp 2009-05-26 18:53:34 +0000 +++ storage/ndb/test/ndbapi/testBasic.cpp 2009-10-16 12:03:02 +0000 @@ -1526,6 +1526,71 @@ runBug20535(NDBT_Context* ctx, NDBT_Step return NDBT_FAILED; } + +int +runDDInsertFailUpdateBatch(NDBT_Context* ctx, NDBT_Step* step) +{ + NdbRestarter restarter; + + const NdbDictionary::Table * tab = ctx->getTab(); + + { + bool tabHasDD = false; + + for(int i = 0; igetNoOfColumns(); i++) + { + tabHasDD |= (tab->getColumn(i)->getStorageType() == + NdbDictionary::Column::StorageTypeDisk); + } + + if (!tabHasDD) + { + ndbout_c("Table %s has no disk attributes, skipping", + tab->getName()); + return NDBT_OK; + } + } + + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + /* Error Insert 4021 - DD tuple insert will fail in disk + * space preallocation step + */ + restarter.insertErrorInAllNodes(4021); + + int result = NDBT_OK; + + for (Uint32 loop = 0; loop < 100; loop ++) + { + CHECK(hugoOps.startTransaction(pNdb) == 0); + + /* Create batch with insert op (which will fail due to disk allocation issue) + * followed by update op on same pk + * Transaction will abort due to insert failure, and reason should be + * disk space exhaustion, not any issue with the update. + */ + CHECK(hugoOps.pkInsertRecord(pNdb, loop, 1, NdbOperation::LM_Exclusive) == 0); + + /* Add up to 16 updates after the insert */ + Uint32 numUpdates = 1 + (loop % 15); + for (Uint32 updateCnt = 0; updateCnt < numUpdates; updateCnt++) + CHECK(hugoOps.pkUpdateRecord(pNdb, loop, 1, 1+updateCnt) == 0); + + CHECK(hugoOps.execute_Commit(pNdb) != 0); /* Expect failure */ + + NdbError err= hugoOps.getTransaction()->getNdbError(); + + CHECK(err.code == 1601); // Disk prealloc error + + hugoOps.closeTransaction(pNdb); + } + + restarter.insertErrorInAllNodes(0); + + return result; +} + template class Vector; NDBT_TESTSUITE(testBasic); @@ -1823,6 +1888,10 @@ TESTCASE("Bug20535", "Verify what happens when we fill the db" ){ STEP(runBug20535); } +TESTCASE("DDInsertFailUpdateBatch", + "Verify DD insert failure effect on other ops in batch on same PK"){ + STEP(runDDInsertFailUpdateBatch); +} NDBT_TESTSUITE_END(testBasic); #if 0 === modified file 'storage/ndb/test/run-test/daily-basic-tests.txt' --- storage/ndb/test/run-test/daily-basic-tests.txt 2009-10-12 11:47:31 +0000 +++ storage/ndb/test/run-test/daily-basic-tests.txt 2009-10-16 12:04:05 +0000 @@ -1366,3 +1366,7 @@ max-time: 300 cmd: testNdbApi args: -n ReadColumnDuplicates +max-time: 300 +cmd: testBasic +args: -n DDInsertFailUpdateBatch D1 D2 +