16 #include <ndb_global.h>
19 #include <NdbConfig.h>
21 #include <portlib/NdbDir.hpp>
22 #include <NdbAutoPtr.hpp>
23 #include <portlib/NdbNuma.h>
25 #include "vm/SimBlockList.hpp"
26 #include "vm/WatchDog.hpp"
27 #include "vm/ThreadConfig.hpp"
28 #include "vm/Configuration.hpp"
32 #include <ConfigRetriever.hpp>
33 #include <LogLevel.hpp>
35 #if defined NDB_SOLARIS
36 #include <sys/processor.h>
39 #include <EventLogger.hpp>
49 GetSystemInfo(&sinfo);
50 processors = sinfo.dwNumberOfProcessors;
52 if(ERROR_SUCCESS==RegOpenKeyEx
54 TEXT(
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
55 0, KEY_READ, &hKey)) {
57 DWORD cbData =
sizeof(dwMHz);
58 if(ERROR_SUCCESS==RegQueryValueEx(hKey,
59 "~MHz", 0, 0, (LPBYTE)&dwMHz, &cbData)) {
64 #elif defined NDB_SOLARIS
66 processor_info_t pinfo; memset(&pinfo, 0,
sizeof(pinfo));
68 while(processors < 16 && pid < 256){
69 if(!processor_info(pid++, &pinfo))
72 speed = pinfo.pi_clock;
76 g_eventLogger->
info(
"NDB Cluster -- DB node %d", globalData.ownId);
77 g_eventLogger->
info(
"%s --", NDB_VERSION_STRING);
79 g_eventLogger->
info(
"NDB is running on a machine with %d processor(s) at %d MHz",
84 Uint32 t = config.timeBetweenWatchDogCheck();
85 g_eventLogger->
info(
"WatchDog timer is set to %d ms", t);
94 ndb_mgm_get_int64_parameter(p, CFG_DB_INDEX_MEM, &accmem);
97 accmem /= GLOBAL_PAGE_SIZE;
99 Uint32 lqhInstances = 1;
100 if (globalData.isNdbMtLqh)
102 lqhInstances = globalData.ndbMtLqhWorkers;
105 accmem += lqhInstances * (32 / 4);
107 return Uint32(accmem);
111 init_global_memory_manager(
EmulatorData &ed, Uint32 *watchCounter)
114 ed.theConfiguration->getOwnConfigIterator();
121 ndb_mgm_get_int_parameter(p, CFG_DB_NUMA, &numa);
124 int res = NdbNuma_setInterleaved();
125 g_eventLogger->
info(
"numa_set_interleave_mask(numa_all_nodes) : %s",
126 res == 0 ?
"OK" :
"no numa support");
129 Uint64 shared_mem = 8*1024*1024;
130 ndb_mgm_get_int64_parameter(p, CFG_DB_SGA, &shared_mem);
131 Uint32 shared_pages = Uint32(shared_mem /= GLOBAL_PAGE_SIZE);
134 if (ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tupmem))
136 g_eventLogger->
alert(
"Failed to get CFG_TUP_PAGE parameter from "
145 Uint32 accpages = compute_acc_32kpages(p);
149 Uint32 lqhInstances = 1;
150 if (globalData.isNdbMtLqh)
152 lqhInstances = globalData.ndbMtLqhWorkers;
160 rl.m_resource_id = RG_DATAMEM;
164 Uint32 maxopen = 4 * 4;
165 Uint32 filebuffer = NDB_FILE_BUFFER_SIZE;
166 Uint32 filepages = (filebuffer / GLOBAL_PAGE_SIZE) * maxopen;
173 ndb_mgm_get_int_parameter(p, CFG_DB_REDO_BUFFER,
178 redomem /= GLOBAL_PAGE_SIZE;
179 Uint32 tmp = redomem & 15;
182 redomem += (16 - tmp);
185 filepages += lqhInstances * redomem;
192 rl.m_min = filepages;
193 rl.m_max = filepages;
194 rl.m_resource_id = RG_FILE_BUFFERS;
198 Uint32 jbpages = compute_jb_pages(&ed);
204 rl.m_resource_id = RG_JOBBUFFER;
209 if (globalTransporterRegistry.get_using_default_send_buffer() ==
false)
212 sbpages = Uint32((mem + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE);
216 rl.m_resource_id = RG_TRANSPORTER_BUFFERS;
220 Uint32 pgman_pages = 0;
225 Uint64 page_buffer = 64*1024*1024;
226 ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY,&page_buffer);
229 pages += Uint32(page_buffer / GLOBAL_PAGE_SIZE);
230 pages += LCP_RESTORE_BUFFER * lqhInstances;
232 pgman_pages += pages;
236 rl.m_min = pgman_pages;
237 rl.m_max = pgman_pages;
238 rl.m_resource_id = RG_DISK_PAGE_BUFFER;
242 Uint32 sum = shared_pages + tupmem + filepages + jbpages + sbpages +
250 rl.m_resource_id = 0;
254 if (!ed.m_mem_manager->
init(watchCounter))
265 g_eventLogger->
alert(
"Malloc (%lld bytes) for %s and %s failed, exiting",
266 Uint64(shared_mem + tupmem) * GLOBAL_PAGE_SIZE,
267 dm.m_name, sga.m_name);
271 Uint32 late_alloc = 0;
272 ndb_mgm_get_int_parameter(p, CFG_DB_LATE_ALLOC,
276 ndb_mgm_get_int_parameter(p, CFG_DB_MEMLOCK, &memlock);
283 Uint32 rg[] = { RG_JOBBUFFER, RG_FILE_BUFFERS, RG_TRANSPORTER_BUFFERS, 0 };
284 ed.m_mem_manager->
map(watchCounter, memlock, rg);
288 ed.m_mem_manager->
map(watchCounter, memlock);
299 globalData.isNdbMt = SimulatedBlock::isMultiThreaded();
300 if (!globalData.isNdbMt)
302 ndbout <<
"NDBMT: non-mt" << endl;
306 THRConfig & conf = ed.theConfiguration->m_thr_config;
308 Uint32 threadcount = conf.getThreadCount();
309 ndbout <<
"NDBMT: MaxNoOfExecutionThreads=" << threadcount << endl;
311 globalData.isNdbMtLqh =
true;
314 if (conf.getMtClassic())
316 globalData.isNdbMtLqh =
false;
320 if (!globalData.isNdbMtLqh)
323 Uint32 threads = conf.getThreadCount(THRConfig::T_LDM);
324 Uint32 workers = threads;
333 if (ndb_mgm_find(p, CFG_NODE_ID, globalData.ownId))
337 ndb_mgm_get_int_parameter(p, CFG_NDBMT_LQH_WORKERS, &workers);
344 p = NdbEnv_GetEnv(
"NDBMT_LQH_WORKERS", (
char*)0, 0);
350 ndbout <<
"NDBMT: workers=" << workers
351 <<
" threads=" << threads << endl;
353 assert(workers != 0 && workers <= MAX_NDBMT_LQH_WORKERS);
354 assert(threads != 0 && threads <= MAX_NDBMT_LQH_THREADS);
355 assert(workers % threads == 0);
357 globalData.ndbMtLqhWorkers = workers;
358 globalData.ndbMtLqhThreads = threads;
379 static FILE *angel_info_w = NULL;
382 writeChildInfo(
const char *token,
int val)
384 fprintf(angel_info_w,
"%s=%d\n", token, val);
385 fflush(angel_info_w);
389 childReportSignal(
int signum)
391 writeChildInfo(
"signal", signum);
395 childExit(
int error_code,
int exit_code, Uint32 currentStartPhase)
397 writeChildInfo(
"error", error_code);
398 writeChildInfo(
"sphase", currentStartPhase);
399 fprintf(angel_info_w,
"\n");
400 fclose(angel_info_w);
401 ndbd_exit(exit_code);
405 childAbort(
int error_code,
int exit_code, Uint32 currentStartPhase)
407 writeChildInfo(
"error", error_code);
408 writeChildInfo(
"sphase", currentStartPhase);
409 fprintf(angel_info_w,
"\n");
410 fclose(angel_info_w);
415 ndbd_exit(exit_code);
417 signal(SIGABRT, SIG_DFL);
424 handler_shutdown(
int signum){
425 g_eventLogger->
info(
"Received signal %d. Performing stop.", signum);
426 childReportSignal(signum);
427 globalData.theRestartFlag = perform_stop;
430 extern NdbMutex * theShutdownMutex;
434 handler_error(
int signum){
436 static bool handling_error =
false;
437 static pthread_t thread_id;
439 if (handling_error &&
440 pthread_equal(thread_id, pthread_self()))
444 signal(signum, SIG_DFL);
445 kill(getpid(), signum);
448 NdbSleep_MilliSleep(10);
450 if(theShutdownMutex && NdbMutex_Trylock(theShutdownMutex) != 0)
452 NdbSleep_MilliSleep(10);
454 thread_id = pthread_self();
455 handling_error =
true;
457 g_eventLogger->
info(
"Received signal %d. Running error handler.", signum);
458 childReportSignal(signum);
460 char errorData[64], *info= 0;
461 #ifdef HAVE_STRSIGNAL
462 info= strsignal(signum);
465 info ? info :
"No text for signal available");
466 ERROR_SET_SIGNAL(fatal, NDBD_EXIT_OS_SIGNAL_RECEIVED, errorData, __FILE__);
471 catchsigs(
bool foreground){
472 static const int signals_shutdown[] = {
482 #elif defined SIGINFO
498 static const int signals_error[] = {
520 static const int signals_ignore[] = {
525 for(i = 0; i <
sizeof(signals_shutdown)/
sizeof(signals_shutdown[0]); i++)
526 signal(signals_shutdown[i], handler_shutdown);
527 for(i = 0; i <
sizeof(signals_error)/
sizeof(signals_error[0]); i++)
528 signal(signals_error[i], handler_error);
529 for(i = 0; i <
sizeof(signals_ignore)/
sizeof(signals_ignore[0]); i++)
530 signal(signals_ignore[i], SIG_IGN);
534 signal(SIGTRAP, handler_error);
540 static HANDLE g_shutdown_event;
542 DWORD WINAPI shutdown_thread(LPVOID)
545 WaitForSingleObject(g_shutdown_event, INFINITE);
547 g_eventLogger->
info(
"Performing stop");
548 globalData.theRestartFlag = perform_stop;
555 ndbd_run(
bool foreground,
int report_fd,
556 const char* connect_str,
int force_nodeid,
const char* bind_address,
557 bool no_start,
bool initial,
bool initialstart,
558 unsigned allocated_nodeid)
562 char shutdown_event_name[32];
563 _snprintf(shutdown_event_name,
sizeof(shutdown_event_name),
564 "ndbd_shutdown_%d", GetCurrentProcessId());
566 g_shutdown_event = CreateEvent(NULL, TRUE, FALSE, shutdown_event_name);
567 if (g_shutdown_event == NULL)
569 g_eventLogger->
error(
"Failed to create shutdown event, error: %d",
574 HANDLE thread = CreateThread(NULL, 0, &shutdown_thread, NULL, 0, NULL);
577 g_eventLogger->
error(
"couldn't start shutdown thread, error: %d",
585 g_eventLogger->
info(
"Ndb started in foreground");
589 g_eventLogger->
debug(
"Opening report stream on fd: %d", report_fd);
591 if (!(angel_info_w = fdopen(report_fd,
"w")))
593 g_eventLogger->
error(
"Failed to open stream for reporting "
594 "to angel, error: %d (%s)", errno, strerror(errno));
601 const char* dev_null = IF_WIN(
"nul",
"/dev/null");
602 if (!(angel_info_w = fopen(dev_null,
"w")))
604 g_eventLogger->
error(
"Failed to open stream for reporting to "
605 "'%s', error: %d (%s)", dev_null, errno,
611 globalEmulatorData.
create();
613 Configuration* theConfig = globalEmulatorData.theConfiguration;
614 if(!theConfig->init(no_start, initial, initialstart))
616 g_eventLogger->
error(
"Failed to init Configuration");
623 if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
625 g_eventLogger->
warning(
"Cannot change directory to '%s', error: %d",
626 NdbConfig_get_path(NULL), errno);
632 if (get_multithreaded_config(globalEmulatorData))
635 systemInfo(* theConfig, * theConfig->m_logLevel);
637 NdbThread* pWatchdog = globalEmulatorData.theWatchDog->doStart();
647 globalEmulatorData.theWatchDog->registerWatchedThread(&watchCounter, 0);
648 if (init_global_memory_manager(globalEmulatorData, &watchCounter))
650 globalEmulatorData.theWatchDog->unregisterWatchedThread(0);
653 globalEmulatorData.theThreadConfig->init();
657 char *
buf= NdbConfig_SignalLogFileName(globalData.ownId);
659 FILE * signalLog = fopen(buf,
"a");
660 globalSignalLoggers.setOwnNodeId(globalData.ownId);
661 globalSignalLoggers.setOutputStream(signalLog);
662 #if 1 // to log startup
663 {
const char* p = NdbEnv_GetEnv(
"NDB_SIGNAL_LOG", (
char*)0, 0);
667 for (
char* q = buf; *q != 0; q++) *q = toupper(toascii(*q));
668 globalSignalLoggers.log(SignalLoggerManager::LogInOut, buf);
669 globalData.testOn = 1;
670 assert(signalLog != 0);
671 fprintf(signalLog,
"START\n");
679 globalEmulatorData.theSimBlockList->load(globalEmulatorData);
683 status = NdbThread_SetConcurrencyLevel(30);
686 catchsigs(foreground);
691 switch(globalData.theRestartFlag){
700 assert(
"Illegal state globalData.theRestartFlag" == 0);
705 if (!globalTransporterRegistry.start_service(*globalEmulatorData.m_socket_server)){
706 ndbout_c(
"globalTransporterRegistry.start_service() failed");
711 if(!globalTransporterRegistry.connect_client(
712 theConfig->get_config_retriever()->get_mgmHandlePtr()))
713 ERROR_SET(fatal, NDBD_EXIT_CONNECTION_SETUP_FAILED,
714 "Failed to convert mgm connection to a transporter",
717 NdbThread* pTrp = globalTransporterRegistry.start_clients();
720 ndbout_c(
"globalTransporterRegistry.start_clients() failed");
726 globalEmulatorData.theConfiguration->
addThread(pTrp, SocketClientThread);
727 globalEmulatorData.theConfiguration->
addThread(pWatchdog, WatchDogThread);
728 globalEmulatorData.theConfiguration->
addThread(pSockServ, SocketServerThread);
732 NdbThread *pThis = NdbThread_CreateObject(0);
733 Uint32 inx = globalEmulatorData.theConfiguration->
addThread(pThis,
735 globalEmulatorData.theThreadConfig->
ipControlLoop(pThis, inx);
736 globalEmulatorData.theConfiguration->removeThreadId(inx);
738 NdbShutdown(0, NST_Normal);
744 extern "C" my_bool opt_core;
747 extern Uint32 g_currentStartPhase;
749 int simulate_error_during_shutdown= 0;
752 NdbShutdown(
int error_code,
753 NdbShutdownType
type,
754 NdbRestartType restartType)
756 if(type == NST_ErrorInsert)
759 restartType = (NdbRestartType)
760 globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
761 if(restartType == NRT_Default)
763 type = NST_ErrorHandler;
764 globalEmulatorData.theConfiguration->stopOnError(
true);
768 if((type == NST_ErrorHandlerSignal) ||
769 (NdbMutex_Trylock(theShutdownMutex) == 0)){
770 globalData.theRestartFlag = perform_stop;
772 bool restart =
false;
774 if((type != NST_Normal &&
775 globalEmulatorData.theConfiguration->stopOnError() ==
false) ||
781 const char * shutting =
"shutting down";
784 shutting =
"restarting";
789 g_eventLogger->
info(
"Shutdown initiated");
792 g_eventLogger->
info(
"Watchdog %s system", shutting);
794 case NST_ErrorHandler:
795 g_eventLogger->
info(
"Error handler %s system", shutting);
797 case NST_ErrorHandlerSignal:
798 g_eventLogger->
info(
"Error handler signal %s system", shutting);
801 g_eventLogger->
info(
"Restarting system");
804 g_eventLogger->
info(
"Error handler %s system (unknown type: %u)",
805 shutting, (
unsigned)type);
806 type = NST_ErrorHandler;
810 const char * exitAbort = 0;
812 exitAbort =
"aborting";
814 exitAbort =
"exiting";
816 if(type == NST_Watchdog)
821 g_eventLogger->
info(
"Watchdog shutdown completed - %s", exitAbort);
824 childAbort(error_code, -1,g_currentStartPhase);
828 childExit(error_code, -1,g_currentStartPhase);
833 if (simulate_error_during_shutdown)
835 kill(getpid(), simulate_error_during_shutdown);
837 NdbSleep_MilliSleep(10);
841 globalEmulatorData.theWatchDog->doStop();
844 FILE * outputStream = globalSignalLoggers.setOutputStream(0);
845 if(outputStream != 0)
846 fclose(outputStream);
859 globalEmulatorData.m_socket_server->stopServer();
861 globalTransporterRegistry.stop_clients();
866 globalTransporterRegistry.stopSending();
875 if(type == NST_ErrorInsert && opt_core)
878 globalEmulatorData.theSimBlockList->unload();
879 NdbMutex_Unlock(theShutdownMutex);
883 if(type != NST_Normal && type != NST_Restart)
885 g_eventLogger->
info(
"Error handler shutdown completed - %s", exitAbort);
888 childAbort(error_code, -1,g_currentStartPhase);
892 childExit(error_code, -1,g_currentStartPhase);
899 if(type == NST_Restart){
900 childExit(error_code, restartType,g_currentStartPhase);
903 g_eventLogger->
info(
"Shutdown completed - exiting");
914 if (type== NST_Watchdog)
916 g_eventLogger->
info(
"Watchdog is killing system the hard way");
918 childAbort(error_code, -1,g_currentStartPhase);
920 childExit(error_code, -1, g_currentStartPhase);
925 NdbSleep_MilliSleep(10);