List:Commits« Previous MessageNext Message »
From:tomas Date:January 30 2007 3:12am
Subject:bk commit into 5.1 tree (tomas:1.2410)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas 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.2410 07/01/30 10:11:55 tomas@stripped +4 -0
  (recommit from 5.1-wl2325-5.0-drop6)
  ndb - add new dump commands for tracking hanging locks

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
    1.134 07/01/30 10:10:59 tomas@stripped +236 -0
    Add new dump commands

  storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
    1.47 07/01/30 10:10:58 tomas@stripped +3 -0
    Add new dump commands

  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
    1.135 07/01/30 10:10:56 tomas@stripped +343 -1
    Add new dump commands

  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
    1.58 07/01/30 10:10:54 tomas@stripped +3 -0
    Add new dump commands

# 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:	tomas
# Host:	poseidon.mysql.com
# Root:	/home/tomas/mysql-5.1-telco

--- 1.57/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2006-12-24 02:20:16 +07:00
+++ 1.58/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2007-01-30 10:10:54 +07:00
@@ -2542,6 +2542,9 @@
   void initData();
   void initRecords();
 
+  bool validate_filter(Signal*);
+  bool match_and_print(Signal*, Ptr<TcConnectionrec>);
+
   void define_backup(Signal*);
   void execDEFINE_BACKUP_REF(Signal*);
   void execDEFINE_BACKUP_CONF(Signal*);

--- 1.134/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2007-01-29 03:57:31 +07:00
+++ 1.135/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2007-01-30 10:10:56 +07:00
@@ -5701,6 +5701,8 @@
     ptrCheckGuard(nextHashptr, ctcConnectrecFileSize, tcConnectionrec);
     nextHashptr.p->prevHashRec = prevHashptr.i;
   }//if
+
+  regTcPtr->prevHashRec = regTcPtr->nextHashRec = RNIL;
 }//Dblqh::deleteTransidHash()
 
 /* -------------------------------------------------------------------------
@@ -8397,6 +8399,7 @@
              ZNIL);
   tcConnectptr.p->save1 = 4;
   tcConnectptr.p->primKeyLen = keyLen + 4; // hard coded in execKEYINFO
+  tcConnectptr.p->applRef = scanFragReq->resultRef;
   errorCode = initScanrec(scanFragReq);
   if (errorCode != ZOK) {
     jam();
@@ -10073,6 +10076,7 @@
   tcConnectptr.p->tcOprec = tcConnectptr.i;
   tcConnectptr.p->schemaVersion = scanptr.p->scanSchemaVersion;
   tcConnectptr.p->savePointId = gci;
+  tcConnectptr.p->applRef = 0;
   scanptr.p->scanState = ScanRecord::WAIT_ACC_COPY;
   AccScanReq * req = (AccScanReq*)&signal->theData[0];
   req->senderData = scanptr.i;
@@ -18373,6 +18377,208 @@
   }//if
 }//Dblqh::writeNextLog()
 
+bool
+Dblqh::validate_filter(Signal* signal)
+{
+  Uint32 * start = signal->theData + 1;
+  Uint32 * end = signal->theData + signal->getLength();
+  if (start == end)
+  {
+    infoEvent("No filter specified, not listing...");
+    return false;
+  }
+
+  while(start < end)
+  {
+    switch(* start){
+    case 0: // Table
+    case 1: // API Node
+    case 3: // TC Node
+      start += 2;
+      break;
+    case 2: // Transid
+      start += 3;
+      break;
+    default:
+      infoEvent("Invalid filter op: 0x%x pos: %d",
+		* start,
+		start - (signal->theData + 1));
+      return false;
+    }
+  }
+
+  if (start != end)
+  {
+    infoEvent("Invalid filter, unexpected end");
+    return false;
+  }
+
+  return true;
+}
+
+bool
+Dblqh::match_and_print(Signal* signal, Ptr<TcConnectionrec> tcRec)
+{
+  Uint32 len = signal->getLength();
+  Uint32* start = signal->theData + 3;
+  Uint32* end = signal->theData + len;
+  while (start < end)
+  {
+    switch(* start){
+    case 0:
+      if (tcRec.p->tableref != * (start + 1))
+	return false;
+      start += 2;
+      break;
+    case 1:
+      if (refToNode(tcRec.p->applRef) != * (start + 1))
+	return false;
+      start += 2;
+      break;
+    case 2:
+      if (tcRec.p->transid[0] != * (start + 1) ||
+	  tcRec.p->transid[1] != * (start + 2))
+	return false;
+      start += 3;
+      break;
+    case 3:
+      if (refToNode(tcRec.p->tcBlockref) != * (start + 1))
+	return false;
+      start += 2;
+      break;
+    default:
+      ndbassert(false);
+      return false;
+    }
+  }
+  
+  if (start != end)
+  {
+    ndbassert(false);
+    return false;
+  }
+
+  /**
+   * Do print
+   */
+  Uint32 *temp = signal->theData + 25;
+  memcpy(temp, signal->theData, 4 * len);
+
+  char state[20];
+  const char* op = "<Unknown>";
+  if (tcRec.p->tcScanRec != RNIL)
+  {
+    ScanRecordPtr sp;
+    sp.i = tcRec.p->tcScanRec;
+    c_scanRecordPool.getPtr(sp);
+
+    op = "SCAN";
+    
+    switch(sp.p->scanState){
+    case ScanRecord::WAIT_NEXT_SCAN:
+      BaseString::snprintf(state, sizeof(state), "WaitNextScan");
+      break;
+    case ScanRecord::IN_QUEUE:
+      BaseString::snprintf(state, sizeof(state), "InQueue");
+      break;
+    case ScanRecord::SCAN_FREE:
+    case ScanRecord::WAIT_STORED_PROC_COPY:
+    case ScanRecord::WAIT_STORED_PROC_SCAN:
+    case ScanRecord::WAIT_NEXT_SCAN_COPY:
+    case ScanRecord::WAIT_DELETE_STORED_PROC_ID_SCAN:
+    case ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY:
+    case ScanRecord::WAIT_ACC_COPY:
+    case ScanRecord::WAIT_ACC_SCAN:
+    case ScanRecord::WAIT_SCAN_NEXTREQ:
+    case ScanRecord::WAIT_CLOSE_SCAN:
+    case ScanRecord::WAIT_CLOSE_COPY:
+    case ScanRecord::WAIT_RELEASE_LOCK:
+    case ScanRecord::WAIT_TUPKEY_COPY:
+    case ScanRecord::WAIT_LQHKEY_COPY:
+      BaseString::snprintf(state, sizeof(state), "%u", sp.p->scanState);
+    }
+  }
+  else
+  {
+    switch(tcRec.p->operation){
+    case ZREAD: op = "READ"; break;
+    case ZINSERT: op = "INSERT"; break;
+    case ZUPDATE: op = "UPDATE"; break;
+    case ZDELETE: op = "DELETE"; break;
+    case ZWRITE: op = "WRITE"; break;
+    }
+
+    switch(tcRec.p->transactionState){
+    case TcConnectionrec::IDLE:
+    case TcConnectionrec::WAIT_ACC:
+      BaseString::snprintf(state, sizeof(state), "In lock queue");
+      break;
+    case TcConnectionrec::WAIT_TUPKEYINFO:
+    case TcConnectionrec::WAIT_ATTR:
+      BaseString::snprintf(state, sizeof(state), "WaitData");
+      break;
+    case TcConnectionrec::WAIT_TUP:
+      BaseString::snprintf(state, sizeof(state), "Running");
+      break;
+    case TcConnectionrec::PREPARED:
+      BaseString::snprintf(state, sizeof(state), "Prepared");
+      break;
+    case TcConnectionrec::COMMITTED:
+      BaseString::snprintf(state, sizeof(state), "Committed");
+      break;
+    case TcConnectionrec::STOPPED:
+    case TcConnectionrec::LOG_QUEUED:
+    case TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL:
+    case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
+    case TcConnectionrec::COMMIT_STOPPED:
+    case TcConnectionrec::LOG_COMMIT_QUEUED:
+    case TcConnectionrec::COMMIT_QUEUED:
+    case TcConnectionrec::WAIT_ACC_ABORT:
+    case TcConnectionrec::ABORT_QUEUED:
+    case TcConnectionrec::ABORT_STOPPED:
+    case TcConnectionrec::WAIT_AI_AFTER_ABORT:
+    case TcConnectionrec::LOG_ABORT_QUEUED:
+    case TcConnectionrec::WAIT_TUP_TO_ABORT:
+    case TcConnectionrec::WAIT_SCAN_AI:
+    case TcConnectionrec::SCAN_STATE_USED:
+    case TcConnectionrec::SCAN_FIRST_STOPPED:
+    case TcConnectionrec::SCAN_CHECK_STOPPED:
+    case TcConnectionrec::SCAN_STOPPED:
+    case TcConnectionrec::SCAN_RELEASE_STOPPED:
+    case TcConnectionrec::SCAN_CLOSE_STOPPED:
+    case TcConnectionrec::COPY_CLOSE_STOPPED:
+    case TcConnectionrec::COPY_FIRST_STOPPED:
+    case TcConnectionrec::COPY_STOPPED:
+    case TcConnectionrec::SCAN_TUPKEY:
+    case TcConnectionrec::COPY_TUPKEY:
+    case TcConnectionrec::TC_NOT_CONNECTED:
+    case TcConnectionrec::PREPARED_RECEIVED_COMMIT:
+    case TcConnectionrec::LOG_COMMIT_WRITTEN:
+      BaseString::snprintf(state, sizeof(state), "%u", 
+			   tcRec.p->transactionState);
+    }
+  }
+  
+  char buf[100];
+  BaseString::snprintf(buf, sizeof(buf),
+		       "OP[%u]: Tab: %d frag: %d TC: %u API: %d(0x%x)"
+		       "transid: 0x%x 0x%x op: %s state: %s",
+		       tcRec.i,
+		       tcRec.p->tableref, 
+		       tcRec.p->fragmentid,
+		       refToNode(tcRec.p->tcBlockref),
+		       refToNode(tcRec.p->applRef),
+		       refToBlock(tcRec.p->applRef),
+		       tcRec.p->transid[0], tcRec.p->transid[1],
+		       op,
+		       state);
+  
+  infoEvent(buf);
+  
+  memcpy(signal->theData, temp, 4*len);
+  return true;
+}
+
 void
 Dblqh::execDUMP_STATE_ORD(Signal* signal)
 {
@@ -18472,7 +18678,7 @@
 
     ScanRecordPtr sp;
     sp.i = recordNo;
-    c_scanRecordPool.getPtr(scanptr);
+    c_scanRecordPool.getPtr(sp);
     if (sp.p->scanState != ScanRecord::SCAN_FREE){
       dumpState->args[0] = DumpStateOrd::LqhDumpOneScanRec;
       dumpState->args[1] = recordNo;
@@ -18831,6 +19037,142 @@
   }
 #endif
   
+  if (arg == 2350)
+  {
+    jam();
+    Uint32 len = signal->getLength() - 1;
+    if (len + 3 > 25)
+    {
+      jam();
+      infoEvent("Too long filter");
+      return;
+    }
+    if (validate_filter(signal))
+    {
+      jam();
+      memmove(signal->theData + 3, signal->theData + 1, 4 * len);
+      signal->theData[0] = 2351;
+      signal->theData[1] = 0;    // Bucket
+      signal->theData[2] = RNIL; // Record
+      sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, len + 3, JBB);
+      
+      infoEvent("Starting dump of operations");
+    }
+    return;
+  }
+
+  if (arg == 2351)
+  {
+    jam();
+    Uint32 bucket = signal->theData[1];
+    Uint32 record = signal->theData[2];
+    Uint32 len = signal->getLength();
+    TcConnectionrecPtr tcRec;
+    if (record != RNIL)
+    {
+      jam();
+      /**
+       * Check that record is still in use...
+       */
+      tcRec.i = record;
+      ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+
+      Uint32 hashIndex = (tcRec.p->transid[0] ^ tcRec.p->tcOprec) & 1023;
+      if (hashIndex != bucket)
+      {
+	jam();
+	record = RNIL;
+      }
+      else
+      {
+	jam();
+	if (tcRec.p->nextHashRec == RNIL && 
+	    tcRec.p->prevHashRec == RNIL &&
+	    ctransidHash[hashIndex] != record)
+	{
+	  jam();
+	  record = RNIL;
+	}
+      }
+      
+      if (record == RNIL)
+      {
+	jam();
+	signal->theData[2] = RNIL;
+	sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 
+		   signal->getLength(), JBB);	
+	return;
+      }
+    }
+    else if ((record = ctransidHash[bucket]) == RNIL)
+    {
+      jam();
+      bucket++;
+      if (bucket < 1024)
+      {
+	jam();
+	signal->theData[1] = bucket;
+	signal->theData[2] = RNIL;
+	sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 
+		   signal->getLength(), JBB);	
+      }
+      else
+      {
+	jam();
+	infoEvent("End of operation dump");
+      }
+
+      return;
+    } 
+    else
+    {
+      jam();
+      tcRec.i = record;
+      ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);      
+    }
+
+    for (Uint32 i = 0; i<32; i++)
+    {
+      jam();
+      bool print = match_and_print(signal, tcRec);
+      
+      tcRec.i = tcRec.p->nextHashRec;
+      if (tcRec.i == RNIL || print)
+      {
+	jam();
+	break;
+      }
+      
+      ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+    }
+    
+    if (tcRec.i == RNIL)
+    {
+      jam();
+      bucket++;
+      if (bucket < 1024)
+      {
+	jam();
+	signal->theData[1] = bucket;
+	signal->theData[2] = RNIL;
+	sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, len, JBB);
+      }
+      else
+      {
+	jam();
+	infoEvent("End of operation dump");
+      }
+      
+      return;
+    }
+    else
+    {
+      jam();
+      signal->theData[2] = tcRec.i;
+      sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD, signal, 200, len);
+      return;
+    }
+  }
 }//Dblqh::execDUMP_STATE_ORD()
 
 void Dblqh::execSET_VAR_REQ(Signal* signal) 

--- 1.46/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-01-23 07:18:03 +07:00
+++ 1.47/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-01-30 10:10:58 +07:00
@@ -1853,6 +1853,9 @@
   };
   AbortAllRecord c_abortRec;
 
+  bool validate_filter(Signal*);
+  bool match_and_print(Signal*, ApiConnectRecordPtr);
+
   /************************** API CONNECT RECORD ***********************/
   /* *******************************************************************/
   /* THE API CONNECT RECORD CONTAINS THE CONNECTION RECORD TO WHICH THE*/

--- 1.133/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-01-23 04:13:43 +07:00
+++ 1.134/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-01-30 10:10:59 +07:00
@@ -10675,7 +10675,9 @@
 void
 Dbtc::execDUMP_STATE_ORD(Signal* signal)
 {
+  jamEntry();
   DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
+  Uint32 arg = signal->theData[0];
   if(signal->theData[0] == DumpStateOrd::CommitAckMarkersSize){
     infoEvent("TC: m_commitAckMarkerPool: %d free size: %d",
               m_commitAckMarkerPool.getNoOfFree(),
@@ -11002,7 +11004,241 @@
     sendSignalWithDelay(cownref, GSN_SYSTEM_ERROR, signal, 300, 1);    
     return;
   }
+
+  if (arg == 2550)
+  {
+    jam();
+    Uint32 len = signal->getLength() - 1;
+    if (len + 2 > 25)
+    {
+      jam();
+      infoEvent("Too long filter");
+      return;
+    }
+    if (validate_filter(signal))
+    {
+      jam();
+      memmove(signal->theData + 2, signal->theData + 1, 4 * len);
+      signal->theData[0] = 2551;
+      signal->theData[1] = 0;    // record
+      sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, len + 2, JBB);
+      
+      infoEvent("Starting dump of transactions");
+    }
+    return;
+  }
+
+  if (arg == 2551)
+  {
+    jam();
+    Uint32 record = signal->theData[1];
+    Uint32 len = signal->getLength();
+    ndbassert(len > 1);
+
+    ApiConnectRecordPtr ap;
+    ap.i = record;
+    ptrAss(ap, apiConnectRecord);
+
+    bool print = false;
+    for (Uint32 i = 0; i<32; i++)
+    {
+      jam();
+      print = match_and_print(signal, ap);
+
+      ap.i++;
+      if (ap.i == capiConnectFilesize || print)
+      {
+	jam();
+	break;
+      }
+      
+      ptrAss(ap, apiConnectRecord);
+    }
+
+    if (ap.i == capiConnectFilesize)
+    {
+      jam();
+      infoEvent("End of transaction dump");
+      return;
+    }
+    
+    signal->theData[1] = ap.i;
+    if (print)
+    {
+      jam();
+      sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD, signal, 200, len);
+    }
+    else
+    {
+      jam();
+      sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, len, JBB);
+    }
+    return;
+  }
 }//Dbtc::execDUMP_STATE_ORD()
+
+bool
+Dbtc::validate_filter(Signal* signal)
+{
+  Uint32 * start = signal->theData + 1;
+  Uint32 * end = signal->theData + signal->getLength();
+  if (start == end)
+  {
+    infoEvent("No filter specified, not listing...");
+    return false;
+  }
+
+  while(start < end)
+  {
+    switch(* start){
+    case 1: // API Node
+    case 4: // Inactive time
+      start += 2;
+      break;
+    case 2: // Transid
+      start += 3;
+      break;
+    default:
+      infoEvent("Invalid filter op: 0x%x pos: %d",
+		* start,
+		start - (signal->theData + 1));
+      return false;
+    }
+  }
+
+  if (start != end)
+  {
+    infoEvent("Invalid filter, unexpected end");
+    return false;
+  }
+
+  return true;
+}
+
+bool
+Dbtc::match_and_print(Signal* signal, ApiConnectRecordPtr apiPtr)
+{
+  Uint32 conState = apiPtr.p->apiConnectstate;
+  if (conState == CS_CONNECTED ||
+      conState == CS_DISCONNECTED ||
+      conState == CS_RESTART)
+    return false;
+
+  Uint32 len = signal->getLength();
+  Uint32* start = signal->theData + 2;
+  Uint32* end = signal->theData + len;
+  Uint32 apiTimer = getApiConTimer(apiPtr.i);
+  while (start < end)
+  {
+    jam();
+    switch(* start){
+    case 1:
+      jam();
+      if (refToNode(apiPtr.p->ndbapiBlockref) != * (start + 1))
+	return false;
+      start += 2;
+      break;
+    case 2:
+      jam();
+      if (apiPtr.p->transid[0] != * (start + 1) ||
+	  apiPtr.p->transid[1] != * (start + 2))
+	return false;
+      start += 3;
+      break;
+    case 4:{
+      jam();
+      if (apiTimer == 0 || ((ctcTimer - apiTimer) / 100) < * (start + 1))
+	return false;
+      start += 2;
+      break;
+    }
+    default:
+      ndbassert(false);
+      return false;
+    }
+  }
+  
+  if (start != end)
+  {
+    ndbassert(false);
+    return false;
+  }
+
+  /**
+   * Do print
+   */
+  Uint32 *temp = signal->theData + 25;
+  memcpy(temp, signal->theData, 4 * len);
+
+  char state[10];
+  const char *stateptr = "";
+  
+  switch(apiPtr.p->apiConnectstate){
+  case CS_STARTED:
+    stateptr = "Prepared";
+    break;
+  case CS_RECEIVING:
+  case CS_REC_COMMITTING:
+  case CS_START_COMMITTING:
+    stateptr = "Running";
+    break;
+  case CS_COMMITTING:
+    stateptr = "Committing";
+    break;
+  case CS_COMPLETING:
+    stateptr = "Completing";
+    break;
+  case CS_PREPARE_TO_COMMIT:
+    stateptr = "Prepare to commit";
+    break;
+  case CS_COMMIT_SENT:
+    stateptr = "Commit sent";
+    break;
+  case CS_COMPLETE_SENT:
+    stateptr = "Complete sent";
+    break;
+  case CS_ABORTING:
+    stateptr = "Aborting";
+    break;
+  case CS_START_SCAN:
+    stateptr = "Scanning";
+    break;
+  case CS_WAIT_ABORT_CONF:
+  case CS_WAIT_COMMIT_CONF:
+  case CS_WAIT_COMPLETE_CONF:
+  case CS_FAIL_PREPARED:
+  case CS_FAIL_COMMITTING:
+  case CS_FAIL_COMMITTED:
+  case CS_REC_PREPARING:
+  case CS_START_PREPARING:
+  case CS_PREPARED:
+  case CS_RESTART:
+  case CS_FAIL_ABORTED:
+  case CS_DISCONNECTED:
+  default:
+    BaseString::snprintf(state, sizeof(state), 
+			 "%u", apiPtr.p->apiConnectstate);
+    stateptr = state;
+    break;
+  }
+
+  char buf[100];
+  BaseString::snprintf(buf, sizeof(buf),
+		       "TRX[%u]: API: %d(0x%x)"
+		       "transid: 0x%x 0x%x inactive: %u(%d) state: %s",
+		       apiPtr.i,
+		       refToNode(apiPtr.p->ndbapiBlockref),
+		       refToBlock(apiPtr.p->ndbapiBlockref),
+		       apiPtr.p->transid[0],
+		       apiPtr.p->transid[1],
+		       apiTimer ? (ctcTimer - apiTimer) / 100 : 0,
+		       c_apiConTimer_line[apiPtr.i],
+		       stateptr);
+  infoEvent(buf);
+  
+  memcpy(signal->theData, temp, 4*len);
+  return true;
+}
 
 void Dbtc::execSET_VAR_REQ(Signal* signal)
 {
Thread
bk commit into 5.1 tree (tomas:1.2410)tomas30 Jan