List:Commits« Previous MessageNext Message »
From:pekka Date:July 7 2006 8:57am
Subject:bk commit into 4.1 tree (pekka:1.2530) BUG#20847
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of pekka. When pekka 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.2530 06/07/07 10:57:22 pekka@stripped +6 -0
  ndb - bug#20847 : DbtupTabDesMan: add merge with left buddies

  ndb/test/run-test/daily-basic-tests.txt
    1.33 06/07/07 10:55:58 pekka@stripped +4 -0
    DbtupTabDesMan: add merge with left buddies

  ndb/test/ndbapi/testDict.cpp
    1.19 06/07/07 10:55:58 pekka@stripped +101 -0
    DbtupTabDesMan: add merge with left buddies

  ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
    1.4 06/07/07 10:55:57 pekka@stripped +136 -30
    DbtupTabDesMan: add merge with left buddies

  ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
    1.9 06/07/07 10:55:57 pekka@stripped +7 -0
    DbtupTabDesMan: add merge with left buddies

  ndb/src/kernel/blocks/dbtup/Dbtup.hpp
    1.21 06/07/07 10:55:56 pekka@stripped +6 -3
    DbtupTabDesMan: add merge with left buddies

  ndb/src/kernel/blocks/ERROR_codes.txt
    1.18 06/07/07 10:55:55 pekka@stripped +3 -1
    DbtupTabDesMan: add merge with left buddies

# 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:	pekka
# Host:	orca.ndb.mysql.com
# Root:	/space_old/pekka/ndb/version/my41-bug20847

--- 1.32/ndb/test/run-test/daily-basic-tests.txt	2006-06-01 08:24:03 +02:00
+++ 1.33/ndb/test/run-test/daily-basic-tests.txt	2006-07-07 10:55:58 +02:00
@@ -491,6 +491,10 @@ args: -n CreateAndDrop 
 
 max-time: 1500
 cmd: testDict
+args: -n CreateAndDropAtRandom -l 200 T1
+
+max-time: 1500
+cmd: testDict
 args: -n CreateAndDropWithData 
 
 max-time: 1500

--- 1.17/ndb/src/kernel/blocks/ERROR_codes.txt	2006-06-01 08:24:02 +02:00
+++ 1.18/ndb/src/kernel/blocks/ERROR_codes.txt	2006-07-07 10:55:55 +02:00
@@ -2,7 +2,7 @@ Next QMGR 1
 Next NDBCNTR 1000
 Next NDBFS 2000
 Next DBACC 3002
-Next DBTUP 4013
+Next DBTUP 4014
 Next DBLQH 5043
 Next DBDICT 6006
 Next DBDIH 7174
@@ -429,6 +429,8 @@ Drop Table/Index:
 8034: Fail next index create in TC
 8035: Fail next trigger drop in TC
 8036: Fail next index drop in TC
+
+4013: verify TUP tab descr before and after next DROP TABLE
 
 System Restart:
 ---------------

--- 1.20/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2005-09-21 17:24:38 +02:00
+++ 1.21/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2006-07-07 10:55:56 +02:00
@@ -2129,15 +2129,18 @@ private:
 // Public methods
   Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset);
   Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset);
-  void freeTabDescr(Uint32 retRef, Uint32 retNo);
+  void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
   Uint32 getTabDescrWord(Uint32 index);
   void setTabDescrWord(Uint32 index, Uint32 word);
 
 // Private methods
   Uint32 sizeOfReadFunction();
   void   removeTdArea(Uint32 tabDesRef, Uint32 list);
-  void   insertTdArea(Uint32 sizeOfChunk, Uint32 tabDesRef, Uint32 list);
-  Uint32 itdaMergeTabDescr(Uint32 retRef, Uint32 retNo);
+  void   insertTdArea(Uint32 tabDesRef, Uint32 list);
+  void   itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
+#ifdef VM_TRACE
+  void verifytabdes();
+#endif
 
 //------------------------------------------------------------------------------------------------------
 // Page Memory Manager

--- 1.8/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2005-08-31 16:14:59 +02:00
+++ 1.9/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2006-07-07 10:55:57 +02:00
@@ -567,6 +567,9 @@ void
 Dbtup::execDROP_TAB_REQ(Signal* signal)
 {
   ljamEntry();
+  if (ERROR_INSERTED(4013)) {
+    verifytabdes();
+  }
   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
   
   TablerecPtr tabPtr;
@@ -685,5 +688,9 @@ void Dbtup::execFSREMOVECONF(Signal* sig
   
   releaseTabDescr(tabPtr.p);
   initTab(tabPtr.p);
+  if (ERROR_INSERTED(4013)) {
+    CLEAR_ERROR_INSERT_VALUE;
+    verifytabdes();
+  }
 }//Dbtup::execFSREMOVECONF()
 

--- 1.3/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp	2006-07-04 15:09:39 +02:00
+++ 1.4/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp	2006-07-07 10:55:57 +02:00
@@ -24,13 +24,15 @@
 #define ljam() { jamLine(22000 + __LINE__); }
 #define ljamEntry() { jamEntryLine(22000 + __LINE__); }
 
-/* **************************************************************** */
-/* *********** TABLE DESCRIPTOR MEMORY MANAGER ******************** */
-/* **************************************************************** */
-/* This module is used to allocate and deallocate table descriptor  */
-/* memory attached to fragments (could be allocated per table       */
-/* instead. Performs its task by a buddy algorithm.                 */
-/* **************************************************************** */
+/*
+ * TABLE DESCRIPTOR MEMORY MANAGER
+ *
+ * Each table has a descriptor which is a contiguous array of words.
+ * The descriptor is allocated from a global array using a buddy
+ * algorithm.  Free lists exist for each power of 2 words.  Freeing
+ * a piece first merges with free right and left neighbours and then
+ * divides itself up into free list chunks.
+ */
 
 Uint32
 Dbtup::getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset)
@@ -72,8 +74,9 @@ Uint32 Dbtup::allocTabDescr(const Tabler
       Uint32 retNo = (1 << i) - allocSize;	        /* CALCULATE THE DIFFERENCE               */
       if (retNo >= ZTD_FREE_SIZE) {
         ljam();
-        Uint32 retRef = reference + allocSize;          /* SET THE RETURN POINTER                 */
-        freeTabDescr(retRef, retNo);	                /* RETURN UNUSED TD SPACE TO THE TD AREA  */
+        // return unused words, of course without attempting left merge
+        Uint32 retRef = reference + allocSize;
+        freeTabDescr(retRef, retNo, false);
       } else {
         ljam();
         allocSize = 1 << i;
@@ -99,15 +102,15 @@ Uint32 Dbtup::allocTabDescr(const Tabler
   }//if
 }//Dbtup::allocTabDescr()
 
-void Dbtup::freeTabDescr(Uint32 retRef, Uint32 retNo) 
+void Dbtup::freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal)
 {
-  retNo = itdaMergeTabDescr(retRef, retNo);       /* MERGE WITH POSSIBLE RIGHT NEIGHBOURS   */
+  itdaMergeTabDescr(retRef, retNo, normal);       /* MERGE WITH POSSIBLE NEIGHBOURS   */
   while (retNo >= ZTD_FREE_SIZE) {
     ljam();
     Uint32 list = nextHigherTwoLog(retNo);
     list--;	/* RETURN TO NEXT LOWER LIST    */
     Uint32 sizeOfChunk = 1 << list;
-    insertTdArea(sizeOfChunk, retRef, list);
+    insertTdArea(retRef, list);
     retRef += sizeOfChunk;
     retNo -= sizeOfChunk;
   }//while
@@ -128,7 +131,7 @@ Dbtup::setTabDescrWord(Uint32 index, Uin
   tableDescriptor[index].tabDescr = word;
 }//Dbtup::setTabDescrWord()
 
-void Dbtup::insertTdArea(Uint32 sizeOfChunk, Uint32 tabDesRef, Uint32 list) 
+void Dbtup::insertTdArea(Uint32 tabDesRef, Uint32 list) 
 {
   ndbrequire(list < 16);
   setTabDescrWord(tabDesRef + ZTD_FL_HEADER, ZTD_TYPE_FREE);
@@ -145,19 +148,14 @@ void Dbtup::insertTdArea(Uint32 sizeOfCh
   setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_SIZE, 1 << list);
 }//Dbtup::insertTdArea()
 
-/* ---------------------------------------------------------------- */
-/* ----------------------- MERGE_TAB_DESCR ------------------------ */
-/* ---------------------------------------------------------------- */
-/* INPUT:  TAB_DESCR_PTR   POINTING AT THE CURRENT CHUNK            */
-/*                                                                  */
-/* SHORTNAME:   MTD                                                 */
-/* -----------------------------------------------------------------*/
-Uint32 Dbtup::itdaMergeTabDescr(Uint32 retRef, Uint32 retNo) 
+/*
+ * Merge to-be-removed chunk (which need not be initialized with header
+ * and trailer) with left and right buddies.  The start point retRef
+ * moves to left and the size retNo increases to match the new chunk.
+ */
+void Dbtup::itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal)
 {
-   /* THE SIZE OF THE PART TO MERGE MUST BE OF THE SAME SIZE AS THE INSERTED PART */
-   /* THIS IS TRUE EITHER IF ONE PART HAS THE SAME SIZE OR THE SUM OF BOTH PARTS  */
-   /* TOGETHER HAS THE SAME SIZE AS THE PART TO BE INSERTED                       */
-   /* FIND THE SIZES OF THE PARTS TO THE RIGHT OF THE PART TO BE REINSERTED */
+  // merge right
   while ((retRef + retNo) < cnoOfTabDescrRec) {
     ljam();
     Uint32 tabDesRef = retRef + retNo;
@@ -171,11 +169,28 @@ Uint32 Dbtup::itdaMergeTabDescr(Uint32 r
       removeTdArea(tabDesRef, list);
     } else {
       ljam();
-      return retNo;
-    }//if
-  }//while
-  ndbrequire((retRef + retNo) == cnoOfTabDescrRec);
-  return retNo;
+      break;
+    }
+  }
+  // merge left
+  const bool mergeLeft = normal;
+  while (mergeLeft && retRef > 0) {
+    ljam();
+    Uint32 trailerWord = getTabDescrWord(retRef - ZTD_TR_TYPE);
+    if (trailerWord == ZTD_TYPE_FREE) {
+      ljam();
+      Uint32 sizeOfMergedPart = getTabDescrWord(retRef - ZTD_TR_SIZE);
+      ndbrequire(retRef >= sizeOfMergedPart);
+      retRef -= sizeOfMergedPart;
+      retNo += sizeOfMergedPart;
+      Uint32 list = nextHigherTwoLog(sizeOfMergedPart - 1);
+      removeTdArea(retRef, list);
+    } else {
+      ljam();
+      break;
+    }
+  }
+  ndbrequire((retRef + retNo) <= cnoOfTabDescrRec);
 }//Dbtup::itdaMergeTabDescr()
 
 /* ---------------------------------------------------------------- */
@@ -211,3 +226,94 @@ void Dbtup::removeTdArea(Uint32 tabDesRe
     setTabDescrWord(tabDescrPrevPtr + ZTD_FL_NEXT, tabDescrNextPtr);
   }//if
 }//Dbtup::removeTdArea()
+
+#ifdef VM_TRACE
+void
+Dbtup::verifytabdes()
+{
+  struct WordType {
+    short fl;   // free list 0-15
+    short ti;   // table id
+    WordType() : fl(-1), ti(-1) {}
+  };
+  WordType* wt = new WordType [cnoOfTabDescrRec];
+  uint free_frags = 0;
+  // free lists
+  {
+    for (uint i = 0; i < 16; i++) {
+      Uint32 desc2 = RNIL;
+      Uint32 desc = cfreeTdList[i];
+      while (desc != RNIL) {
+        const Uint32 size = (1 << i);
+        ndbrequire(size >= ZTD_FREE_SIZE);
+        ndbrequire(desc + size <= cnoOfTabDescrRec);
+        { Uint32 index = desc + ZTD_FL_HEADER;
+          ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_FREE);
+        }
+        { Uint32 index = desc + ZTD_FL_SIZE;
+          ndbrequire(tableDescriptor[index].tabDescr == size);
+        }
+        { Uint32 index = desc + size - ZTD_TR_TYPE;
+          ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_FREE);
+        }
+        { Uint32 index = desc + size - ZTD_TR_SIZE;
+          ndbrequire(tableDescriptor[index].tabDescr == size);
+        }
+        { Uint32 index = desc + ZTD_FL_PREV;
+          ndbrequire(tableDescriptor[index].tabDescr == desc2);
+        }
+        for (uint j = 0; j < size; j++) {
+          ndbrequire(wt[desc + j].fl == -1);
+          wt[desc + j].fl = i;
+        }
+        desc2 = desc;
+        desc = tableDescriptor[desc + ZTD_FL_NEXT].tabDescr;
+        free_frags++;
+      }
+    }
+  }
+  // tables
+  {
+    for (uint i = 0; i < cnoOfTablerec; i++) {
+      TablerecPtr ptr;
+      ptr.i = i;
+      ptrAss(ptr, tablerec);
+      if (ptr.p->tableStatus == DEFINED) {
+        Uint32 offset[10];
+        const Uint32 alloc = getTabDescrOffsets(ptr.p, offset);
+        const Uint32 desc = ptr.p->readKeyArray - offset[3];
+        Uint32 size = alloc;
+        if (size % ZTD_FREE_SIZE != 0)
+          size += ZTD_FREE_SIZE - size % ZTD_FREE_SIZE;
+        ndbrequire(desc + size <= cnoOfTabDescrRec);
+        { Uint32 index = desc + ZTD_FL_HEADER;
+          ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_NORMAL);
+        }
+        { Uint32 index = desc + ZTD_FL_SIZE;
+          ndbrequire(tableDescriptor[index].tabDescr == size);
+        }
+        { Uint32 index = desc + size - ZTD_TR_TYPE;
+          ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_NORMAL);
+        }
+        { Uint32 index = desc + size - ZTD_TR_SIZE;
+          ndbrequire(tableDescriptor[index].tabDescr == size);
+        }
+        for (uint j = 0; j < size; j++) {
+          ndbrequire(wt[desc + j].ti == -1);
+          wt[desc + j].ti = i;
+        }
+      }
+    }
+  }
+  // all words
+  {
+    for (uint i = 0; i < cnoOfTabDescrRec; i++) {
+      bool is_fl = wt[i].fl != -1;
+      bool is_ti = wt[i].ti != -1;
+      ndbrequire(is_fl != is_ti);
+    }
+  }
+  delete [] wt;
+  ndbout << "verifytabdes: frags=" << free_frags << endl;
+}
+#endif

--- 1.18/ndb/test/ndbapi/testDict.cpp	2004-12-07 10:27:00 +01:00
+++ 1.19/ndb/test/ndbapi/testDict.cpp	2006-07-07 10:55:58 +02:00
@@ -223,6 +223,101 @@ int runCreateAndDrop(NDBT_Context* ctx, 
   return NDBT_OK;
 }
 
+int runCreateAndDropAtRandom(NDBT_Context* ctx, NDBT_Step* step)
+{
+  myRandom48Init(NdbTick_CurrentMillisecond());
+  Ndb* pNdb = GETNDB(step);
+  NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+  int loops = ctx->getNumLoops();
+  int numTables = NDBT_Tables::getNumTables();
+  bool* tabList = new bool [ numTables ];
+  int tabCount;
+
+  {
+    for (int num = 0; num < numTables; num++) {
+      (void)pDic->dropTable(NDBT_Tables::getTable(num)->getName());
+      tabList[num] = false;
+    }
+    tabCount = 0;
+  }
+
+  NdbRestarter restarter;
+  int result = NDBT_OK;
+  int bias = 1; // 0-less 1-more
+  int i = 0;
+  
+  while (i < loops) {
+    g_info << "loop " << i << " tabs " << tabCount << "/" << numTables << endl;
+    int num = myRandom48(numTables);
+    const NdbDictionary::Table* pTab = NDBT_Tables::getTable(num);
+    char tabName[200];
+    strcpy(tabName, pTab->getName());
+
+    if (tabList[num] == false) {
+      if (bias == 0 && myRandom48(100) < 80)
+        continue;
+      g_info << tabName << ": create" << endl;
+      if (pDic->createTable(*pTab) != 0) {
+        const NdbError err = pDic->getNdbError();
+        g_err << tabName << ": create failed: " << err << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+      const NdbDictionary::Table* pTab2 = pDic->getTable(tabName);
+      if (pTab2 == NULL) {
+        const NdbError err = pDic->getNdbError();
+        g_err << tabName << ": verify create: " << err << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+      tabList[num] = true;
+      assert(tabCount < numTables);
+      tabCount++;
+      if (tabCount == numTables)
+        bias = 0;
+    }
+    else {
+      if (bias == 1 && myRandom48(100) < 80)
+        continue;
+      g_info << tabName << ": drop" << endl;
+      if (restarter.insertErrorInAllNodes(4013) != 0) {
+        g_err << "error insert failed" << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+      if (pDic->dropTable(tabName) != 0) {
+        const NdbError err = pDic->getNdbError();
+        g_err << tabName << ": drop failed: " << err << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+      const NdbDictionary::Table* pTab2 = pDic->getTable(tabName);
+      if (pTab2 != NULL) {
+        g_err << tabName << ": verify drop: table exists" << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+      if (pDic->getNdbError().code != 709 &&
+          pDic->getNdbError().code != 723) {
+        const NdbError err = pDic->getNdbError();
+        g_err << tabName << ": verify drop: " << err << endl;
+        result = NDBT_FAILED;
+        break;
+      }
+      tabList[num] = false;
+      assert(tabCount > 0);
+      tabCount--;
+      if (tabCount == 0)
+        bias = 1;
+    }
+    i++;
+  }
+
+  delete [] tabList;
+  return result;
+}
+
+
 int runCreateAndDropWithData(NDBT_Context* ctx, NDBT_Step* step){
   Ndb* pNdb = GETNDB(step);
   int loops = ctx->getNumLoops();
@@ -1561,6 +1656,12 @@ NDBT_TESTSUITE(testDict);
 TESTCASE("CreateAndDrop", 
 	 "Try to create and drop the table loop number of times\n"){
   INITIALIZER(runCreateAndDrop);
+}
+TESTCASE("CreateAndDropAtRandom",
+	 "Try to create and drop table at random loop number of times\n"
+         "Uses all available tables\n"
+         "Uses error insert 4013 to make TUP verify table descriptor"){
+  INITIALIZER(runCreateAndDropAtRandom);
 }
 TESTCASE("CreateAndDropWithData", 
 	 "Try to create and drop the table when it's filled with data\n"
Thread
bk commit into 4.1 tree (pekka:1.2530) BUG#20847pekka7 Jul