DbtuxDebug.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:14k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBTUX_DEBUG_CPP
  14. #include "Dbtux.hpp"
  15. /*
  16.  * 12001 log file 0-close 1-open 2-append 3-append to signal log
  17.  * 12002 log flags 1-meta 2-maint 4-tree 8-scan
  18.  */
  19. void
  20. Dbtux::execDUMP_STATE_ORD(Signal* signal)
  21. {
  22.   jamEntry();
  23. #ifdef VM_TRACE
  24.   if (signal->theData[0] == DumpStateOrd::TuxLogToFile) {
  25.     unsigned flag = signal->theData[1];
  26.     const char* const tuxlog = "tux.log";
  27.     FILE* slFile = globalSignalLoggers.getOutputStream();
  28.     if (flag <= 3) {
  29.       if (debugFile != 0) {
  30.         if (debugFile != slFile)
  31.           fclose(debugFile);
  32.         debugFile = 0;
  33.         debugOut = *new NdbOut(*new NullOutputStream());
  34.       }
  35.       if (flag == 1)
  36.         debugFile = fopen(tuxlog, "w");
  37.       if (flag == 2)
  38.         debugFile = fopen(tuxlog, "a");
  39.       if (flag == 3)
  40.         debugFile = slFile;
  41.       if (debugFile != 0)
  42.         debugOut = *new NdbOut(*new FileOutputStream(debugFile));
  43.     }
  44.     return;
  45.   }
  46.   if (signal->theData[0] == DumpStateOrd::TuxSetLogFlags) {
  47.     debugFlags = signal->theData[1];
  48.     return;
  49.   }
  50.   if (signal->theData[0] == DumpStateOrd::TuxMetaDataJunk) {
  51.     // read table definition
  52.     Uint32 tableId = signal->theData[1];
  53.     Uint32 tableVersion = signal->theData[2];
  54.     int ret;
  55.     MetaData md(this);
  56.     MetaData::Table table;
  57.     MetaData::Attribute attribute;
  58.     infoEvent("md: read table %u %u", tableId, tableVersion);
  59.     if ((ret = md.lock(false)) < 0) {
  60.       infoEvent("md.lock error %d", ret);
  61.       return;
  62.     }
  63.     if ((ret = md.getTable(table, tableId, tableVersion)) < 0) {
  64.       infoEvent("md.getTable error %d", ret);
  65.       // lock is released by destructor
  66.       return;
  67.     }
  68.     infoEvent("md: %s type=%d attrs=%u", table.tableName, table.tableType, table.noOfAttributes);
  69.     for (Uint32 i = 0; i < table.noOfAttributes; i++) {
  70.       if ((ret = md.getAttribute(attribute, table, i)) < 0) {
  71.         infoEvent("mg.getAttribute %u error %d", i, ret);
  72.         // lock is released by destructor
  73.         return;
  74.       }
  75.       infoEvent("md: %d %s", attribute.attributeId, attribute.attributeName);
  76.     }
  77.     if ((ret = md.unlock(false)) < 0) {
  78.       infoEvent("md.unlock error %d", ret);
  79.       return;
  80.     }
  81.     return;
  82.   }
  83. #endif
  84. }
  85. #ifdef VM_TRACE
  86. void
  87. Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
  88. {
  89.   TreeHead& tree = frag.m_tree;
  90.   PrintPar par;
  91.   strcpy(par.m_path, ".");
  92.   par.m_side = 2;
  93.   par.m_parent = NullTupLoc;
  94.   printNode(frag, out, tree.m_root, par);
  95.   out.m_out->flush();
  96.   if (! par.m_ok) {
  97.     if (debugFile == 0) {
  98.       signal->theData[0] = 12001;
  99.       signal->theData[1] = 1;
  100.       execDUMP_STATE_ORD(signal);
  101.       if (debugFile != 0) {
  102.         printTree(signal, frag, debugOut);
  103.       }
  104.     }
  105.     ndbrequire(false);
  106.   }
  107. }
  108. void
  109. Dbtux::printNode(Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par)
  110. {
  111.   if (loc == NullTupLoc) {
  112.     par.m_depth = 0;
  113.     return;
  114.   }
  115.   TreeHead& tree = frag.m_tree;
  116.   NodeHandle node(frag);
  117.   selectNode(node, loc);
  118.   out << par.m_path << " " << node << endl;
  119.   // check children
  120.   PrintPar cpar[2];
  121.   ndbrequire(strlen(par.m_path) + 1 < sizeof(par.m_path));
  122.   for (unsigned i = 0; i <= 1; i++) {
  123.     sprintf(cpar[i].m_path, "%s%c", par.m_path, "LR"[i]);
  124.     cpar[i].m_side = i;
  125.     cpar[i].m_depth = 0;
  126.     cpar[i].m_parent = loc;
  127.     printNode(frag, out, node.getLink(i), cpar[i]);
  128.     if (! cpar[i].m_ok) {
  129.       par.m_ok = false;
  130.     }
  131.   }
  132.   static const char* const sep = " *** ";
  133.   // check child-parent links
  134.   if (node.getLink(2) != par.m_parent) {
  135.     par.m_ok = false;
  136.     out << par.m_path << sep;
  137.     out << "parent loc " << hex << node.getLink(2);
  138.     out << " should be " << hex << par.m_parent << endl;
  139.   }
  140.   if (node.getSide() != par.m_side) {
  141.     par.m_ok = false;
  142.     out << par.m_path << sep;
  143.     out << "side " << dec << node.getSide();
  144.     out << " should be " << dec << par.m_side << endl;
  145.   }
  146.   // check balance
  147.   const int balance = -cpar[0].m_depth + cpar[1].m_depth;
  148.   if (node.getBalance() != balance) {
  149.     par.m_ok = false;
  150.     out << par.m_path << sep;
  151.     out << "balance " << node.getBalance();
  152.     out << " should be " << balance << endl;
  153.   }
  154.   if (abs(node.getBalance()) > 1) {
  155.     par.m_ok = false;
  156.     out << par.m_path << sep;
  157.     out << "balance " << node.getBalance() << " is invalid" << endl;
  158.   }
  159.   // check occupancy
  160.   if (node.getOccup() == 0 || node.getOccup() > tree.m_maxOccup) {
  161.     par.m_ok = false;
  162.     out << par.m_path << sep;
  163.     out << "occupancy " << node.getOccup();
  164.     out << " zero or greater than max " << tree.m_maxOccup << endl;
  165.   }
  166.   // check for occupancy of interior node
  167.   if (node.getChilds() == 2 && node.getOccup() < tree.m_minOccup) {
  168.     par.m_ok = false;
  169.     out << par.m_path << sep;
  170.     out << "occupancy " << node.getOccup() << " of interior node";
  171.     out << " less than min " << tree.m_minOccup << endl;
  172.   }
  173. #ifdef dbtux_totally_groks_t_trees
  174.   // check missed semi-leaf/leaf merge
  175.   for (unsigned i = 0; i <= 1; i++) {
  176.     if (node.getLink(i) != NullTupLoc &&
  177.         node.getLink(1 - i) == NullTupLoc &&
  178.         // our semi-leaf seems to satify interior minOccup condition
  179.         node.getOccup() < tree.m_minOccup) {
  180.       par.m_ok = false;
  181.       out << par.m_path << sep;
  182.       out << "missed merge with child " << i << endl;
  183.     }
  184.   }
  185. #endif
  186.   // check inline prefix
  187.   { ConstData data1 = node.getPref();
  188.     Uint32 data2[MaxPrefSize];
  189.     memset(data2, DataFillByte, MaxPrefSize << 2);
  190.     readKeyAttrs(frag, node.getMinMax(0), 0, c_searchKey);
  191.     copyAttrs(frag, c_searchKey, data2, tree.m_prefSize);
  192.     for (unsigned n = 0; n < tree.m_prefSize; n++) {
  193.       if (data1[n] != data2[n]) {
  194.         par.m_ok = false;
  195.         out << par.m_path << sep;
  196.         out << "inline prefix mismatch word " << n;
  197.         out << " value " << hex << data1[n];
  198.         out << " should be " << hex << data2[n] << endl;
  199.         break;
  200.       }
  201.     }
  202.   }
  203.   // check ordering within node
  204.   for (unsigned j = 1; j < node.getOccup(); j++) {
  205.     const TreeEnt ent1 = node.getEnt(j - 1);
  206.     const TreeEnt ent2 = node.getEnt(j);
  207.     unsigned start = 0;
  208.     readKeyAttrs(frag, ent1, start, c_searchKey);
  209.     readKeyAttrs(frag, ent2, start, c_entryKey);
  210.     int ret = cmpSearchKey(frag, start, c_searchKey, c_entryKey);
  211.     if (ret == 0)
  212.       ret = ent1.cmp(ent2);
  213.     if (ret != -1) {
  214.       par.m_ok = false;
  215.       out << par.m_path << sep;
  216.       out << " disorder within node at pos " << j << endl;
  217.     }
  218.   }
  219.   // check ordering wrt subtrees
  220.   for (unsigned i = 0; i <= 1; i++) {
  221.     if (node.getLink(i) == NullTupLoc)
  222.       continue;
  223.     const TreeEnt ent1 = cpar[i].m_minmax[1 - i];
  224.     const TreeEnt ent2 = node.getMinMax(i);
  225.     unsigned start = 0;
  226.     readKeyAttrs(frag, ent1, start, c_searchKey);
  227.     readKeyAttrs(frag, ent2, start, c_entryKey);
  228.     int ret = cmpSearchKey(frag, start, c_searchKey, c_entryKey);
  229.     if (ret == 0)
  230.       ret = ent1.cmp(ent2);
  231.     if (ret != (i == 0 ? -1 : +1)) {
  232.       par.m_ok = false;
  233.       out << par.m_path << sep;
  234.       out << " disorder wrt subtree " << i << endl;
  235.     }
  236.   }
  237.   // return values
  238.   par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
  239.   par.m_occup = node.getOccup();
  240.   for (unsigned i = 0; i <= 1; i++) {
  241.     if (node.getLink(i) == NullTupLoc)
  242.       par.m_minmax[i] = node.getMinMax(i);
  243.     else
  244.       par.m_minmax[i] = cpar[i].m_minmax[i];
  245.   }
  246. }
  247. NdbOut&
  248. operator<<(NdbOut& out, const Dbtux::TupLoc& loc)
  249. {
  250.   if (loc == Dbtux::NullTupLoc) {
  251.     out << "null";
  252.   } else {
  253.     out << dec << loc.getPageId();
  254.     out << "." << dec << loc.getPageOffset();
  255.   }
  256.   return out;
  257. }
  258. NdbOut&
  259. operator<<(NdbOut& out, const Dbtux::TreeEnt& ent)
  260. {
  261.   out << dec << ent.m_fragBit;
  262.   out << "-" << ent.m_tupLoc;
  263.   out << "-" << dec << ent.m_tupVersion;
  264.   return out;
  265. }
  266. NdbOut&
  267. operator<<(NdbOut& out, const Dbtux::TreeNode& node)
  268. {
  269.   out << "[TreeNode " << hex << &node;
  270.   out << " [left " << node.m_link[0] << "]";
  271.   out << " [right " << node.m_link[1] << "]";
  272.   out << " [up " << node.m_link[2] << "]";
  273.   out << " [side " << dec << node.m_side << "]";
  274.   out << " [occup " << dec << node.m_occup << "]";
  275.   out << " [balance " << dec << (int)node.m_balance - 1 << "]";
  276.   out << " [nodeScan " << hex << node.m_nodeScan << "]";
  277.   out << "]";
  278.   return out;
  279. }
  280. NdbOut&
  281. operator<<(NdbOut& out, const Dbtux::TreeHead& tree)
  282. {
  283.   out << "[TreeHead " << hex << &tree;
  284.   out << " [nodeSize " << dec << tree.m_nodeSize << "]";
  285.   out << " [prefSize " << dec << tree.m_prefSize << "]";
  286.   out << " [minOccup " << dec << tree.m_minOccup << "]";
  287.   out << " [maxOccup " << dec << tree.m_maxOccup << "]";
  288.   out << " [AccHead " << dec << tree.getSize(Dbtux::AccHead) << "]";
  289.   out << " [AccPref " << dec << tree.getSize(Dbtux::AccPref) << "]";
  290.   out << " [AccFull " << dec << tree.getSize(Dbtux::AccFull) << "]";
  291.   out << " [root " << hex << tree.m_root << "]";
  292.   out << "]";
  293.   return out;
  294. }
  295. NdbOut&
  296. operator<<(NdbOut& out, const Dbtux::TreePos& pos)
  297. {
  298.   out << "[TreePos " << hex << &pos;
  299.   out << " [loc " << pos.m_loc << "]";
  300.   out << " [pos " << dec << pos.m_pos << "]";
  301.   out << " [match " << dec << pos.m_match << "]";
  302.   out << " [dir " << dec << pos.m_dir << "]";
  303.   out << "]";
  304.   return out;
  305. }
  306. NdbOut&
  307. operator<<(NdbOut& out, const Dbtux::DescAttr& descAttr)
  308. {
  309.   out << "[DescAttr " << hex << &descAttr;
  310.   out << " [attrDesc " << hex << descAttr.m_attrDesc;
  311.   out << " [primaryAttrId " << dec << descAttr.m_primaryAttrId << "]";
  312.   out << " [typeId " << dec << descAttr.m_typeId << "]";
  313.   out << "]";
  314.   return out;
  315. }
  316. NdbOut&
  317. operator<<(NdbOut& out, const Dbtux::ScanOp& scan)
  318. {
  319.   out << "[ScanOp " << hex << &scan;
  320.   out << " [state " << dec << scan.m_state << "]";
  321.   out << " [lockwait " << dec << scan.m_lockwait << "]";
  322.   out << " [indexId " << dec << scan.m_indexId << "]";
  323.   out << " [fragId " << dec << scan.m_fragId << "]";
  324.   out << " [transId " << hex << scan.m_transId1 << " " << scan.m_transId2 << "]";
  325.   out << " [savePointId " << dec << scan.m_savePointId << "]";
  326.   out << " [accLockOp " << hex << scan.m_accLockOp << "]";
  327.   out << " [accLockOps";
  328.   for (unsigned i = 0; i < Dbtux::MaxAccLockOps; i++) {
  329.     if (scan.m_accLockOps[i] != RNIL)
  330.       out << " " << hex << scan.m_accLockOps[i];
  331.   }
  332.   out << "]";
  333.   out << " [readCommitted " << dec << scan.m_readCommitted << "]";
  334.   out << " [lockMode " << dec << scan.m_lockMode << "]";
  335.   out << " [keyInfo " << dec << scan.m_keyInfo << "]";
  336.   out << " [pos " << scan.m_scanPos << "]";
  337.   out << " [ent " << scan.m_scanEnt << "]";
  338.   for (unsigned i = 0; i <= 1; i++) {
  339.     out << " [bound " << dec << i;
  340.     Dbtux::ScanBound& bound = *scan.m_bound[i];
  341.     Dbtux::ScanBoundIterator iter;
  342.     bound.first(iter);
  343.     for (unsigned j = 0; j < bound.getSize(); j++) {
  344.       out << " " << hex << *iter.data;
  345.       bound.next(iter);
  346.     }
  347.     out << "]";
  348.   }
  349.   out << "]";
  350.   return out;
  351. }
  352. NdbOut&
  353. operator<<(NdbOut& out, const Dbtux::Index& index)
  354. {
  355.   out << "[Index " << hex << &index;
  356.   out << " [tableId " << dec << index.m_tableId << "]";
  357.   out << " [fragOff " << dec << index.m_fragOff << "]";
  358.   out << " [numFrags " << dec << index.m_numFrags << "]";
  359.   for (unsigned i = 0; i < index.m_numFrags; i++) {
  360.     out << " [frag " << dec << i << " ";
  361.     // dangerous and wrong
  362.     Dbtux* tux = (Dbtux*)globalData.getBlock(DBTUX);
  363.     const Dbtux::Frag& frag = *tux->c_fragPool.getPtr(index.m_fragPtrI[i]);
  364.     out << frag;
  365.     out << "]";
  366.   }
  367.   out << " [descPage " << hex << index.m_descPage << "]";
  368.   out << " [descOff " << dec << index.m_descOff << "]";
  369.   out << " [numAttrs " << dec << index.m_numAttrs << "]";
  370.   out << "]";
  371.   return out;
  372. }
  373. NdbOut&
  374. operator<<(NdbOut& out, const Dbtux::Frag& frag)
  375. {
  376.   out << "[Frag " << hex << &frag;
  377.   out << " [tableId " << dec << frag.m_tableId << "]";
  378.   out << " [indexId " << dec << frag.m_indexId << "]";
  379.   out << " [fragOff " << dec << frag.m_fragOff << "]";
  380.   out << " [fragId " << dec << frag.m_fragId << "]";
  381.   out << " [descPage " << hex << frag.m_descPage << "]";
  382.   out << " [descOff " << dec << frag.m_descOff << "]";
  383.   out << " [numAttrs " << dec << frag.m_numAttrs << "]";
  384.   out << " [tree " << frag.m_tree << "]";
  385.   out << "]";
  386.   return out;
  387. }
  388. NdbOut&
  389. operator<<(NdbOut& out, const Dbtux::FragOp& fragOp)
  390. {
  391.   out << "[FragOp " << hex << &fragOp;
  392.   out << " [userPtr " << dec << fragOp.m_userPtr << "]";
  393.   out << " [indexId " << dec << fragOp.m_indexId << "]";
  394.   out << " [fragId " << dec << fragOp.m_fragId << "]";
  395.   out << " [fragNo " << dec << fragOp.m_fragNo << "]";
  396.   out << " numAttrsRecvd " << dec << fragOp.m_numAttrsRecvd << "]";
  397.   out << "]";
  398.   return out;
  399. }
  400. NdbOut&
  401. operator<<(NdbOut& out, const Dbtux::NodeHandle& node)
  402. {
  403.   const Dbtux::Frag& frag = node.m_frag;
  404.   const Dbtux::TreeHead& tree = frag.m_tree;
  405.   out << "[NodeHandle " << hex << &node;
  406.   out << " [loc " << node.m_loc << "]";
  407.   out << " [node " << *node.m_node << "]";
  408.   const Uint32* data;
  409.   out << " [pref";
  410.   data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize;
  411.   for (unsigned j = 0; j < tree.m_prefSize; j++)
  412.     out << " " << hex << data[j];
  413.   out << "]";
  414.   out << " [entList";
  415.   unsigned numpos = node.m_node->m_occup;
  416.   data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize + tree.m_prefSize;
  417.   const Dbtux::TreeEnt* entList = (const Dbtux::TreeEnt*)data;
  418.   // print entries in logical order
  419.   for (unsigned pos = 1; pos <= numpos; pos++)
  420.     out << " " << entList[pos % numpos];
  421.   out << "]";
  422.   out << "]";
  423.   return out;
  424. }
  425. #endif