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

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. #include <NdbOut.hpp>
  14. #include <Ndb.hpp>
  15. #include <NdbOperation.hpp>
  16. #include <NdbIndexOperation.hpp>
  17. #include <NdbIndexScanOperation.hpp>
  18. #include <NdbConnection.hpp>
  19. #include "NdbApiSignal.hpp"
  20. #include <NdbRecAttr.hpp>
  21. #include "NdbUtil.hpp"
  22. #include "API.hpp"
  23. #include "NdbBlob.hpp"
  24. void
  25. Ndb::checkFailedNode()
  26. {
  27.   DBUG_ENTER("Ndb::checkFailedNode");
  28.   Uint32 *the_release_ind= theImpl->the_release_ind;
  29.   if (the_release_ind[0] == 0)
  30.   {
  31.     DBUG_VOID_RETURN;
  32.   }
  33.   Uint32 tNoOfDbNodes = theImpl->theNoOfDBnodes;
  34.   Uint8 *theDBnodes= theImpl->theDBnodes;
  35.   DBUG_PRINT("enter", ("theNoOfDBnodes: %d", tNoOfDbNodes));
  36.   DBUG_ASSERT(tNoOfDbNodes < MAX_NDB_NODES);
  37.   for (Uint32 i = 0; i < tNoOfDbNodes; i++){
  38.     const NodeId node_id = theDBnodes[i];
  39.     DBUG_PRINT("info", ("i: %d, node_id: %d", i, node_id));
  40.     
  41.     DBUG_ASSERT(node_id < MAX_NDB_NODES);    
  42.     if (the_release_ind[node_id] == 1){
  43.       /**
  44.        * Release all connections in idle list (for node)
  45.        */
  46.       NdbConnection * tNdbCon = theConnectionArray[node_id];
  47.       theConnectionArray[node_id] = NULL;
  48.       while (tNdbCon != NULL) {
  49.         NdbConnection* tempNdbCon = tNdbCon;
  50.         tNdbCon = tNdbCon->next();
  51.         releaseNdbCon(tempNdbCon);
  52.       }
  53.       the_release_ind[node_id] = 0;
  54.     }
  55.   }
  56.   DBUG_VOID_RETURN;
  57. }
  58. /***************************************************************************
  59.  * int createConIdleList(int aNrOfCon);
  60.  * 
  61.  * Return Value:   Return the number of created connection object 
  62.  *                 if createConIdleList was succesful
  63.  *                 Return -1: In all other case.  
  64.  * Parameters:     aNrOfCon : Number of connections offered to the application.
  65.  * Remark:         Create connection idlelist with NdbConnection objects.
  66.  ***************************************************************************/ 
  67. int 
  68. Ndb::createConIdleList(int aNrOfCon)
  69. {
  70.   theImpl->theConIdleList.fill(this, aNrOfCon);
  71.   return aNrOfCon; 
  72. }
  73. /***************************************************************************
  74.  * int createOpIdleList(int aNrOfOp);
  75.  *
  76.  * Return Value:   Return the number of created operation object if 
  77.  *                 createOpIdleList was succesful.
  78.  *                 Return -1: In all other case.
  79.  * Parameters:     aNrOfOp:  Number of operations offered to the application. 
  80.  * Remark:         Create  operation idlelist with NdbOperation objects..
  81.  ***************************************************************************/ 
  82. int 
  83. Ndb::createOpIdleList(int aNrOfOp)
  84.   theImpl->theOpIdleList.fill(this, aNrOfOp);
  85.   return aNrOfOp; 
  86. }
  87. /***************************************************************************
  88.  * NdbBranch* NdbBranch();
  89.  *
  90.  * Return Value:   Return a NdbBranch if the  getNdbBranch was successful.
  91.  *                Return NULL : In all other case.  
  92.  * Remark:         Get a NdbBranch from theBranchList and return the object .
  93.  ***************************************************************************/ 
  94. NdbBranch*
  95. Ndb::getNdbBranch()
  96. {
  97.   return theImpl->theBranchList.seize(this);
  98. }
  99. /***************************************************************************
  100.  * NdbCall* NdbCall();
  101.  *
  102.  * Return Value:   Return a NdbCall if the  getNdbCall was successful.
  103.  *                Return NULL : In all other case.  
  104.  * Remark:         Get a NdbCall from theCallList and return the object .
  105.  ***************************************************************************/ 
  106. NdbCall*
  107. Ndb::getNdbCall()
  108. {
  109.   return theImpl->theCallList.seize(this);
  110. }
  111. /***************************************************************************
  112.  * NdbConnection* getNdbCon();
  113.  *
  114.  * Return Value:   Return a connection if the  getNdbCon was successful.
  115.  *                Return NULL : In all other case.  
  116.  * Remark:         Get a connection from theConIdleList and return the object .
  117.  ***************************************************************************/ 
  118. NdbConnection*
  119. Ndb::getNdbCon()
  120. {
  121.   NdbConnection* tNdbCon = theImpl->theConIdleList.seize(this);
  122.   if (unlikely(theImpl->theConIdleList.m_alloc_cnt > theMaxNoOfTransactions)) 
  123.   {
  124.     theImpl->theConIdleList.release(tNdbCon);
  125.     ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
  126.     return NULL;
  127.   }//if
  128.   
  129.   tNdbCon->theMagicNumber = 0x37412619;
  130.   return tNdbCon;
  131. }
  132. /***************************************************************************
  133.  * NdbLabel* getNdbLabel();
  134.  *
  135.  * Return Value:   Return a NdbLabel if the  getNdbLabel was successful.
  136.  *                 Return NULL : In all other case.  
  137.  * Remark:         Get a NdbLabel from theLabelList and return the object .
  138.  ***************************************************************************/ 
  139. NdbLabel*
  140. Ndb::getNdbLabel()
  141. {
  142.   return theImpl->theLabelList.seize(this);
  143. }
  144. /***************************************************************************
  145.  * NdbScanReceiver* getNdbScanRec()
  146.  * 
  147.  * Return Value:  Return a NdbScanReceiver
  148.  *                Return NULL : In all other case.  
  149.  * Remark:        Get a NdbScanReceiver from theScanRecList and return the 
  150.  *                object .
  151.  ****************************************************************************/ 
  152. NdbReceiver*
  153. Ndb::getNdbScanRec()
  154. {
  155.   return theImpl->theScanList.seize(this);
  156. }
  157. /***************************************************************************
  158.  * NdbSubroutine* getNdbSubroutine();
  159.  *
  160.  * Return Value: Return a NdbSubroutine if the  getNdbSubroutine was successful.
  161.  *                Return NULL : In all other case.  
  162.  * Remark:    Get a NdbSubroutine from theSubroutineList and return the object .
  163.  ***************************************************************************/ 
  164. NdbSubroutine*
  165. Ndb::getNdbSubroutine()
  166. {
  167.   return theImpl->theSubroutineList.seize(this);
  168. }
  169. /***************************************************************************
  170. NdbOperation* getOperation();
  171. Return Value:   Return theOpList : if the  getOperation was succesful.
  172.                 Return NULL : In all other case.  
  173. Remark:         Get an operation from theOpIdleList and return the object .
  174. ***************************************************************************/ 
  175. NdbOperation*
  176. Ndb::getOperation()
  177. {
  178.   return theImpl->theOpIdleList.seize(this);
  179. }
  180. /***************************************************************************
  181. NdbScanOperation* getScanOperation();
  182. Return Value:   Return theOpList : if the  getScanOperation was succesful.
  183.                 Return NULL : In all other case.  
  184. Remark:         Get an operation from theScanOpIdleList and return the object .
  185. ***************************************************************************/ 
  186. NdbIndexScanOperation*
  187. Ndb::getScanOperation()
  188. {
  189.   return theImpl->theScanOpIdleList.seize(this);
  190. }
  191. /***************************************************************************
  192. NdbIndexOperation* getIndexOperation();
  193. Return Value:   Return theOpList : if the  getIndexOperation was succesful.
  194.                 Return NULL : In all other case.  
  195. Remark:         Get an operation from theIndexOpIdleList and return the object .
  196. ***************************************************************************/ 
  197. NdbIndexOperation*
  198. Ndb::getIndexOperation()
  199. {
  200.   return theImpl->theIndexOpIdleList.seize(this);
  201. }
  202. /***************************************************************************
  203. NdbRecAttr* getRecAttr();
  204. Return Value:   Return a reference to a receive attribute object.
  205.                 Return NULL if it's not possible to get a receive attribute object.
  206. ***************************************************************************/
  207. NdbRecAttr*
  208. Ndb::getRecAttr()
  209. {
  210.   NdbRecAttr* tRecAttr = theImpl->theRecAttrIdleList.seize(this);
  211.   if (tRecAttr != NULL) 
  212.   {
  213.     tRecAttr->init();
  214.     return tRecAttr;
  215.   }
  216.   return NULL;
  217. }
  218. /***************************************************************************
  219. NdbApiSignal* getSignal();
  220. Return Value:   Return a reference to a signal object.
  221.                 Return NULL if not possible to get a signal object.
  222. ***************************************************************************/
  223. NdbApiSignal*
  224. Ndb::getSignal()
  225. {
  226.   return theImpl->theSignalIdleList.seize(this);
  227. }
  228. NdbBlob*
  229. Ndb::getNdbBlob()
  230. {
  231.   NdbBlob* tBlob = theImpl->theNdbBlobIdleList.seize(this);
  232.   if(tBlob)
  233.   {
  234.     tBlob->init();
  235.   }
  236.   return tBlob;
  237. }
  238. /***************************************************************************
  239. void releaseNdbBranch(NdbBranch* aNdbBranch);
  240. Parameters:     NdbBranch: The NdbBranch object.
  241. Remark:         Add a NdbBranch object into the Branch idlelist.
  242. ***************************************************************************/
  243. void
  244. Ndb::releaseNdbBranch(NdbBranch* aNdbBranch)
  245. {
  246.   theImpl->theBranchList.release(aNdbBranch);
  247. }
  248. /***************************************************************************
  249. void releaseNdbCall(NdbCall* aNdbCall);
  250. Parameters:     NdbBranch: The NdbBranch object.
  251. Remark:         Add a NdbBranch object into the Branch idlelist.
  252. ***************************************************************************/
  253. void
  254. Ndb::releaseNdbCall(NdbCall* aNdbCall)
  255. {
  256.   theImpl->theCallList.release(aNdbCall);
  257. }
  258. /***************************************************************************
  259. void releaseNdbCon(NdbConnection* aNdbCon);
  260. Parameters:     aNdbCon: The NdbConnection object.
  261. Remark:         Add a Connection object into the signal idlelist.
  262. ***************************************************************************/
  263. void
  264. Ndb::releaseNdbCon(NdbConnection* aNdbCon)
  265. {
  266.   aNdbCon->theMagicNumber = 0xFE11DD;
  267.   theImpl->theConIdleList.release(aNdbCon);
  268. }
  269. /***************************************************************************
  270. void releaseNdbLabel(NdbLabel* aNdbLabel);
  271. Parameters:     NdbLabel: The NdbLabel object.
  272. Remark:         Add a NdbLabel object into the Label idlelist.
  273. ***************************************************************************/
  274. void
  275. Ndb::releaseNdbLabel(NdbLabel* aNdbLabel)
  276. {
  277.   theImpl->theLabelList.release(aNdbLabel);
  278. }
  279. /***************************************************************************
  280. void releaseNdbScanRec(NdbScanReceiver* aNdbScanRec);
  281. Parameters:     aNdbScanRec: The NdbScanReceiver object.
  282. Remark:         Add a NdbScanReceiver object into the Scan idlelist.
  283. ***************************************************************************/
  284. void
  285. Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec)
  286. {
  287.   theImpl->theScanList.release(aNdbScanRec);
  288. }
  289. /***************************************************************************
  290. void releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine);
  291. Parameters:     NdbSubroutine: The NdbSubroutine object.
  292. Remark:         Add a NdbSubroutine object into theSubroutine idlelist.
  293. ***************************************************************************/
  294. void
  295. Ndb::releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine)
  296. {
  297.   theImpl->theSubroutineList.release(aNdbSubroutine);
  298. }
  299. /***************************************************************************
  300. void releaseOperation(NdbOperation* anOperation);
  301. Parameters:     anOperation : The released NdbOperation object.
  302. Remark:         Add a NdbOperation object into the signal idlelist.
  303. ***************************************************************************/
  304. void
  305. Ndb::releaseOperation(NdbOperation* anOperation)
  306. {
  307.   if(anOperation->m_tcReqGSN == GSN_TCKEYREQ){
  308.     anOperation->theNdbCon = NULL;
  309.     anOperation->theMagicNumber = 0xFE11D0;
  310.     theImpl->theOpIdleList.release(anOperation);
  311.   } else {
  312.     assert(anOperation->m_tcReqGSN == GSN_TCINDXREQ);
  313.     anOperation->theNdbCon = NULL;
  314.     anOperation->theMagicNumber = 0xFE11D1;
  315.     theImpl->theIndexOpIdleList.release((NdbIndexOperation*)anOperation);
  316.   }
  317. }
  318. /***************************************************************************
  319. void releaseScanOperation(NdbScanOperation* aScanOperation);
  320. Parameters:     aScanOperation : The released NdbScanOperation object.
  321. Remark:         Add a NdbScanOperation object into the signal idlelist.
  322. ***************************************************************************/
  323. void
  324. Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation)
  325. {
  326.   aScanOperation->theNdbCon = NULL;
  327.   aScanOperation->theMagicNumber = 0xFE11D2;
  328.   theImpl->theScanOpIdleList.release(aScanOperation);
  329. }
  330. /***************************************************************************
  331. void releaseRecAttr(NdbRecAttr* aRecAttr);
  332. Parameters:     aRecAttr : The released NdbRecAttr object.
  333. Remark:         Add a NdbRecAttr object into the RecAtt idlelist.
  334. ***************************************************************************/
  335. void
  336. Ndb::releaseRecAttr(NdbRecAttr* aRecAttr)
  337. {
  338.   aRecAttr->release();
  339.   theImpl->theRecAttrIdleList.release(aRecAttr);
  340. }
  341. /***************************************************************************
  342. void releaseSignal(NdbApiSignal* aSignal);
  343. Parameters:     aSignal : The released NdbApiSignal object.
  344. Remark:         Add a NdbApiSignal object into the signal idlelist.
  345. ***************************************************************************/
  346. void
  347. Ndb::releaseSignal(NdbApiSignal* aSignal)
  348. {
  349. #if defined VM_TRACE
  350.   // Check that signal is not null
  351.   assert(aSignal != NULL);
  352. #if 0
  353.   // Check that signal is not already in list
  354.   NdbApiSignal* tmp = theSignalIdleList;
  355.   while (tmp != NULL){
  356.     assert(tmp != aSignal);
  357.     tmp = tmp->next();
  358.   }
  359. #endif
  360. #endif
  361. #ifdef POORMANSPURIFY
  362.   creleaseSignals++;
  363. #endif
  364.   theImpl->theSignalIdleList.release(aSignal);
  365. }
  366. void
  367. Ndb::releaseSignalsInList(NdbApiSignal** pList){
  368.   NdbApiSignal* tmp;
  369.   while (*pList != NULL){
  370.     tmp = *pList;
  371.     *pList = (*pList)->next();
  372.     releaseSignal(tmp);
  373.   }
  374. }
  375. void
  376. Ndb::releaseNdbBlob(NdbBlob* aBlob)
  377. {
  378.   theImpl->theNdbBlobIdleList.release(aBlob);
  379. }
  380. /****************************************************************************
  381. int releaseConnectToNdb(NdbConnection* aConnectConnection);
  382. Return Value:   -1 if error 
  383. Parameters:     aConnectConnection : Seized schema connection to DBTC
  384. Remark:         Release and disconnect from DBTC a connection and seize it to theConIdleList.
  385. *****************************************************************************/
  386. void
  387. Ndb::releaseConnectToNdb(NdbConnection* a_con)     
  388. {
  389.   DBUG_ENTER("Ndb::releaseConnectToNdb");
  390.   NdbApiSignal          tSignal(theMyRef);
  391.   int                   tConPtr;
  392. // I need to close the connection irrespective of whether I
  393. // manage to reach NDB or not.
  394.   if (a_con == NULL)
  395.     DBUG_VOID_RETURN;
  396.   Uint32 node_id = a_con->getConnectedNodeId();
  397.   Uint32 conn_seq = a_con->theNodeSequence;
  398.   tSignal.setSignal(GSN_TCRELEASEREQ);
  399.   tSignal.setData((tConPtr = a_con->getTC_ConnectPtr()), 1);
  400.   tSignal.setData(theMyRef, 2);
  401.   tSignal.setData(a_con->ptr2int(), 3); 
  402.   a_con->Status(NdbConnection::DisConnecting);
  403.   a_con->theMagicNumber = 0x37412619;
  404.   int ret_code = sendRecSignal(node_id,
  405.                                WAIT_TC_RELEASE,
  406.                                &tSignal,
  407.                                conn_seq);
  408.   if (ret_code == 0) {
  409.     ;
  410.   } else if (ret_code == -1) {
  411.     TRACE_DEBUG("Time-out when TCRELEASE sent");
  412.   } else if (ret_code == -2) {
  413.     TRACE_DEBUG("Node failed when TCRELEASE sent");
  414.   } else if (ret_code == -3) {
  415.     TRACE_DEBUG("Send failed when TCRELEASE sent");
  416.   } else if (ret_code == -4) {
  417.     TRACE_DEBUG("Send buffer full when TCRELEASE sent");
  418.   } else if (ret_code == -5) {
  419.     TRACE_DEBUG("Node stopping when TCRELEASE sent");
  420.   } else {
  421.     ndbout << "Impossible return from sendRecSignal when TCRELEASE" << endl;
  422.     abort();
  423.   }//if
  424.   releaseNdbCon(a_con);
  425.   DBUG_VOID_RETURN;
  426. }
  427. template<class T>
  428. static
  429. Ndb::Free_list_usage*
  430. update(Ndb::Free_list_usage* curr, 
  431.        Ndb_free_list_t<T> & list, 
  432.        const char * name)
  433. {
  434.   curr->m_name = name;
  435.   curr->m_created = list.m_alloc_cnt;
  436.   curr->m_free = list.m_free_cnt;
  437.   curr->m_sizeof = sizeof(T);
  438.   return curr;
  439. }
  440. Ndb::Free_list_usage*
  441. Ndb::get_free_list_usage(Ndb::Free_list_usage* curr)
  442. {
  443.   if (curr == 0)
  444.   {
  445.     return 0;
  446.   } 
  447.   if(curr->m_name == 0)
  448.   {
  449.     update(curr, theImpl->theConIdleList, "NdbTransaction");
  450.   }
  451.   else if(!strcmp(curr->m_name, "NdbTransaction"))
  452.   {
  453.     update(curr, theImpl->theOpIdleList, "NdbOperation");
  454.   }
  455.   else if(!strcmp(curr->m_name, "NdbOperation"))
  456.   {
  457.     update(curr, theImpl->theScanOpIdleList, "NdbIndexScanOperation");
  458.   }
  459.   else if(!strcmp(curr->m_name, "NdbIndexScanOperation"))
  460.   {
  461.     update(curr, theImpl->theIndexOpIdleList, "NdbIndexOperation");
  462.   }
  463.   else if(!strcmp(curr->m_name, "NdbIndexOperation"))
  464.   {
  465.     update(curr, theImpl->theRecAttrIdleList, "NdbRecAttr");
  466.   }
  467.   else if(!strcmp(curr->m_name, "NdbRecAttr"))
  468.   {
  469.     update(curr, theImpl->theSignalIdleList, "NdbApiSignal");
  470.   }
  471.   else if(!strcmp(curr->m_name, "NdbApiSignal"))
  472.   {
  473.     update(curr, theImpl->theLabelList, "NdbLabel");
  474.   }
  475.   else if(!strcmp(curr->m_name, "NdbLabel"))
  476.   {
  477.     update(curr, theImpl->theBranchList, "NdbBranch");
  478.   }
  479.   else if(!strcmp(curr->m_name, "NdbBranch"))
  480.   {
  481.     update(curr, theImpl->theSubroutineList, "NdbSubroutine");
  482.   }
  483.   else if(!strcmp(curr->m_name, "NdbSubroutine"))
  484.   {
  485.     update(curr, theImpl->theCallList, "NdbCall");
  486.   }
  487.   else if(!strcmp(curr->m_name, "NdbCall"))
  488.   {
  489.     update(curr, theImpl->theNdbBlobIdleList, "NdbBlob");
  490.   }
  491.   else if(!strcmp(curr->m_name, "NdbBlob"))
  492.   {
  493.     update(curr, theImpl->theScanList, "NdbReceiver");
  494.   }
  495.   else if(!strcmp(curr->m_name, "NdbReceiver"))
  496.   {
  497.     return 0;
  498.   }
  499.   else
  500.   {
  501.     update(curr, theImpl->theConIdleList, "NdbTransaction");
  502.   }
  503.   return curr;
  504. }
  505. #define TI(T) 
  506.  template Ndb::Free_list_usage* 
  507.  update(Ndb::Free_list_usage*, Ndb_free_list_t<T> &, const char * name);
  508.  template struct Ndb_free_list_t<T>
  509. TI(NdbBlob);
  510. TI(NdbCall);
  511. TI(NdbLabel);
  512. TI(NdbBranch);
  513. TI(NdbSubroutine);
  514. TI(NdbApiSignal);
  515. TI(NdbRecAttr);
  516. TI(NdbOperation);
  517. TI(NdbReceiver);
  518. TI(NdbConnection);
  519. TI(NdbIndexOperation);
  520. TI(NdbIndexScanOperation);