From 3e3842fa2e4ecd6f1014f6e20282fe2c475a67a4 Mon Sep 17 00:00:00 2001
From: unknown <jonas@perch.ndb.mysql.com>
Date: Mon, 24 Apr 2006 09:02:46 +0200
Subject: [PATCH] ndb - bug#18780   Fix various abort cases (mainly MM but also
 1 DD)     that has been found running dbt2

storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp:
  Fix abort case
storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp:
  Set page dirty even if in cache
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp:
  Fix abort case
storage/ndb/test/ndbapi/testBasic.cpp:
  Add new testcases for various abort cases
storage/ndb/test/run-test/daily-basic-tests.txt:
  Add autotest of various abort cases
---
 .../src/kernel/blocks/dbtup/DbtupAbort.cpp    | 14 +++++-
 .../kernel/blocks/dbtup/DbtupDiskAlloc.cpp    | 11 ++---
 .../kernel/blocks/dbtup/DbtupExecQuery.cpp    |  9 ++--
 storage/ndb/test/ndbapi/testBasic.cpp         | 45 +++++++++++++++++++
 .../ndb/test/run-test/daily-basic-tests.txt   | 10 +++--
 5 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp
index 273ccb9e1e..aa55985c1f 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp
@@ -118,7 +118,8 @@ void Dbtup::execTUP_ABORTREQ(Signal* signal)
   PagePtr page;
   Tuple_header *tuple_ptr= (Tuple_header*)
     get_ptr(&page, &regOperPtr.p->m_tuple_location, regTabPtr.p);
-  
+
+  Uint32 bits= tuple_ptr->m_header_bits;  
   if(regOperPtr.p->op_struct.op_type != ZDELETE)
   {
     Tuple_header *copy= (Tuple_header*)
@@ -132,7 +133,7 @@ void Dbtup::execTUP_ABORTREQ(Signal* signal)
       disk_page_abort_prealloc(signal, regFragPtr.p, &key, key.m_page_idx);
     }
     
-    Uint32 bits= tuple_ptr->m_header_bits;
+
     Uint32 copy_bits= copy->m_header_bits;
     if(! (bits & Tuple_header::ALLOC))
     {
@@ -174,6 +175,15 @@ void Dbtup::execTUP_ABORTREQ(Signal* signal)
       tuple_ptr->m_header_bits |= Tuple_header::FREED;
     }
   }
+  else if (regOperPtr.p->is_first_operation() && 
+	   regOperPtr.p->is_last_operation())
+  {
+    if (bits & Tuple_header::ALLOC)
+    {
+      tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
+      tuple_ptr->m_header_bits |= Tuple_header::FREED;
+    }
+  }
   
   if(regOperPtr.p->is_first_operation() && regOperPtr.p->is_last_operation())
   {
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
index ec3231f55f..56f7fb1dd1 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
@@ -1053,7 +1053,6 @@ Dbtup::disk_page_abort_prealloc_callback(Signal* signal,
   Ptr<Fragrecord> fragPtr;
   getFragmentrec(fragPtr, pagePtr.p->m_fragment_id, tabPtr.p);
 
-  disk_page_set_dirty(pagePtr);
   disk_page_abort_prealloc_callback_1(signal, fragPtr.p, pagePtr, sz);
 }
 
@@ -1063,6 +1062,9 @@ Dbtup::disk_page_abort_prealloc_callback_1(Signal* signal,
 					   PagePtr pagePtr,
 					   Uint32 sz)
 {
+  jam();
+  disk_page_set_dirty(pagePtr);
+
   Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
   Uint32 page_idx = pagePtr.p->list_index;
   Uint32 used = pagePtr.p->uncommitted_used_space;
@@ -1075,13 +1077,6 @@ Dbtup::disk_page_abort_prealloc_callback_1(Signal* signal,
   ddassert(alloc.calc_page_free_bits(free - used) == old_idx);
   Uint32 new_idx = alloc.calc_page_free_bits(free - used + sz);
 
-#ifdef VM_TRACE
-  Local_key key;
-  key.m_page_no = pagePtr.p->m_page_no;
-  key.m_file_no = pagePtr.p->m_file_no;
-  ndbout << "disk_page_abort_prealloc_callback_1" << key << endl;
-#endif
-  
   Ptr<Extent_info> extentPtr;
   c_extent_pool.getPtr(extentPtr, ext);
   if (old_idx != new_idx)
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index ff917c8482..0000796d7b 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -1408,8 +1408,6 @@ int Dbtup::handleInsertReq(Signal* signal,
     }
     req_struct->m_use_rowid = false;
     base->m_header_bits &= ~(Uint32)Tuple_header::FREE;
-    base->m_header_bits |= Tuple_header::ALLOC & 
-      (regOperPtr.p->is_first_operation() ? ~0 : 1);
   }
   else
   {
@@ -1418,8 +1416,6 @@ int Dbtup::handleInsertReq(Signal* signal,
     {
       ndbout_c("no mem insert but rowid (same)");
       base->m_header_bits &= ~(Uint32)Tuple_header::FREE;
-      base->m_header_bits |= Tuple_header::ALLOC & 
-	(regOperPtr.p->is_first_operation() ? ~0 : 1);
     }
     else
     {
@@ -1427,6 +1423,9 @@ int Dbtup::handleInsertReq(Signal* signal,
       ndbrequire(false);
     }
   }
+
+  base->m_header_bits |= Tuple_header::ALLOC & 
+    (regOperPtr.p->is_first_operation() ? ~0 : 1);
   
   if (disk_insert)
   {
@@ -2888,7 +2887,7 @@ Dbtup::handle_size_change_after_update(KeyReqStruct* req_struct,
     
     if(needed <= alloc)
     {
-      ndbassert(!regOperPtr->is_first_operation());
+      //ndbassert(!regOperPtr->is_first_operation());
       ndbout_c(" no grow");
       return 0;
     }
diff --git a/storage/ndb/test/ndbapi/testBasic.cpp b/storage/ndb/test/ndbapi/testBasic.cpp
index 69f3d8daef..d45a8ecb7b 100644
--- a/storage/ndb/test/ndbapi/testBasic.cpp
+++ b/storage/ndb/test/ndbapi/testBasic.cpp
@@ -1041,6 +1041,38 @@ runMassiveRollback3(NDBT_Context* ctx, NDBT_Step* step){
   HugoOperations hugoOps(*ctx->getTab());
   Ndb* pNdb = GETNDB(step);
 
+  const Uint32 BATCH = 10;
+  const Uint32 OPS_TOTAL = 50;
+  const Uint32 LOOPS = 100;
+  
+  for(Uint32 loop = 0; loop<LOOPS; loop++)
+  {
+    CHECK(hugoOps.startTransaction(pNdb) == 0);  
+    bool ok = true;
+    for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
+    {
+      CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
+      if (hugoOps.execute_NoCommit(pNdb) != 0)
+      {
+	ok = false;
+	break;
+      }
+    }
+    hugoOps.execute_Rollback(pNdb);
+    CHECK(hugoOps.closeTransaction(pNdb) == 0);
+  }
+  
+  hugoOps.closeTransaction(pNdb);
+  return result;
+}
+
+int
+runMassiveRollback4(NDBT_Context* ctx, NDBT_Step* step){
+
+  int result = NDBT_OK;
+  HugoOperations hugoOps(*ctx->getTab());
+  Ndb* pNdb = GETNDB(step);
+
   const Uint32 BATCH = 10;
   const Uint32 OPS_TOTAL = 20;
   const Uint32 LOOPS = 100;
@@ -1052,6 +1084,12 @@ runMassiveRollback3(NDBT_Context* ctx, NDBT_Step* step){
     for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
     {
       CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
+      CHECK(hugoOps.pkDeleteRecord(pNdb, i, BATCH) == 0);
+      if (hugoOps.execute_NoCommit(pNdb) != 0)
+      {
+	ok = false;
+	break;
+      }
       if (hugoOps.execute_NoCommit(pNdb) != 0)
       {
 	ok = false;
@@ -1399,6 +1437,13 @@ TESTCASE("MassiveRollback3",
   STEP(runMassiveRollback3);
   FINALIZER(runClearTable2);
 }
+TESTCASE("MassiveRollback4", 
+	 "Test rollback of 4096 operations"){
+  INITIALIZER(runClearTable2);
+  STEP(runMassiveRollback4);
+  STEP(runMassiveRollback4);
+  FINALIZER(runClearTable2);
+}
 TESTCASE("MassiveTransaction",
          "Test very large insert transaction"){
   INITIALIZER(runLoadTable2);
diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt
index ba415d657a..3fead45533 100644
--- a/storage/ndb/test/run-test/daily-basic-tests.txt
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt
@@ -201,15 +201,19 @@ args: -n PkDeleteAsynch
 
 max-time: 500
 cmd: testBasic
-args: -n MassiveRollback T1 T6 T13 D1 D2
+args: -n MassiveRollback T1 T7 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n MassiveRollback2 T1 T6 T13 D1 D2
+args: -n MassiveRollback2 T1 T7 D1 D2
 
 max-time: 500
 cmd: testBasic
-args: -n MassiveRollback3 T1 D1
+args: -n MassiveRollback3 T1 T7 D1 D2
+
+max-time: 500
+cmd: testBasic
+args: -n MassiveRollback4 T1 T7 D1 D2
 
 max-time: 500
 cmd: testBasic
-- 
2.30.9