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

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 <my_pthread.h>
  15. #include <ndb_version.h>
  16. #include "Configuration.hpp"
  17. #include <TransporterRegistry.hpp>
  18. #include "vm/SimBlockList.hpp"
  19. #include "ThreadConfig.hpp"
  20. #include <SignalLoggerManager.hpp>
  21. #include <NdbOut.hpp>
  22. #include <NdbMain.h>
  23. #include <NdbDaemon.h>
  24. #include <NdbSleep.h>
  25. #include <NdbConfig.h>
  26. #include <WatchDog.hpp>
  27. #include <LogLevel.hpp>
  28. #include <EventLogger.hpp>
  29. #include <NdbAutoPtr.hpp>
  30. #if defined NDB_SOLARIS // ok
  31. #include <sys/processor.h> // For system informatio
  32. #endif
  33. extern EventLogger g_eventLogger;
  34. extern NdbMutex * theShutdownMutex;
  35. void catchsigs(bool ignore); // for process signal handling
  36. #define MAX_FAILED_STARTUPS 3
  37. // Flag set by child through SIGUSR1 to signal a failed startup
  38. static bool failed_startup_flag = false;
  39. // Counter for consecutive failed startups
  40. static Uint32 failed_startups = 0;
  41. extern "C" void handler_shutdown(int signum);  // for process signal handling
  42. extern "C" void handler_error(int signum);  // for process signal handling
  43. extern "C" void handler_sigusr1(int signum);  // child signalling failed restart
  44. // Shows system information
  45. void systemInfo(const Configuration & conf,
  46. const LogLevel & ll); 
  47. int main(int argc, char** argv)
  48. {
  49.   NDB_INIT(argv[0]);
  50.   // Print to stdout/console
  51.   g_eventLogger.createConsoleHandler();
  52.   g_eventLogger.setCategory("ndbd");
  53.   g_eventLogger.enable(Logger::LL_ON, Logger::LL_CRITICAL);
  54.   g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
  55.   g_eventLogger.enable(Logger::LL_ON, Logger::LL_WARNING);
  56.   globalEmulatorData.create();
  57.   // Parse command line options
  58.   Configuration* theConfig = globalEmulatorData.theConfiguration;
  59.   if(!theConfig->init(argc, argv)){
  60.     return NRT_Default;
  61.   }
  62.   
  63.   { // Do configuration
  64. #ifndef NDB_WIN32
  65. signal(SIGPIPE, SIG_IGN);
  66. #endif
  67.     theConfig->fetch_configuration();
  68.   }
  69.   my_setwd(NdbConfig_get_path(0), MYF(0));
  70.   if (theConfig->getDaemonMode()) {
  71.     // Become a daemon
  72.     char *lockfile= NdbConfig_PidFileName(globalData.ownId);
  73.     char *logfile=  NdbConfig_StdoutFileName(globalData.ownId);
  74.     NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
  75.     if (NdbDaemon_Make(lockfile, logfile, 0) == -1) {
  76.       ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
  77.       return 1;
  78.     }
  79.   }
  80.   
  81. #ifndef NDB_WIN32
  82.   signal(SIGUSR1, handler_sigusr1);
  83.   for(pid_t child = fork(); child != 0; child = fork()){
  84.     /**
  85.      * Parent
  86.      */
  87.     catchsigs(true);
  88.     int status = 0;
  89.     while(waitpid(child, &status, 0) != child);
  90.     if(WIFEXITED(status)){
  91.       switch(WEXITSTATUS(status)){
  92.       case NRT_Default:
  93. g_eventLogger.info("Angel shutting down");
  94. exit(0);
  95. break;
  96.       case NRT_NoStart_Restart:
  97. theConfig->setInitialStart(false);
  98. globalData.theRestartFlag = initial_state;
  99. break;
  100.       case NRT_NoStart_InitialStart:
  101. theConfig->setInitialStart(true);
  102. globalData.theRestartFlag = initial_state;
  103. break;
  104.       case NRT_DoStart_InitialStart:
  105. theConfig->setInitialStart(true);
  106. globalData.theRestartFlag = perform_start;
  107. break;
  108.       default:
  109. if(theConfig->stopOnError()){
  110.   /**
  111.    * Error shutdown && stopOnError()
  112.    */
  113.   exit(0);
  114. }
  115. // Fall-through
  116.       case NRT_DoStart_Restart:
  117. theConfig->setInitialStart(false);
  118. globalData.theRestartFlag = perform_start;
  119. break;
  120.       }
  121.     } else if(theConfig->stopOnError()){
  122.       /**
  123.        * Error shutdown && stopOnError()
  124.        */
  125.       exit(0);
  126.     }
  127.     if (!failed_startup_flag)
  128.     {
  129.       // Reset the counter for consecutive failed startups
  130.       failed_startups = 0;
  131.     }
  132.     else if (failed_startups >= MAX_FAILED_STARTUPS && !theConfig->stopOnError())
  133.     {
  134.       /**
  135.        * Error shutdown && stopOnError()
  136.        */
  137.       g_eventLogger.alert("Ndbd has failed %u consecutive startups. Not restarting", failed_startups);
  138.       exit(0);
  139.     }
  140.     failed_startup_flag = false;
  141.     g_eventLogger.info("Ndb has terminated (pid %d) restarting", child);
  142.     theConfig->fetch_configuration();
  143.   }
  144.   g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid());
  145. #else
  146.   g_eventLogger.info("Ndb started");
  147. #endif
  148.   theConfig->setupConfiguration();
  149.   systemInfo(* theConfig, * theConfig->m_logLevel); 
  150.   
  151.     // Load blocks
  152.   globalEmulatorData.theSimBlockList->load(* theConfig);
  153.     
  154.   // Set thread concurrency for Solaris' light weight processes
  155.   int status;
  156.   status = NdbThread_SetConcurrencyLevel(30);
  157.   assert(status == 0);
  158.   
  159. #ifdef VM_TRACE
  160.   // Create a signal logger
  161.   char *buf= NdbConfig_SignalLogFileName(globalData.ownId);
  162.   NdbAutoPtr<char> tmp_aptr(buf);
  163.   FILE * signalLog = fopen(buf, "a");
  164.   globalSignalLoggers.setOwnNodeId(globalData.ownId);
  165.   globalSignalLoggers.setOutputStream(signalLog);
  166. #endif
  167.   
  168.   catchsigs(false);
  169.    
  170.   /**
  171.    * Do startup
  172.    */
  173.   ErrorReporter::setErrorHandlerShutdownType(NST_ErrorHandlerStartup);
  174.   switch(globalData.theRestartFlag){
  175.   case initial_state:
  176.     globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
  177.     break;
  178.   case perform_start:
  179.     globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
  180.     globalEmulatorData.theThreadConfig->doStart(NodeState::SL_STARTING);
  181.     break;
  182.   default:
  183.     assert("Illegal state globalData.theRestartFlag" == 0);
  184.   }
  185.   globalTransporterRegistry.startSending();
  186.   globalTransporterRegistry.startReceiving();
  187.   if (!globalTransporterRegistry.start_service(*globalEmulatorData.m_socket_server)){
  188.     ndbout_c("globalTransporterRegistry.start_service() failed");
  189.     exit(-1);
  190.   }
  191.   if (!globalTransporterRegistry.start_clients()){
  192.     ndbout_c("globalTransporterRegistry.start_clients() failed");
  193.     exit(-1);
  194.   }
  195.   globalEmulatorData.theWatchDog->doStart();
  196.   
  197.   globalEmulatorData.m_socket_server->startServer();
  198.   //  theConfig->closeConfiguration();
  199.   globalEmulatorData.theThreadConfig->ipControlLoop();
  200.   
  201.   NdbShutdown(NST_Normal);
  202.   return NRT_Default;
  203. }
  204. void 
  205. systemInfo(const Configuration & config, const LogLevel & logLevel){
  206. #ifdef NDB_WIN32
  207.   int processors = 0;
  208.   int speed;
  209.   SYSTEM_INFO sinfo;
  210.   GetSystemInfo(&sinfo);
  211.   processors = sinfo.dwNumberOfProcessors;
  212.   HKEY hKey;
  213.   if(ERROR_SUCCESS==RegOpenKeyEx
  214.      (HKEY_LOCAL_MACHINE, 
  215.       TEXT("HARDWARE\DESCRIPTION\System\CentralProcessor\0"), 
  216.       0, KEY_READ, &hKey)) {
  217.     DWORD dwMHz;
  218.     DWORD cbData = sizeof(dwMHz);
  219.     if(ERROR_SUCCESS==RegQueryValueEx(hKey, 
  220.       "~MHz", 0, 0, (LPBYTE)&dwMHz, &cbData)) {
  221.       speed = int(dwMHz);
  222.     }
  223.     RegCloseKey(hKey);
  224.   }
  225. #elif defined NDB_SOLARIS // ok
  226.   // Search for at max 16 processors among the first 256 processor ids
  227.   processor_info_t pinfo; memset(&pinfo, 0, sizeof(pinfo));
  228.   int pid = 0;
  229.   while(processors < 16 && pid < 256){
  230.     if(!processor_info(pid++, &pinfo))
  231.       processors++;
  232.   }
  233.   speed = pinfo.pi_clock;
  234. #endif
  235.   
  236.   if(logLevel.getLogLevel(LogLevel::llStartUp) > 0){
  237.     g_eventLogger.info("NDB Cluster -- DB node %d", globalData.ownId);
  238.     g_eventLogger.info("%s --", NDB_VERSION_STRING);
  239.     if (config.get_mgmd_host())
  240.       g_eventLogger.info("Configuration fetched at %s port %d",
  241.  config.get_mgmd_host(), config.get_mgmd_port());
  242. #ifdef NDB_SOLARIS // ok
  243.     g_eventLogger.info("NDB is running on a machine with %d processor(s) at %d MHz",
  244.        processor, speed);
  245. #endif
  246.   }
  247.   if(logLevel.getLogLevel(LogLevel::llStartUp) > 3){
  248.     Uint32 t = config.timeBetweenWatchDogCheck();
  249.     g_eventLogger.info("WatchDog timer is set to %d ms", t);
  250.   }
  251. }
  252. #define handler_register(signum, handler, ignore)
  253. {
  254.   if (ignore) {
  255.     if(signum != SIGCHLD)
  256.       signal(signum, SIG_IGN);
  257.   } else
  258.     signal(signum, handler);
  259. }
  260. void 
  261. catchsigs(bool ignore){
  262. #if !defined NDB_WIN32 && !defined NDB_SOFTOSE && !defined NDB_OSE 
  263.   static const int signals_shutdown[] = {
  264. #ifdef SIGBREAK
  265.     SIGBREAK,
  266. #endif
  267.     SIGHUP,
  268.     SIGINT,
  269. #if defined SIGPWR
  270.     SIGPWR,
  271. #elif defined SIGINFO
  272.     SIGINFO,
  273. #endif
  274.     SIGQUIT,
  275.     SIGTERM,
  276. #ifdef SIGTSTP
  277.     SIGTSTP,
  278. #endif
  279.     SIGTTIN,
  280.     SIGTTOU
  281.   };
  282.   static const int signals_error[] = {
  283.     SIGABRT,
  284.     SIGALRM,
  285. #ifdef SIGBUS
  286.     SIGBUS,
  287. #endif
  288.     SIGCHLD,
  289.     SIGFPE,
  290.     SIGILL,
  291. #ifdef SIGIO
  292.     SIGIO,
  293. #endif
  294. #ifdef SIGPOLL
  295.     SIGPOLL,
  296. #endif
  297.     SIGSEGV,
  298. #ifdef SIGTRAP
  299.     SIGTRAP
  300. #endif
  301.   };
  302.   static const int signals_ignore[] = {
  303.     SIGPIPE
  304.   };
  305.   size_t i;
  306.   for(i = 0; i < sizeof(signals_shutdown)/sizeof(signals_shutdown[0]); i++)
  307.     handler_register(signals_shutdown[i], handler_shutdown, ignore);
  308.   for(i = 0; i < sizeof(signals_error)/sizeof(signals_error[0]); i++)
  309.     handler_register(signals_error[i], handler_error, ignore);
  310.   for(i = 0; i < sizeof(signals_ignore)/sizeof(signals_ignore[0]); i++)
  311.     handler_register(signals_ignore[i], SIG_IGN, ignore);
  312. #endif
  313. }
  314. extern "C"
  315. void 
  316. handler_shutdown(int signum){
  317.   g_eventLogger.info("Received signal %d. Performing stop.", signum);
  318.   globalData.theRestartFlag = perform_stop;
  319. }
  320. extern "C"
  321. void 
  322. handler_error(int signum){
  323.   // only let one thread run shutdown
  324.   static long thread_id= 0;
  325.   if (thread_id != 0 && thread_id == my_thread_id())
  326.   {
  327.     // Shutdown thread received signal
  328. #ifndef NDB_WIN32
  329. signal(signum, SIG_DFL);
  330.     kill(getpid(), signum);
  331. #endif
  332.     while(true)
  333.       NdbSleep_MilliSleep(10);
  334.   }
  335.   if(theShutdownMutex && NdbMutex_Trylock(theShutdownMutex) != 0)
  336.     while(true)
  337.       NdbSleep_MilliSleep(10);
  338.   thread_id= my_thread_id();
  339.   g_eventLogger.info("Received signal %d. Running error handler.", signum);
  340.   // restart the system
  341.   char errorData[40];
  342.   BaseString::snprintf(errorData, 40, "Signal %d received", signum);
  343.   ERROR_SET_SIGNAL(fatal, 0, errorData, __FILE__);
  344. }
  345. extern "C"
  346. void 
  347. handler_sigusr1(int signum)
  348. {
  349.   if (!failed_startup_flag)
  350.   {
  351.     failed_startups++;
  352.     failed_startup_flag = true;
  353.   }
  354.   g_eventLogger.info("Angel received ndbd startup failure count %u.", failed_startups);
  355. }