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

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 <ndb_global.h>
  14. #include <ndb_opts.h>
  15. #include <mgmapi.h>
  16. #include <NdbMain.h>
  17. #include <NdbOut.hpp>
  18. #include <NdbSleep.h>
  19. #include <kernel/ndb_limits.h>
  20. #include <NDBT.hpp>
  21. int 
  22. waitClusterStatus(const char* _addr, ndb_mgm_node_status _status,
  23.   unsigned int _timeout);
  24. enum ndb_waiter_options {
  25.   OPT_WAIT_STATUS_NOT_STARTED = NDB_STD_OPTIONS_LAST
  26. };
  27. NDB_STD_OPTS_VARS;
  28. static int _no_contact = 0;
  29. static int _not_started = 0;
  30. static int _timeout = 120;
  31. static struct my_option my_long_options[] =
  32. {
  33.   NDB_STD_OPTS("ndb_desc"),
  34.   { "no-contact", 'n', "Wait for cluster no contact",
  35.     (gptr*) &_no_contact, (gptr*) &_no_contact, 0,
  36.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, 
  37.   { "not-started", OPT_WAIT_STATUS_NOT_STARTED, "Wait for cluster not started",
  38.     (gptr*) &_not_started, (gptr*) &_not_started, 0,
  39.     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, 
  40.   { "timeout", 't', "Timeout to wait",
  41.     (gptr*) &_timeout, (gptr*) &_timeout, 0,
  42.     GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 }, 
  43.   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
  44. };
  45. static void usage()
  46. {
  47.   ndb_std_print_version();
  48.   my_print_help(my_long_options);
  49.   my_print_variables(my_long_options);
  50. }
  51. static my_bool
  52. get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
  53.        char *argument)
  54. {
  55.   return ndb_std_get_one_option(optid, opt, argument ? argument :
  56. "d:t:O,/tmp/ndb_drop_table.trace");
  57. }
  58. int main(int argc, char** argv){
  59.   NDB_INIT(argv[0]);
  60.   const char *load_default_groups[]= { "mysql_cluster",0 };
  61.   load_defaults("my",load_default_groups,&argc,&argv);
  62.   const char* _hostName = NULL;
  63.   int ho_error;
  64.   if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
  65.     return NDBT_ProgramExit(NDBT_WRONGARGS);
  66.   char buf[255];
  67.   _hostName = argv[0];
  68.   if (_hostName == 0)
  69.     _hostName= opt_connect_str;
  70.   enum ndb_mgm_node_status wait_status;
  71.   if (_no_contact)
  72.   {
  73.     wait_status= NDB_MGM_NODE_STATUS_NO_CONTACT;
  74.   }
  75.   else if (_not_started)
  76.   {
  77.     wait_status= NDB_MGM_NODE_STATUS_NOT_STARTED;
  78.   }
  79.   else 
  80.   {
  81.     wait_status= NDB_MGM_NODE_STATUS_STARTED;
  82.   }
  83.   if (waitClusterStatus(_hostName, wait_status, _timeout) != 0)
  84.     return NDBT_ProgramExit(NDBT_FAILED);
  85.   return NDBT_ProgramExit(NDBT_OK);
  86. }
  87. #define MGMERR(h) 
  88.   ndbout << "latest_error="<<ndb_mgm_get_latest_error(h) 
  89.  << ", line="<<ndb_mgm_get_latest_error_line(h) 
  90.  << endl;
  91. NdbMgmHandle handle= NULL;
  92. Vector<ndb_mgm_node_state> ndbNodes;
  93. Vector<ndb_mgm_node_state> mgmNodes;
  94. Vector<ndb_mgm_node_state> apiNodes;
  95. int 
  96. getStatus(){
  97.   int retries = 0;
  98.   struct ndb_mgm_cluster_state * status;
  99.   struct ndb_mgm_node_state * node;
  100.   
  101.   ndbNodes.clear();
  102.   mgmNodes.clear();
  103.   apiNodes.clear();
  104.   while(retries < 10){
  105.     status = ndb_mgm_get_status(handle);
  106.     if (status == NULL){
  107.       ndbout << "status==NULL, retries="<<retries<<endl;
  108.       MGMERR(handle);
  109.       retries++;
  110.       continue;
  111.     }
  112.     int count = status->no_of_nodes;
  113.     for (int i = 0; i < count; i++){
  114.       node = &status->node_states[i];      
  115.       switch(node->node_type){
  116.       case NDB_MGM_NODE_TYPE_NDB:
  117. ndbNodes.push_back(*node);
  118. break;
  119.       case NDB_MGM_NODE_TYPE_MGM:
  120. mgmNodes.push_back(*node);
  121. break;
  122.       case NDB_MGM_NODE_TYPE_API:
  123. apiNodes.push_back(*node);
  124. break;
  125.       default:
  126. if(node->node_status == NDB_MGM_NODE_STATUS_UNKNOWN ||
  127.    node->node_status == NDB_MGM_NODE_STATUS_NO_CONTACT){
  128.   retries++;
  129.   ndbNodes.clear();
  130.   mgmNodes.clear();
  131.   apiNodes.clear();
  132.   free(status); 
  133.   status = NULL;
  134.           count = 0;
  135.   ndbout << "kalle"<< endl;
  136.   break;
  137. }
  138. abort();
  139. break;
  140.       }
  141.     }
  142.     if(status == 0){
  143.       ndbout << "status == 0" << endl;
  144.       continue;
  145.     }
  146.     free(status);
  147.     return 0;
  148.   }
  149.    
  150.   g_err  << "getStatus failed" << endl;
  151.   return -1;
  152. }
  153. int 
  154. waitClusterStatus(const char* _addr,
  155.   ndb_mgm_node_status _status,
  156.   unsigned int _timeout)
  157. {
  158.   int _startphase = -1;
  159.   int _nodes[MAX_NDB_NODES];
  160.   int _num_nodes = 0;
  161.   handle = ndb_mgm_create_handle();
  162.   if (handle == NULL){
  163.     g_err << "handle == NULL" << endl;
  164.     return -1;
  165.   }
  166.   g_info << "Connecting to mgmsrv at " << _addr << endl;
  167.   if (ndb_mgm_set_connectstring(handle, _addr))
  168.   {
  169.     MGMERR(handle);
  170.     g_err  << "Connectstring " << _addr << " invalid" << endl;
  171.     return -1;
  172.   }
  173.   if (ndb_mgm_connect(handle,0,0,1)) {
  174.     MGMERR(handle);
  175.     g_err  << "Connection to " << _addr << " failed" << endl;
  176.     return -1;
  177.   }
  178.   if (getStatus() != 0)
  179.     return -1;
  180.   
  181.   // Collect all nodes into nodes
  182.   for (size_t i = 0; i < ndbNodes.size(); i++){
  183.     _nodes[i] = ndbNodes[i].node_id;
  184.     _num_nodes++;
  185.   }
  186.   unsigned int attempts = 0;
  187.   unsigned int resetAttempts = 0;
  188.   const unsigned int MAX_RESET_ATTEMPTS = 10;
  189.   bool allInState = false;    
  190.   while (allInState == false){
  191.     if (_timeout > 0 && attempts > _timeout){
  192.       /**
  193.        * Timeout has expired waiting for the nodes to enter
  194.        * the state we want
  195.        */
  196.       bool waitMore = false;
  197.       /** 
  198.        * Make special check if we are waiting for 
  199.        * cluster to become started
  200.        */
  201.       if(_status == NDB_MGM_NODE_STATUS_STARTED){
  202. waitMore = true;
  203. /**
  204.  * First check if any node is not starting
  205.  * then it's no idea to wait anymore
  206.  */
  207. for (size_t n = 0; n < ndbNodes.size(); n++){
  208.   if (ndbNodes[n].node_status != NDB_MGM_NODE_STATUS_STARTED &&
  209.       ndbNodes[n].node_status != NDB_MGM_NODE_STATUS_STARTING)
  210.     waitMore = false;
  211. }
  212.       } 
  213.       if (!waitMore || resetAttempts > MAX_RESET_ATTEMPTS){
  214. g_err << "waitNodeState("
  215.       << ndb_mgm_get_node_status_string(_status)
  216.       <<", "<<_startphase<<")"
  217.       << " timeout after " << attempts <<" attemps" << endl;
  218. return -1;
  219.       } 
  220.       g_err << "waitNodeState("
  221.     << ndb_mgm_get_node_status_string(_status)
  222.     <<", "<<_startphase<<")"
  223.     << " resetting number of attempts "
  224.     << resetAttempts << endl;
  225.       attempts = 0;
  226.       resetAttempts++;
  227.       
  228.     }
  229.     allInState = true;
  230.     if (getStatus() != 0){
  231.       g_err << "getStatus != 0" << endl;
  232.       return -1;
  233.     }
  234.     // ndbout << "waitNodeState; _num_nodes = " << _num_nodes << endl;
  235.     // for (int i = 0; i < _num_nodes; i++)
  236.     //   ndbout << " node["<<i<<"] =" <<_nodes[i] << endl;
  237.     for (int i = 0; i < _num_nodes; i++){
  238.       ndb_mgm_node_state* ndbNode = NULL;
  239.       for (size_t n = 0; n < ndbNodes.size(); n++){
  240. if (ndbNodes[n].node_id == _nodes[i])
  241.   ndbNode = &ndbNodes[n];
  242.       }
  243.       if(ndbNode == NULL){
  244. allInState = false;
  245. continue;
  246.       }
  247.       g_info << "State node " << ndbNode->node_id << " "
  248.      << ndb_mgm_get_node_status_string(ndbNode->node_status)<< endl;
  249.       assert(ndbNode != NULL);
  250.       if(_status == NDB_MGM_NODE_STATUS_STARTING && 
  251.  ((ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTING && 
  252.    ndbNode->start_phase >= _startphase) ||
  253.   (ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTED)))
  254. continue;
  255.       if (_status == NDB_MGM_NODE_STATUS_STARTING){
  256. g_info << "status = "  
  257.        << ndb_mgm_get_node_status_string(ndbNode->node_status)
  258.        <<", start_phase="<<ndbNode->start_phase<<endl;
  259. if (ndbNode->node_status !=  _status) {
  260.   if (ndbNode->node_status < _status)
  261.     allInState = false;
  262.   else 
  263.     g_info << "node_status(" << (unsigned)ndbNode->node_status
  264.    << ") != _status("<< (unsigned)_status << ")" <<endl;
  265. } else if (ndbNode->start_phase < _startphase)
  266.   allInState = false;
  267.       } else {
  268. if (ndbNode->node_status !=  _status) 
  269.   allInState = false;
  270.       }
  271.     }
  272.     g_info << "Waiting for cluster enter state " 
  273.     << ndb_mgm_get_node_status_string(_status)<< endl;
  274.     NdbSleep_SecSleep(1);
  275.     attempts++;
  276.   }
  277.   return 0;
  278. }
  279. template class Vector<ndb_mgm_node_state>;