#At file:///home/frazer/bzr/mysql-5.1-telco-6.2/
3019 Frazer Clement 2009-10-16
Bug#48113 : Ndb : Insert hitting DD space exhaustion does not lock following tuple ops
modified:
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
storage/ndb/test/ndbapi/testBasic.cpp
storage/ndb/test/run-test/daily-basic-tests.txt
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2009-10-16 15:37:14 +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'
--- a/storage/ndb/test/ndbapi/testBasic.cpp 2009-05-26 18:53:34 +0000
+++ b/storage/ndb/test/ndbapi/testBasic.cpp 2009-10-16 15:37:14 +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; i<tab->getNoOfColumns(); 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, 0) == 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<NdbRecAttr*>;
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'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2009-10-12 11:47:31 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2009-10-16 15:37:14 +0000
@@ -1366,3 +1366,7 @@ max-time: 300
cmd: testNdbApi
args: -n ReadColumnDuplicates
+max-time: 300
+cmd: testBasic
+args: -n DDInsertFailUpdateBatch D1 D2
+
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-6.2 branch (frazer:3019) Bug#48113 | Frazer Clement | 16 Oct |