18 #include <ndb_global.h>
21 #include <ndbd_exit_codes.h>
23 #include <util/BaseString.hpp>
24 #include <util/Vector.hpp>
25 #include <kernel/BlockNumbers.h>
49 bool execute(
const char *line,
int try_reconnect = -1,
50 bool interactive =
true,
int *error = NULL);
54 bool execute_impl(
const char *line,
bool interactive);
65 int analyseAfterFirstToken(
int processId,
char* allAfterFirstTokenCstr);
69 int *node_ids,
int no_of_nodes);
79 bool parseBlockSpecification(
const char* allAfterLog,
93 int executeHelp(
char* parameters);
94 int executeShow(
char* parameters);
95 int executePurge(
char* parameters);
96 int executeConnect(
char* parameters,
bool interactive);
97 int executeShutdown(
char* parameters);
98 void executeClusterLog(
char* parameters);
101 int executeStop(
int processId,
const char* parameters,
bool all);
102 int executeEnterSingleUser(
char* parameters);
103 int executeExitSingleUser(
char* parameters);
104 int executeStart(
int processId,
const char* parameters,
bool all);
105 int executeRestart(
int processId,
const char* parameters,
bool all);
106 int executeLogLevel(
int processId,
const char* parameters,
bool all);
107 int executeError(
int processId,
const char* parameters,
bool all);
108 int executeLog(
int processId,
const char* parameters,
bool all);
109 int executeTestOn(
int processId,
const char* parameters,
bool all);
110 int executeTestOff(
int processId,
const char* parameters,
bool all);
111 int executeStatus(
int processId,
const char* parameters,
bool all);
112 int executeEventReporting(
int processId,
const char* parameters,
bool all);
113 int executeDumpState(
int processId,
const char* parameters,
bool all);
114 int executeReport(
int processId,
const char* parameters,
bool all);
116 int executeAbortBackup(
char * parameters);
118 int *node_ids,
int no_of_nodes);
120 int *node_ids,
int no_of_nodes);
122 int *node_ids,
int no_of_nodes);
123 int executeCreateNodeGroup(
char* parameters);
124 int executeDropNodeGroup(
char* parameters);
126 bool connect(
bool interactive);
127 void disconnect(
void);
138 const char * command;
145 int executeForAll(
const char * cmd,
151 const char *m_constr;
157 NdbMutex *m_print_mutex;
160 NdbMutex* print_mutex;
166 #include "ndb_mgmclient.hpp"
168 Ndb_mgmclient::Ndb_mgmclient(
const char *host,
int verbose)
172 Ndb_mgmclient::~Ndb_mgmclient()
176 bool Ndb_mgmclient::execute(
const char *line,
int try_reconnect,
177 bool interactive,
int *error)
179 return m_cmd->
execute(line, try_reconnect, interactive, error);
186 #include <mgmapi_debug.h>
188 #include <util/version.h>
189 #include <util/NdbAutoPtr.hpp>
190 #include <util/NdbOut.hpp>
192 #include <portlib/NdbSleep.h>
193 #include <portlib/NdbThread.h>
195 #include <debugger/EventLogger.hpp>
196 #include <signaldata/SetLogLevelOrd.hpp>
201 static const char* helpText =
202 "---------------------------------------------------------------------------\n"
203 " NDB Cluster -- Management Client -- Help\n"
204 "---------------------------------------------------------------------------\n"
205 "HELP Print help text\n"
206 "HELP COMMAND Print detailed help for COMMAND(e.g. SHOW)\n"
207 #ifdef VM_TRACE // DEBUG ONLY
208 "HELP DEBUG Help for debug compiled version\n"
210 "SHOW Print information about cluster\n"
211 "CREATE NODEGROUP <id>,<id>... Add a Nodegroup containing nodes\n"
212 "DROP NODEGROUP <NG> Drop nodegroup with id NG\n"
213 "START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
214 "START BACKUP [<backup id>] [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
215 "START BACKUP [<backup id>] [SNAPSHOTSTART | SNAPSHOTEND] [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
216 " Start backup (default WAIT COMPLETED,SNAPSHOTEND)\n"
217 "ABORT BACKUP <backup id> Abort backup\n"
218 "SHUTDOWN Shutdown all processes in cluster\n"
219 "CLUSTERLOG ON [<severity>] ... Enable Cluster logging\n"
220 "CLUSTERLOG OFF [<severity>] ... Disable Cluster logging\n"
221 "CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off\n"
222 "CLUSTERLOG INFO Print cluster log information\n"
223 "<id> START Start data node (started with -n)\n"
224 "<id> RESTART [-n] [-i] [-a] [-f] Restart data or management server node\n"
225 "<id> STOP [-a] [-f] Stop data or management server node\n"
226 "ENTER SINGLE USER MODE <id> Enter single user mode\n"
227 "EXIT SINGLE USER MODE Exit single user mode\n"
228 "<id> STATUS Print status\n"
229 "<id> CLUSTERLOG {<category>=<level>}+ Set log level for cluster log\n"
230 "PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n"
231 "CONNECT [<connectstring>] Connect to management server (reconnect if already connected)\n"
232 "<id> REPORT <report-type> Display report for <report-type>\n"
233 "QUIT Quit management client\n"
236 static const char* helpTextShow =
237 "---------------------------------------------------------------------------\n"
238 " NDB Cluster -- Management Client -- Help for SHOW command\n"
239 "---------------------------------------------------------------------------\n"
240 "SHOW Print information about cluster\n\n"
241 "SHOW Print information about cluster.The status reported is from\n"
242 " the perspective of the data nodes. API and Management Server nodes\n"
243 " are only reported as connected once the data nodes have started.\n"
246 static const char* helpTextHelp =
247 "---------------------------------------------------------------------------\n"
248 " NDB Cluster -- Management Client -- Help for HELP command\n"
249 "---------------------------------------------------------------------------\n"
250 "HELP List available commands of NDB Cluster Management Client\n\n"
251 "HELP List available commands.\n"
254 static const char* helpTextBackup =
255 "---------------------------------------------------------------------------\n"
256 " NDB Cluster -- Management Client -- Help for BACKUP command\n"
257 "---------------------------------------------------------------------------\n"
258 "BACKUP A backup is a snapshot of the database at a given time. \n"
259 " The backup consists of three main parts:\n\n"
260 " Metadata: the names and definitions of all database tables. \n"
261 " Table records: the data actually stored in the database tables \n"
262 " at the time that the backup was made.\n"
263 " Transaction log: a sequential record telling how \n"
264 " and when data was stored in the database.\n\n"
265 " Backups are stored on each data node in the cluster that \n"
266 " participates in the backup.\n\n"
267 " The cluster log records backup related events (such as \n"
268 " backup started, aborted, finished).\n"
271 static const char* helpTextStartBackup =
272 "---------------------------------------------------------------------------\n"
273 " NDB Cluster -- Management Client -- Help for START BACKUP command\n"
274 "---------------------------------------------------------------------------\n"
275 "START BACKUP Start a cluster backup\n\n"
276 "START BACKUP [<backup id>] [SNAPSHOTSTART | SNAPSHOTEND] [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
277 " Start a backup for the cluster.\n"
278 " Each backup gets an ID number that is reported to the\n"
279 " user. This ID number can help you find the backup on the\n"
280 " file system, or ABORT BACKUP if you wish to cancel a \n"
282 " You can also start specified backup using START BACKUP <backup id> \n\n"
284 " Start a specified backup using <backup id> as bakcup ID number.\n"
286 " Backup snapshot is taken around the time the backup is started.\n"
288 " Backup snapshot is taken around the time the backup is completed.\n"
290 " Start a cluster backup and return immediately.\n"
291 " The management client will return control directly\n"
292 " to the user without waiting for the backup\n"
293 " to have started.\n"
294 " The status of the backup is recorded in the Cluster log.\n"
296 " Start a cluster backup and return until the backup has\n"
297 " started. The management client will wait for the backup \n"
298 " to have started before returning control to the user.\n"
300 " Start a cluster backup and return until the backup has\n"
301 " completed. The management client will wait for the backup\n"
302 " to complete before returning control to the user.\n"
305 static const char* helpTextAbortBackup =
306 "---------------------------------------------------------------------------\n"
307 " NDB Cluster -- Management Client -- Help for ABORT BACKUP command\n"
308 "---------------------------------------------------------------------------\n"
309 "ABORT BACKUP Abort a cluster backup\n\n"
310 "ABORT BACKUP <backup id> \n"
311 " Abort a backup that is already in progress.\n"
312 " The backup id can be seen in the cluster log or in the\n"
313 " output of the START BACKUP command.\n"
316 static const char* helpTextShutdown =
317 "---------------------------------------------------------------------------\n"
318 " NDB Cluster -- Management Client -- Help for SHUTDOWN command\n"
319 "---------------------------------------------------------------------------\n"
320 "SHUTDOWN Shutdown the cluster\n\n"
321 "SHUTDOWN Shutdown the data nodes and management nodes.\n"
322 " MySQL Servers and NDBAPI nodes are currently not \n"
323 " shut down by issuing this command.\n"
326 static const char* helpTextClusterlogOn =
327 "---------------------------------------------------------------------------\n"
328 " NDB Cluster -- Management Client -- Help for CLUSTERLOG ON command\n"
329 "---------------------------------------------------------------------------\n"
330 "CLUSTERLOG ON Enable Cluster logging\n\n"
331 "CLUSTERLOG ON [<severity>] ... \n"
332 " Turn the cluster log on.\n"
333 " It tells management server which severity levels\n"
334 " messages will be logged.\n\n"
335 " <severity> can be any one of the following values:\n"
336 " ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
339 static const char* helpTextClusterlogOff =
340 "---------------------------------------------------------------------------\n"
341 " NDB Cluster -- Management Client -- Help for CLUSTERLOG OFF command\n"
342 "---------------------------------------------------------------------------\n"
343 "CLUSTERLOG OFF Disable Cluster logging\n\n"
344 "CLUSTERLOG OFF [<severity>] ... \n"
345 " Turn the cluster log off.\n"
346 " It tells management server which serverity\n"
347 " levels logging will be disabled.\n\n"
348 " <severity> can be any one of the following values:\n"
349 " ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
352 static const char* helpTextClusterlogToggle =
353 "---------------------------------------------------------------------------\n"
354 " NDB Cluster -- Management Client -- Help for CLUSTERLOG TOGGLE command\n"
355 "---------------------------------------------------------------------------\n"
356 "CLUSTERLOG TOGGLE Toggle severity filter on/off\n\n"
357 "CLUSTERLOG TOGGLE [<severity>] ... \n"
358 " Toggle serverity filter on/off.\n"
359 " If a serverity level is already enabled,then it will\n"
360 " be disabled after you use the command,vice versa.\n\n"
361 " <severity> can be any one of the following values:\n"
362 " ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
365 static const char* helpTextClusterlogInfo =
366 "---------------------------------------------------------------------------\n"
367 " NDB Cluster -- Management Client -- Help for CLUSTERLOG INFO command\n"
368 "---------------------------------------------------------------------------\n"
369 "CLUSTERLOG INFO Print cluster log information\n\n"
370 "CLUSTERLOG INFO Display which severity levels have been enabled,\n"
371 " see HELP CLUSTERLOG for list of the severity levels.\n"
374 static const char* helpTextStart =
375 "---------------------------------------------------------------------------\n"
376 " NDB Cluster -- Management Client -- Help for START command\n"
377 "---------------------------------------------------------------------------\n"
378 "START Start data node (started with -n)\n\n"
379 "<id> START Start the data node identified by <id>.\n"
380 " Only starts data nodes that have not\n"
381 " yet joined the cluster. These are nodes\n"
382 " launched or restarted with the -n(--nostart)\n"
384 " It does not launch the ndbd process on a remote\n"
388 static const char* helpTextRestart =
389 "---------------------------------------------------------------------------\n"
390 " NDB Cluster -- Management Client -- Help for RESTART command\n"
391 "---------------------------------------------------------------------------\n"
392 "RESTART Restart data or management server node\n\n"
393 "<id> RESTART [-n] [-i] [-a] [-f]\n"
394 " Restart the data or management node <id>(or All data nodes).\n\n"
395 " -n (--nostart) restarts the node but does not\n"
396 " make it join the cluster. Use '<id> START' to\n"
397 " join the node to the cluster.\n\n"
398 " -i (--initial) perform initial start.\n"
399 " This cleans the file system (ndb_<id>_fs)\n"
400 " and the node will copy data from another node\n"
401 " in the same node group during start up.\n\n"
402 " Consult the documentation before using -i.\n\n"
403 " INCORRECT USE OF -i WILL CAUSE DATA LOSS!\n\n"
404 " -a Aborts the node, not syncing GCP.\n\n"
405 " -f Force restart even if that would mean the\n"
406 " whole cluster would need to be restarted\n"
409 static const char* helpTextStop =
410 "---------------------------------------------------------------------------\n"
411 " NDB Cluster -- Management Client -- Help for STOP command\n"
412 "---------------------------------------------------------------------------\n"
413 "STOP Stop data or management server node\n\n"
414 "<id> STOP [-a] [-f]\n"
415 " Stop the data or management server node <id>.\n\n"
416 " ALL STOP will just stop all data nodes.\n\n"
417 " If you desire to also shut down management servers,\n"
418 " use SHUTDOWN instead.\n\n"
419 " -a Aborts the node, not syncing GCP.\n\n"
420 " -f Force stop even if that would mean the\n"
421 " whole cluster would need to be stopped\n"
424 static const char* helpTextEnterSingleUserMode =
425 "---------------------------------------------------------------------------\n"
426 " NDB Cluster -- Management Client -- Help for ENTER SINGLE USER MODE command\n"
427 "---------------------------------------------------------------------------\n"
428 "ENTER SINGLE USER MODE Enter single user mode\n\n"
429 "ENTER SINGLE USER MODE <id> \n"
430 " Enters single-user mode, whereby only the MySQL Server or NDBAPI\n"
431 " node identified by <id> is allowed to access the database. \n"
434 static const char* helpTextExitSingleUserMode =
435 "---------------------------------------------------------------------------\n"
436 " NDB Cluster -- Management Client -- Help for EXIT SINGLE USER MODE command\n"
437 "---------------------------------------------------------------------------\n"
438 "EXIT SINGLE USER MODE Exit single user mode\n\n"
439 "EXIT SINGLE USER MODE \n"
440 " Exits single-user mode, allowing all SQL nodes \n"
441 " (that is, all running mysqld processes) to access the database. \n"
444 static const char* helpTextStatus =
445 "---------------------------------------------------------------------------\n"
446 " NDB Cluster -- Management Client -- Help for STATUS command\n"
447 "---------------------------------------------------------------------------\n"
448 "STATUS Print status\n\n"
449 "<id> STATUS Displays status information for the data node <id>\n"
450 " or for All data nodes. \n\n"
454 " When a node is starting, the start phase will be\n"
456 " Start Phase Meaning\n"
457 " 1 Clear the cluster file system(ndb_<id>_fs). \n"
458 " This stage occurs only when the --initial option \n"
459 " has been specified.\n"
460 " 2 This stage sets up Cluster connections, establishes \n"
461 " inter-node communications and starts Cluster heartbeats.\n"
462 " 3 The arbitrator node is elected.\n"
463 " 4 Initializes a number of internal cluster variables.\n"
464 " 5 For an initial start or initial node restart,\n"
465 " the redo log files are created.\n"
466 " 6 If this is an initial start, create internal system tables.\n"
467 " 7 Update internal variables. \n"
468 " 8 In a system restart, rebuild all indexes.\n"
469 " 9 Update internal variables. \n"
470 " 10 The node can be connected by APIs and can receive events.\n"
471 " 11 At this point,event delivery is handed over to\n"
472 " the node joining the cluster.\n"
473 "(see manual for more information)\n"
476 static const char* helpTextClusterlog =
477 "---------------------------------------------------------------------------\n"
478 " NDB Cluster -- Management Client -- Help for CLUSTERLOG command\n"
479 "---------------------------------------------------------------------------\n"
480 "CLUSTERLOG Set log level for cluster log\n\n"
481 " <id> CLUSTERLOG {<category>=<level>}+ \n"
482 " Logs <category> events with priority less than \n"
483 " or equal to <level> in the cluster log.\n\n"
484 " <category> can be any one of the following values:\n"
485 " STARTUP, SHUTDOWN, STATISTICS, CHECKPOINT, NODERESTART,\n"
486 " CONNECTION, ERROR, INFO, CONGESTION, DEBUG, or BACKUP. \n\n"
487 " <level> is represented by one of the numbers \n"
488 " from 1 to 15 inclusive, where 1 indicates 'most important' \n"
489 " and 15 'least important'.\n\n"
490 " <severity> can be any one of the following values:\n"
491 " ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
495 static const char* helpTextPurgeStaleSessions =
496 "---------------------------------------------------------------------------\n"
497 " NDB Cluster -- Management Client -- Help for PURGE STALE SESSIONS command\n"
498 "---------------------------------------------------------------------------\n"
499 "PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n\n"
500 "PURGE STALE SESSIONS \n"
501 " Running this statement forces all reserved \n"
502 " node IDs to be checked; any that are not \n"
503 " being used by nodes acutally connected to \n"
504 " the cluster are then freed.\n\n"
505 " This command is not normally needed, but may be\n"
506 " required in some situations where failed nodes \n"
507 " cannot rejoin the cluster due to failing to\n"
508 " allocate a node id.\n"
511 static const char* helpTextConnect =
512 "---------------------------------------------------------------------------\n"
513 " NDB Cluster -- Management Client -- Help for CONNECT command\n"
514 "---------------------------------------------------------------------------\n"
515 "CONNECT Connect to management server (reconnect if already connected)\n\n"
516 "CONNECT [<connectstring>] \n"
517 " Connect to management server.\n"
518 " The optional parameter connectstring specifies the \n"
519 " connect string to user.\n\n"
520 " A connect string may be:\n"
523 " mgm1:port,mgm2:port\n"
524 " With multiple management servers comma separated.\n"
525 " The management client with try to connect to the \n"
526 " management servers in the order they are listed.\n\n"
527 " If no connect string is specified, the default \n"
531 static const char* helpTextReport =
532 "---------------------------------------------------------------------------\n"
533 " NDB Cluster -- Management Client -- Help for REPORT command\n"
534 "---------------------------------------------------------------------------\n"
535 "REPORT Displays a report of type <report-type> for the specified data \n"
536 " node, or for all data nodes using ALL\n"
538 static void helpTextReportFn();
540 static const char* helpTextQuit =
541 "---------------------------------------------------------------------------\n"
542 " NDB Cluster -- Management Client -- Help for QUIT command\n"
543 "---------------------------------------------------------------------------\n"
544 "QUIT Quit management client\n\n"
545 "QUIT Terminates the management client. \n"
549 #ifdef VM_TRACE // DEBUG ONLY
550 static const char* helpTextDebug =
551 "---------------------------------------------------------------------------\n"
552 " NDB Cluster -- Management Client -- Help for Debugging (Internal use only)\n"
553 "---------------------------------------------------------------------------\n"
554 "SHOW PROPERTIES Print config properties object\n"
555 "<id> LOGLEVEL {<category>=<level>}+ Set log level\n"
557 "<id> ERROR <errorNo> Inject error into NDB node\n"
559 "<id> LOG [BLOCK = {ALL|<block>+}] Set logging on in & out signals\n"
560 "<id> TESTON Start signal logging\n"
561 "<id> TESTOFF Stop signal logging\n"
562 "<id> DUMP <arg> Dump system state to cluster.log\n"
564 "<id> = ALL | Any database node id\n"
573 {
"SHOW", helpTextShow, NULL},
574 {
"HELP", helpTextHelp, NULL},
575 {
"BACKUP", helpTextBackup, NULL},
576 {
"START BACKUP", helpTextStartBackup, NULL},
577 {
"START BACKUP NOWAIT", helpTextStartBackup, NULL},
578 {
"START BACKUP WAIT STARTED", helpTextStartBackup, NULL},
579 {
"START BACKUP WAIT", helpTextStartBackup, NULL},
580 {
"START BACKUP WAIT COMPLETED", helpTextStartBackup, NULL},
581 {
"ABORT BACKUP", helpTextAbortBackup, NULL},
582 {
"SHUTDOWN", helpTextShutdown, NULL},
583 {
"CLUSTERLOG ON", helpTextClusterlogOn, NULL},
584 {
"CLUSTERLOG OFF", helpTextClusterlogOff, NULL},
585 {
"CLUSTERLOG TOGGLE", helpTextClusterlogToggle, NULL},
586 {
"CLUSTERLOG INFO", helpTextClusterlogInfo, NULL},
587 {
"START", helpTextStart, NULL},
588 {
"RESTART", helpTextRestart, NULL},
589 {
"STOP", helpTextStop, NULL},
590 {
"ENTER SINGLE USER MODE", helpTextEnterSingleUserMode, NULL},
591 {
"EXIT SINGLE USER MODE", helpTextExitSingleUserMode, NULL},
592 {
"STATUS", helpTextStatus, NULL},
593 {
"CLUSTERLOG", helpTextClusterlog, NULL},
594 {
"PURGE STALE SESSIONS", helpTextPurgeStaleSessions, NULL},
595 {
"CONNECT", helpTextConnect, NULL},
596 {
"REPORT", helpTextReport, helpTextReportFn},
597 {
"QUIT", helpTextQuit, NULL},
598 #ifdef VM_TRACE // DEBUG ONLY
599 {
"DEBUG", helpTextDebug, NULL},
605 convert(
const char* s,
int& val) {
615 long v = strtol(s, &p, 10);
619 if (p != &s[strlen(s)])
637 m_print_mutex= NdbMutex_Create();
643 CommandInterpreter::~CommandInterpreter()
646 NdbMutex_Destroy(m_print_mutex);
650 emptyString(
const char* s)
656 for (
unsigned int i = 0;
i < strlen(s); ++
i) {
657 if (! isspace(s[
i])) {
666 CommandInterpreter::printError()
670 ndbout_c(
"* %5d: %s",
674 if (ndb_mgm_check_connection(m_mgmsrv))
684 #define make_uint64(a,b) (((Uint64)(a)) + (((Uint64)(b)) << 32))
685 #define Q64(a) make_uint64(event->EVENT.a ## _lo, event->EVENT.a ## _hi)
686 #define R event->source_nodeid
687 #define Q(a) event->EVENT.a
688 #define QVERSION getMajor(Q(version)), getMinor(Q(version)), getBuild(Q(version))
689 #define NDB_LE_(a) NDB_LE_ ## a
693 switch (event->
type) {
698 #define EVENT BackupStarted
700 ndbout_c(
"Node %u: Backup %u started from node %d",
701 R, Q(backup_id), Q(starting_node));
704 #define EVENT BackupStatus
706 if (Q(starting_node))
707 ndbout_c(
"Node %u: Local backup status: backup %u started from node %u\n"
708 " #Records: %llu #LogRecords: %llu\n"
709 " Data: %llu bytes Log: %llu bytes", R,
717 ndbout_c(
"Node %u: Backup not started", R);
720 #define EVENT BackupFailedToStart
722 ndbout_c(
"Node %u: Backup request from %d failed to start. Error: %d",
723 R, Q(starting_node), Q(error));
726 #define EVENT BackupCompleted
728 ndbout_c(
"Node %u: Backup %u started from node %u completed\n"
729 " StartGCP: %u StopGCP: %u\n"
730 " #Records: %u #LogRecords: %u\n"
731 " Data: %u bytes Log: %u bytes", R,
732 Q(backup_id), Q(starting_node),
733 Q(start_gci), Q(stop_gci),
734 Q(n_records), Q(n_log_records),
735 Q(n_bytes), Q(n_log_bytes));
738 #define EVENT BackupAborted
740 ndbout_c(
"Node %u: Backup %u started from %d has been aborted. Error: %d",
741 R, Q(backup_id), Q(starting_node), Q(error));
747 #define EVENT NDBStartStarted
749 ndbout_c(
"Node %u: Start initiated (version %d.%d.%d)",
753 #define EVENT NDBStartCompleted
755 ndbout_c(
"Node %u: Started (version %d.%d.%d)",
759 #define EVENT NDBStopStarted
761 ndbout_c(
"Node %u: %s shutdown initiated", R,
762 (Q(stoptype) == 1 ?
"Cluster" :
"Node"));
765 #define EVENT NDBStopCompleted
770 getRestartAction(Q(action), action_str);
772 signum_str.appfmt(
" Initiated by signal %d.",
774 ndbout_c(
"Node %u: Node shutdown completed%s.%s",
775 R, action_str.c_str(), signum_str.c_str());
779 #define EVENT NDBStopForced
785 int signum = Q(signum);
786 int error = Q(error);
787 int sphase = Q(sphase);
788 int extra = Q(extra);
789 getRestartAction(Q(action), action_str);
791 reason_str.appfmt(
" Initiated by signal %d.", signum);
794 ndbd_exit_classification cl;
796 const char *
msg = ndbd_exit_message(error, &cl);
797 const char *cl_msg = ndbd_exit_classification_message(cl, &st);
798 const char *st_msg = ndbd_exit_status_message(st);
799 reason_str.appfmt(
" Caused by error %d: \'%s(%s). %s\'.",
800 error, msg, cl_msg, st_msg);
802 reason_str.appfmt(
" (extra info %d)", extra);
805 sphase_str.appfmt(
" Occured during startphase %u.", sphase);
806 ndbout_c(
"Node %u: Forced node shutdown completed%s.%s%s",
807 R, action_str.c_str(), sphase_str.c_str(),
812 #define EVENT StopAborted
814 ndbout_c(
"Node %u: Node shutdown aborted", R);
820 #define EVENT MemoryUsage
830 const int percent = Q(pages_total) ? (Q(pages_used)*100)/Q(pages_total) : 0;
831 ndbout_c(
"Node %u: %s usage %s %d%s(%d %dK pages of total %d)", R,
832 (Q(
block) == DBACC ?
"Index" : (Q(
block) == DBTUP ?
"Data":
"<unknown>")),
833 (Q(gth) > 0 ?
"increased to" :
"decreased to"),
835 Q(pages_used), Q(page_size_kb)/1024, Q(pages_total));
854 static int do_event_thread = 0;
857 event_thread_run(
void* p)
859 DBUG_ENTER(
"event_thread_run");
863 NdbMutex* printmutex= *(param.p);
882 printLogEvent(&log_event);
886 }
while(do_event_thread);
887 ndb_mgm_destroy_logevent_handle(&log_handle);
898 CommandInterpreter::connect(
bool interactive)
900 DBUG_ENTER(
"CommandInterpreter::connect");
903 DBUG_RETURN(m_connected);
906 if(m_mgmsrv == NULL) {
907 ndbout_c(
"Can't create handle to management server.");
913 if(m_mgmsrv2 == NULL) {
914 ndbout_c(
"Can't create 2:nd handle to management server.");
926 DBUG_RETURN(m_connected);
932 constr.
assfmt(
"%s:%d",host,port);
936 DBUG_PRINT(
"info",(
"2:ndb connected to Management Server ok at: %s:%d",
938 assert(m_event_thread == NULL);
939 assert(do_event_thread == 0);
944 m_event_thread = NdbThread_Create(event_thread_run,
947 "CommandInterpreted_event_thread",
948 NDB_THREAD_PRIO_LOW);
951 DBUG_PRINT(
"info",(
"Thread created ok, waiting for started..."));
953 while(do_event_thread == 0 &&
955 NdbSleep_MilliSleep(30);
957 if (m_event_thread == NULL ||
958 do_event_thread == 0 ||
959 do_event_thread == -1)
961 DBUG_PRINT(
"info",(
"Warning, event thread startup failed, "
962 "degraded printouts as result, errno=%d",
964 printf(
"Warning, event thread startup failed, "
965 "degraded printouts as result, errno=%d\n", errno);
970 NdbThread_WaitFor(m_event_thread, &res);
971 NdbThread_Destroy(&m_event_thread);
978 DBUG_PRINT(
"warning",
979 (
"Could not do 2:nd connect to mgmtserver for event listening"));
980 DBUG_PRINT(
"info", (
"code: %d, msg: %s",
983 printf(
"Warning, event connect failed, degraded printouts as result\n");
984 printf(
"code: %d, msg: %s\n",
990 DBUG_PRINT(
"info",(
"Connected to Management Server at: %s:%d", host, port));
993 printf(
"Connected to Management Server at: %s:%d\n",
997 DBUG_RETURN(m_connected);
1001 CommandInterpreter::disconnect(
void)
1003 DBUG_ENTER(
"CommandInterpreter::disconnect");
1005 if (m_event_thread) {
1008 NdbThread_WaitFor(m_event_thread, &res);
1009 NdbThread_Destroy(&m_event_thread);
1010 m_event_thread= NULL;
1026 bool interactive,
int *error)
1028 if (try_reconnect >= 0)
1029 m_try_reconnect = try_reconnect;
1030 bool result= execute_impl(_line, interactive);
1038 invalid_command(
const char *cmd)
1040 ndbout <<
"Invalid command: " << cmd << endl;
1041 ndbout <<
"Type HELP for help." << endl << endl;
1059 bool fetch(
NdbMgmHandle handle,
bool all_nodes =
false) {
1063 NDB_MGM_NODE_TYPE_UNKNOWN
1066 !all_nodes ? types : 0);
1067 if (m_status == NULL)
1069 ndbout_c(
"ERROR: couldn't fetch cluster status");
1075 bool is_valid_ndb_nodeid(
int nodeid)
const {
1077 if (nodeid < 1 || nodeid >= MAX_NDB_NODES)
1079 ndbout_c(
"ERROR: illegal nodeid %d!", nodeid);
1085 bool is_ndb_node(
int nodeid)
const {
1087 if (!is_valid_ndb_nodeid(nodeid))
1099 ndbout_c(
"ERROR: node %d is not a NDB node!", nodeid);
1118 for (
unsigned i= 0;
i < args.size();
i++)
1119 if (args[
i].length() == 0)
1125 CommandInterpreter::execute_impl(
const char *_line,
bool interactive)
1127 DBUG_ENTER(
"CommandInterpreter::execute_impl");
1128 DBUG_PRINT(
"enter",(
"line='%s'", _line));
1132 ndbout_c(
"ERROR: Internal error at %s:%d.", __FILE__, __LINE__);
1137 char* line = strdup(_line);
1140 ndbout_c(
"ERROR: Memory allocation error at %s:%d.", __FILE__, __LINE__);
1157 unsigned last= strlen(line)-1;
1158 if (line[last] ==
';')
1164 }
while (do_continue);
1168 split_args(line, command_list);
1170 char* firstToken = strtok(line,
" ");
1171 char* allAfterFirstToken = strtok(NULL,
"");
1173 if (strcasecmp(firstToken,
"HELP") == 0 ||
1174 strcasecmp(firstToken,
"?") == 0) {
1175 m_error = executeHelp(allAfterFirstToken);
1178 else if (strcasecmp(firstToken,
"CONNECT") == 0) {
1179 m_error = executeConnect(allAfterFirstToken, interactive);
1182 else if (strcasecmp(firstToken,
"SLEEP") == 0) {
1183 if (allAfterFirstToken)
1184 NdbSleep_SecSleep(atoi(allAfterFirstToken));
1187 else if((strcasecmp(firstToken,
"QUIT") == 0 ||
1188 strcasecmp(firstToken,
"EXIT") == 0 ||
1189 strcasecmp(firstToken,
"BYE") == 0) &&
1190 allAfterFirstToken == NULL){
1194 if (!connect(interactive)){
1199 if (ndb_mgm_check_connection(m_mgmsrv))
1202 connect(interactive);
1205 if (strcasecmp(firstToken,
"SHOW") == 0) {
1206 Guard g(m_print_mutex);
1207 m_error = executeShow(allAfterFirstToken);
1210 else if (strcasecmp(firstToken,
"SHUTDOWN") == 0) {
1211 m_error= executeShutdown(allAfterFirstToken);
1214 else if (strcasecmp(firstToken,
"CLUSTERLOG") == 0){
1215 executeClusterLog(allAfterFirstToken);
1218 else if(strcasecmp(firstToken,
"START") == 0 &&
1219 allAfterFirstToken != NULL &&
1220 strncasecmp(allAfterFirstToken,
"BACKUP",
sizeof(
"BACKUP") - 1) == 0){
1224 else if(strcasecmp(firstToken,
"ABORT") == 0 &&
1225 allAfterFirstToken != NULL &&
1226 strncasecmp(allAfterFirstToken,
"BACKUP",
sizeof(
"BACKUP") - 1) == 0){
1227 m_error = executeAbortBackup(allAfterFirstToken);
1230 else if (strcasecmp(firstToken,
"PURGE") == 0) {
1231 m_error = executePurge(allAfterFirstToken);
1234 else if(strcasecmp(firstToken,
"ENTER") == 0 &&
1235 allAfterFirstToken != NULL &&
1236 allAfterFirstToken != NULL &&
1237 strncasecmp(allAfterFirstToken,
"SINGLE USER MODE ",
1238 sizeof(
"SINGLE USER MODE") - 1) == 0){
1239 m_error = executeEnterSingleUser(allAfterFirstToken);
1242 else if(strcasecmp(firstToken,
"EXIT") == 0 &&
1243 allAfterFirstToken != NULL &&
1244 strncasecmp(allAfterFirstToken,
"SINGLE USER MODE ",
1245 sizeof(
"SINGLE USER MODE") - 1) == 0){
1246 m_error = executeExitSingleUser(allAfterFirstToken);
1249 else if(strcasecmp(firstToken,
"CREATE") == 0 &&
1250 allAfterFirstToken != NULL &&
1251 strncasecmp(allAfterFirstToken,
"NODEGROUP",
1252 sizeof(
"NODEGROUP") - 1) == 0){
1253 m_error = executeCreateNodeGroup(allAfterFirstToken);
1256 else if(strcasecmp(firstToken,
"DROP") == 0 &&
1257 allAfterFirstToken != NULL &&
1258 strncasecmp(allAfterFirstToken,
"NODEGROUP",
1259 sizeof(
"NODEGROUP") - 1) == 0){
1260 m_error = executeDropNodeGroup(allAfterFirstToken);
1263 else if (strcasecmp(firstToken,
"ALL") == 0) {
1264 m_error = analyseAfterFirstToken(-1, allAfterFirstToken);
1269 int node_ids[MAX_NODES];
1271 for (pos= 0; pos < command_list.size(); pos++)
1274 if (convert(command_list[pos].c_str(), node_id))
1276 if (node_id <= 0 || node_id > MAX_NODES) {
1277 ndbout <<
"Invalid node ID: " << command_list[pos].c_str()
1281 node_ids[pos]= node_id;
1286 int no_of_nodes= pos;
1287 if (no_of_nodes == 0)
1290 invalid_command(_line);
1294 if (pos == command_list.size())
1297 invalid_command(_line);
1301 if (no_of_nodes == 1)
1303 m_error = analyseAfterFirstToken(node_ids[0], allAfterFirstToken);
1306 m_error = executeCommand(command_list, pos, node_ids, no_of_nodes);
1317 {
"START", &CommandInterpreter::executeStart }
1318 ,{
"RESTART", &CommandInterpreter::executeRestart }
1319 ,{
"STOP", &CommandInterpreter::executeStop }
1320 ,{
"STATUS", &CommandInterpreter::executeStatus }
1321 ,{
"LOGLEVEL", &CommandInterpreter::executeLogLevel }
1322 ,{
"CLUSTERLOG", &CommandInterpreter::executeEventReporting }
1324 ,{
"ERROR", &CommandInterpreter::executeError }
1326 ,{
"LOG", &CommandInterpreter::executeLog }
1327 ,{
"TESTON", &CommandInterpreter::executeTestOn }
1328 ,{
"TESTOFF", &CommandInterpreter::executeTestOff }
1329 ,{
"DUMP", &CommandInterpreter::executeDumpState }
1330 ,{
"REPORT", &CommandInterpreter::executeReport }
1337 CommandInterpreter::analyseAfterFirstToken(
int processId,
1338 char* allAfterFirstToken) {
1341 if (emptyString(allAfterFirstToken)) {
1342 ndbout <<
"Expected a command after "
1343 << ((processId == -1) ?
"ALL." :
"node ID.") << endl;
1347 char* secondToken = strtok(allAfterFirstToken,
" ");
1348 char* allAfterSecondToken = strtok(NULL,
"\0");
1350 const int tmpSize =
sizeof(commands)/
sizeof(CommandFunctionPair);
1352 const char * command = 0;
1353 for(
int i = 0;
i<tmpSize;
i++){
1354 if(strcasecmp(secondToken, commands[
i].command) == 0){
1355 fun = commands[
i].executeFunction;
1356 command = commands[
i].command;
1362 invalid_command(secondToken);
1366 if(processId == -1){
1367 retval = executeForAll(command, fun, allAfterSecondToken);
1369 retval = (this->*fun)(processId, allAfterSecondToken,
false);
1377 unsigned command_pos,
1378 int *node_ids,
int no_of_nodes)
1380 const char *cmd= command_list[command_pos].c_str();
1383 if (strcasecmp(
"STOP", cmd) == 0)
1385 retval = executeStop(command_list, command_pos+1, node_ids, no_of_nodes);
1388 if (strcasecmp(
"RESTART", cmd) == 0)
1390 retval = executeRestart(command_list, command_pos+1, node_ids, no_of_nodes);
1393 if (strcasecmp(
"START", cmd) == 0)
1395 retval = executeStart(command_list, command_pos+1, node_ids, no_of_nodes);
1398 ndbout_c(
"Invalid command: '%s' after multi node id list. "
1399 "Expected STOP, START, or RESTART.", cmd);
1425 while((i < cl->no_of_nodes)) {
1426 if((*node_id < cl->node_states[i].node_id) &&
1442 CommandInterpreter::executeForAll(
const char * cmd, ExecuteFunction fun,
1443 const char * allAfterSecondToken)
1448 if(strcasecmp(cmd,
"STOP") == 0) {
1449 ndbout_c(
"Executing STOP on all nodes.");
1450 retval = (this->*fun)(nodeId, allAfterSecondToken,
true);
1451 }
else if(strcasecmp(cmd,
"RESTART") == 0) {
1452 retval = (this->*fun)(nodeId, allAfterSecondToken,
true);
1453 }
else if (strcasecmp(cmd,
"STATUS") == 0) {
1454 (this->*fun)(nodeId, allAfterSecondToken,
true);
1455 }
else if (strcasecmp(cmd,
"REPORT") == 0) {
1456 Guard g(m_print_mutex);
1457 retval = executeReport(nodeId, allAfterSecondToken,
true);
1459 Guard g(m_print_mutex);
1462 ndbout_c(
"Unable get status from management server");
1468 retval = (this->*fun)(nodeId, allAfterSecondToken,
true);
1476 CommandInterpreter::parseBlockSpecification(
const char* allAfterLog,
1481 if (emptyString(allAfterLog)) {
1486 char* newAllAfterLog = strdup(allAfterLog);
1487 if (newAllAfterLog == NULL)
1489 ndbout_c(
"ERROR: Memory allocation error at %s:%d.", __FILE__, __LINE__);
1494 char* firstTokenAfterLog = strtok(newAllAfterLog,
" ");
1495 for (
unsigned int i = 0; i < strlen(firstTokenAfterLog); ++
i) {
1496 firstTokenAfterLog[
i] = toupper(firstTokenAfterLog[i]);
1499 if (strcasecmp(firstTokenAfterLog,
"BLOCK") != 0) {
1500 ndbout <<
"Unexpected value: " << firstTokenAfterLog
1501 <<
". Expected BLOCK." << endl;
1505 char* allAfterFirstToken = strtok(NULL,
"\0");
1506 if (emptyString(allAfterFirstToken)) {
1507 ndbout <<
"Expected =." << endl;
1511 char* secondTokenAfterLog = strtok(allAfterFirstToken,
" ");
1512 if (strcasecmp(secondTokenAfterLog,
"=") != 0) {
1513 ndbout <<
"Unexpected value: " << secondTokenAfterLog
1514 <<
". Expected =." << endl;
1518 char* blockName = strtok(NULL,
" ");
1520 if (blockName != NULL && (strcasecmp(blockName,
"ALL") == 0)) {
1523 while (blockName != NULL) {
1524 blocks.push_back(blockName);
1525 blockName = strtok(NULL,
" ");
1528 if (blocks.size() == 0) {
1529 ndbout <<
"No block specified." << endl;
1532 if (blocks.size() > 1 && all) {
1534 ndbout <<
"Nothing expected after ALL." << endl;
1547 CommandInterpreter::executeHelp(
char* parameters)
1549 if (emptyString(parameters)) {
1554 <<
"ALERT | CRITICAL | ERROR | WARNING | INFO | DEBUG"
1557 ndbout <<
"<category> = ";
1558 for(
int i = CFG_MIN_LOGLEVEL; i <= CFG_MAX_LOGLEVEL; i++){
1561 if (i != CFG_MIN_LOGLEVEL)
1568 ndbout <<
"<level> = " <<
"0 - 15" << endl;
1569 ndbout <<
"<id> = " <<
"ALL | Any database node id" << endl;
1571 ndbout <<
"For detailed help on COMMAND, use HELP COMMAND." << endl;
1574 for (i = 0; help_items[
i].cmd != NULL; i++)
1576 if (strcasecmp(parameters, help_items[i].cmd) == 0)
1578 if (help_items[i].help)
1579 ndbout << help_items[
i].help;
1580 if (help_items[i].help_fn)
1581 (*help_items[
i].help_fn)();
1585 if (help_items[i].cmd == NULL){
1586 ndbout <<
"No help for " << parameters <<
" available" << endl;
1599 CommandInterpreter::executeShutdown(
char* parameters)
1603 ndbout_c(
"Could not get status");
1610 int need_disconnect;
1611 result =
ndb_mgm_stop3(m_mgmsrv, -1, 0, 0, &need_disconnect);
1613 ndbout <<
"Shutdown of NDB Cluster node(s) failed." << endl;
1618 ndbout << result <<
" NDB Cluster node(s) have shutdown." << endl;
1620 if(need_disconnect) {
1621 ndbout <<
"Disconnecting to allow management server to shutdown."
1638 return "not connected";
1640 return "not started";
1646 return "shutting down";
1648 return "restarting";
1650 return "single user mode";
1652 return "unknown state";
1662 ndbout <<
"[" << proc_name
1664 << no_proc <<
" node(s)" << endl;
1668 int node_id= node_state->
node_id;
1670 if(node_state->
version != 0) {
1673 || strlen(hostname) == 0
1674 || strcasecmp(hostname,
"0.0.0.0") == 0)
1677 ndbout <<
"\t@" << hostname;
1680 ndbout <<
" (" << ndbGetVersionString(node_state->
version,
1686 ndbout <<
", " << status_string(node_state->
node_status);
1689 ndbout <<
", Nodegroup: " << node_state->
node_group;
1691 else if (node_state->
node_group == (
int)RNIL)
1693 ndbout <<
", no nodegroup";
1696 if (master_id && node_state->
dynamic_id == master_id)
1697 ndbout <<
", Master";
1699 ndbout <<
")" << endl;
1702 if(ndb_mgm_find(it, CFG_NODE_ID, node_id) == 0){
1703 const char *config_hostname= 0;
1704 ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &config_hostname);
1705 if (config_hostname == 0 || config_hostname[0] == 0)
1706 config_hostname=
"any host";
1707 ndbout_c(
" (not connected, accepting connect from %s)",
1712 ndbout_c(
"Unable to find node with id: %d", node_id);
1721 CommandInterpreter::executePurge(
char* parameters)
1725 if (emptyString(parameters))
1727 char* firstToken = strtok(parameters,
" ");
1728 char* nextToken = strtok(NULL,
" \0");
1729 if (strcasecmp(firstToken,
"STALE") == 0 &&
1731 strcasecmp(nextToken,
"SESSIONS") == 0) {
1738 ndbout_c(
"Unexpected command, expected: PURGE STALE SESSIONS");
1744 if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) {
1745 ndbout_c(
"Command failed");
1749 ndbout_c(
"Purged sessions with node id's: %s", str);
1754 ndbout_c(
"No sessions purged");
1760 CommandInterpreter::executeShow(
char* parameters)
1763 if (emptyString(parameters)) {
1766 ndbout_c(
"Could not get status");
1774 ndbout_c(
"Could not get configuration");
1783 ndbout_c(
"Unable to create config iterator");
1784 ndb_mgm_destroy_configuration(conf);
1817 case NDB_MGM_NODE_TYPE_UNKNOWN:
1818 ndbout <<
"Error: Unknown Node Type" << endl;
1820 case NDB_MGM_NODE_TYPE_MAX:
1825 ndbout <<
"Cluster Configuration" << endl
1826 <<
"---------------------" << endl;
1830 ndb_mgm_destroy_configuration(conf);
1833 ndbout <<
"Invalid argument: '" << parameters <<
"'" << endl;
1840 CommandInterpreter::executeConnect(
char* parameters,
bool interactive)
1845 if (!emptyString(parameters)) {
1849 if ( connect(interactive) ==
false ){
1852 if (basestring != NULL)
1861 CommandInterpreter::executeClusterLog(
char* parameters)
1863 DBUG_ENTER(
"CommandInterpreter::executeClusterLog");
1865 if (emptyString(parameters))
1867 ndbout_c(
"ERROR: Missing argument(s).");
1874 char * tmpString = strdup(parameters);
1875 if (tmpString == NULL)
1877 ndbout_c(
"ERROR: Memory allocation error at %s:%d.", __FILE__, __LINE__);
1884 char * item = strtok_r(tmpString,
" ", &tmpPtr);
1896 if(enabled == NULL) {
1897 ndbout <<
"Couldn't get status" << endl;
1906 if (strcasecmp(item,
"INFO") == 0) {
1907 DBUG_PRINT(
"info",(
"INFO"));
1908 if(enabled[0].value == 0)
1910 ndbout <<
"Cluster logging is disabled." << endl;
1915 for(i = 0; i<DB_MGM_EVENT_SEVERITY_ALL;i++)
1916 printf(
"enabled[%d] = %d\n", i, enabled[i].value);
1918 ndbout <<
"Severities enabled: ";
1920 const char *str= ndb_mgm_get_event_severity_string(enabled[i].category);
1926 if(enabled[i].value)
1934 else if (strcasecmp(item,
"FILTER") == 0 ||
1935 strcasecmp(item,
"TOGGLE") == 0)
1937 DBUG_PRINT(
"info",(
"TOGGLE"));
1940 else if (strcasecmp(item,
"OFF") == 0)
1942 DBUG_PRINT(
"info",(
"OFF"));
1944 }
else if (strcasecmp(item,
"ON") == 0) {
1945 DBUG_PRINT(
"info",(
"ON"));
1948 ndbout <<
"Invalid argument." << endl;
1954 item = strtok_r(NULL,
" ", &tmpPtr);
1962 ndbout <<
"Couldn't set filter" << endl;
1967 ndbout <<
"Cluster logging is " << (res_enable ?
"enabled.":
"disabled") << endl;
1973 severity= NDB_MGM_ILLEGAL_EVENT_SEVERITY;
1974 if (strcasecmp(item,
"ALL") == 0) {
1976 }
else if (strcasecmp(item,
"ALERT") == 0) {
1978 }
else if (strcasecmp(item,
"CRITICAL") == 0) {
1980 }
else if (strcasecmp(item,
"ERROR") == 0) {
1982 }
else if (strcasecmp(item,
"WARNING") == 0) {
1984 }
else if (strcasecmp(item,
"INFO") == 0) {
1986 }
else if (strcasecmp(item,
"DEBUG") == 0) {
1988 }
else if (strcasecmp(item,
"OFF") == 0 ||
1989 strcasecmp(item,
"ON") == 0) {
1993 if (severity == NDB_MGM_ILLEGAL_EVENT_SEVERITY) {
1994 ndbout <<
"Invalid severity level: " << item << endl;
2003 ndbout <<
"Couldn't set filter" << endl;
2010 item = strtok_r(NULL,
" ", &tmpPtr);
2011 }
while(item != NULL);
2021 CommandInterpreter::executeStop(
int processId,
const char *parameters,
2026 split_args(parameters, command_list);
2030 retval = executeStop(command_list, 0, 0, 0);
2032 retval = executeStop(command_list, 0, &processId, 1);
2039 unsigned command_pos,
2040 int *node_ids,
int no_of_nodes)
2042 int need_disconnect;
2047 for (; command_pos < command_list.size(); command_pos++)
2049 const char *item= command_list[command_pos].c_str();
2050 if (strcasecmp(item,
"-A") == 0)
2055 if (strcasecmp(item,
"-F") == 0)
2060 ndbout_c(
"Invalid option: %s. Expecting -A or -F after STOP",
2065 int result=
ndb_mgm_stop4(m_mgmsrv, no_of_nodes, node_ids, abort,
2066 force, &need_disconnect);
2069 ndbout_c(
"Shutdown failed.");
2076 ndbout_c(
"NDB Cluster has shutdown.");
2080 for (
int i= 0; i < no_of_nodes; i++)
2081 ndbout <<
" " << node_ids[i];
2082 ndbout_c(
" has shutdown.");
2088 ndbout <<
"Disconnecting to allow Management Server to shutdown" << endl;
2096 CommandInterpreter::executeEnterSingleUser(
char* parameters)
2098 strtok(parameters,
" ");
2100 char*
id = strtok(NULL,
" ");
2101 id = strtok(NULL,
" ");
2102 id = strtok(NULL,
"\0");
2104 if(
id == 0 || sscanf(
id,
"%d", &nodeId) != 1){
2105 ndbout_c(
"Invalid arguments: expected <NodeId>");
2106 ndbout_c(
"Use SHOW to see what API nodes are configured");
2112 ndbout_c(
"Entering single user mode for node %d failed", nodeId);
2116 ndbout_c(
"Single user mode entered");
2117 ndbout_c(
"Access is granted for API node %d only.", nodeId);
2123 CommandInterpreter::executeExitSingleUser(
char* parameters)
2127 ndbout_c(
"Exiting single user mode failed.");
2131 ndbout_c(
"Exiting single user mode in progress.");
2132 ndbout_c(
"Use ALL STATUS or SHOW to see when single user mode has been exited.");
2138 CommandInterpreter::executeStart(
int processId,
const char* parameters,
2150 ndbout <<
"Start failed." << endl;
2156 ndbout_c(
"NDB Cluster is being started.");
2158 ndbout_c(
"Database node %d is being started.", processId);
2165 unsigned command_pos,
2166 int *node_ids,
int no_of_nodes)
2172 ndbout_c(
"Start failed.");
2179 for (
int i= 0; i < no_of_nodes; i++)
2180 ndbout <<
" " << node_ids[i];
2181 ndbout_c(
" is being started");
2187 CommandInterpreter::executeRestart(
int processId,
const char* parameters,
2192 split_args(parameters, command_list);
2196 retval = executeRestart(command_list, 0, 0, 0);
2198 retval = executeRestart(command_list, 0, &processId, 1);
2205 unsigned command_pos,
2206 int *node_ids,
int no_of_nodes)
2211 int initialstart= 0;
2213 int need_disconnect= 0;
2216 for (; command_pos < command_list.size(); command_pos++)
2218 const char *item= command_list[command_pos].c_str();
2219 if (strcasecmp(item,
"-N") == 0)
2224 if (strcasecmp(item,
"-I") == 0)
2229 if (strcasecmp(item,
"-A") == 0)
2234 if (strcasecmp(item,
"-F") == 0)
2239 ndbout_c(
"Invalid option: %s. Expecting -A,-N,-I or -F after RESTART",
2247 ndbout_c(
"Could not get status");
2258 ndbout_c(
"Cannot restart nodes: single user mode");
2264 if (node_ids == 0) {
2265 ndbout_c(
"Executing RESTART on all nodes.");
2266 ndbout_c(
"Starting shutdown. This may take a while. Please wait...");
2277 ndbout << node_ids[
i] <<
": Node not found" << endl;
2283 ndbout <<
"Shutting down MGM node"
2284 <<
" " << node_ids[
i] <<
" for restart" << endl;
2289 initialstart, nostart, abort, force,
2293 ndbout_c(
"Restart failed.");
2300 ndbout_c(
"All DB nodes are being restarted.");
2305 ndbout <<
" " << node_ids[i];
2306 ndbout_c(
" is being restarted");
2321 Uint32 version = state->
version;
2326 ndbout <<
"Node " << state->
node_id <<
": connected" ;
2327 ndbout_c(
" (Version %d.%d.%d)",
2335 ndbout <<
"Node " << state->
node_id <<
": not connected" << endl;
2340 ndbout <<
"Node " << state->
node_id
2344 ndbout <<
" (Last completed phase " << state->
start_phase <<
")";
2347 ndbout <<
" (Last completed phase " << state->
start_phase <<
")";
2356 ndbout_c(
" (%s)", ndbGetVersionString(version,
2367 CommandInterpreter::executeStatus(
int processId,
2368 const char* parameters,
bool all)
2370 if (! emptyString(parameters)) {
2371 ndbout_c(
"No parameters expected to this command.");
2377 NDB_MGM_NODE_TYPE_UNKNOWN
2383 ndbout_c(
"Can't get status of node %d.", processId);
2405 ndbout << processId <<
": Node not found" << endl;
2412 CommandInterpreter::executeDumpState(
int processId,
const char* parameters,
2415 if(emptyString(parameters))
2417 ndbout_c(
"ERROR: Expected argument!");
2423 const size_t max_params =
sizeof(params)/
sizeof(params[0]);
2426 split_args(parameters, args);
2428 if (args.size() > max_params)
2430 ndbout_c(
"ERROR: Too many arguments, max %d allowed", (
int)max_params);
2434 for (
size_t i = 0; i < args.size(); i++)
2436 const char* arg = args[
i].c_str();
2438 if (strtoll(arg, NULL, 0) < 0 ||
2439 strtoll(arg, NULL, 0) > 0xffffffff)
2441 ndbout_c(
"ERROR: Illegal value '%s' in argument to signal.\n"
2442 "(Value must be between 0 and 0xffffffff.)", arg);
2445 assert(num_params < (
int)max_params);
2446 params[num_params] = (int)strtoll(arg, NULL, 0);
2450 ndbout <<
"Sending dump signal with data:" << endl;
2451 for (
int i = 0; i < num_params; i++)
2453 ndbout.setHexFormat(1) << params[
i] <<
" ";
2454 if (!((i+1) & 0x3)) ndbout << endl;
2466 const Uint32
block = usage.block;
2467 const Uint32 total = usage.pages_total;
2468 const Uint32 used = usage.pages_used;
2471 ndbout_c(
"Node %u: %s usage is %d%%(%d %dK pages of total %d)",
2473 (block == DBACC ?
"Index" : (block == DBTUP ?
"Data" :
"<unknown>")),
2474 (total ? (used * 100 / total) : 0),
2476 usage.page_size_kb/1024,
2488 if (status.starting_node)
2489 ndbout_c(
"Node %u: Local backup status: backup %u started from node %u\n"
2490 " #Records: %llu #LogRecords: %llu\n"
2491 " Data: %llu bytes Log: %llu bytes",
2494 refToNode(status.starting_node),
2495 make_uint64(status.n_records_lo, status.n_records_hi),
2496 make_uint64(status.n_log_records_lo, status.n_log_records_hi),
2497 make_uint64(status.n_bytes_lo, status.n_bytes_hi),
2498 make_uint64(status.n_log_bytes_lo, status.n_log_bytes_hi));
2500 ndbout_c(
"Node %u: Backup not started",
2508 Uint32 threshold = 0;
2510 LogLevel::EventCategory cat= LogLevel::llInvalid;
2514 Uint32 type = real_event->getEventType();
2516 if (EventLoggerBase::event_lookup(type,cat,threshold,severity,textF))
2524 pos= (Uint32)strlen(out);
2526 textF(out+pos,
sizeof(out)-pos, event.SavedEvent.data, event.SavedEvent.len);
2528 time_t t =
event.SavedEvent.time;
2529 struct tm * tm_now = localtime(&t);
2530 ndbout_c(
"%d-%.2d-%.2d %.2d:%.2d:%.2d %s",
2531 tm_now->tm_year + 1900,
2541 sort_log(
const void *_a,
const void *_b)
2548 return a->SavedEvent.seq - b->SavedEvent.seq;
2551 if (a->SavedEvent.time < b->SavedEvent.time)
2553 if (a->SavedEvent.time > b->SavedEvent.time)
2556 if (a->SavedEvent.seq < b->SavedEvent.seq)
2558 if (a->SavedEvent.seq > b->SavedEvent.seq)
2565 struct st_report_cmd {
2570 int (* sort_fn)(
const void *_a,
const void *_b);
2574 "Report backup status of respective node",
2576 report_backupstatus, 0 },
2579 "Report memory usage of respective node",
2581 report_memoryusage, 0 },
2584 "Report events in datanodes circular event log buffer",
2586 report_events, sort_log },
2588 { 0, 0, NDB_LE_ILLEGAL_TYPE, 0, 0 }
2593 CommandInterpreter::executeReport(
int nodeid,
const char* parameters,
2596 if (emptyString(parameters))
2598 ndbout_c(
"ERROR: missing report type specifier!");
2603 split_args(parameters, args);
2605 const st_report_cmd* report_cmd = report_cmds;
2606 for (; report_cmd->name; report_cmd++)
2608 if (strncasecmp(report_cmd->name, args[0].c_str(),
2609 args[0].length()) == 0)
2613 if (!report_cmd->name)
2615 ndbout_c(
"ERROR: '%s' - report type specifier unknown!", args[0].c_str());
2622 if (!info.fetch(m_mgmsrv))
2629 if (!info.is_ndb_node(nodeid))
2635 all ? 0 : 1, &nodeid);
2638 ndbout_c(
"ERROR: failed to fetch report!");
2643 if (report_cmd->sort_fn)
2646 sizeof(events->
events[0]), report_cmd->sort_fn);
2652 report_cmd->print_event_fn(event);
2663 ndbout_c(
" <report-type> =");
2664 const st_report_cmd* report_cmd = report_cmds;
2665 for (; report_cmd->name; report_cmd++)
2666 ndbout_c(
" %s\t- %s", report_cmd->name, report_cmd->help);
2674 CommandInterpreter::executeLogLevel(
int processId,
const char* parameters,
2678 if (emptyString(parameters)) {
2679 ndbout <<
"Expected argument" << endl;
2684 tmp.split(spec,
"=");
2685 if(spec.size() != 2){
2686 ndbout <<
"Invalid loglevel specification: " << parameters << endl;
2690 spec[0].trim().ndb_toupper();
2691 int category = ndb_mgm_match_event_category(spec[0].c_str());
2693 category = atoi(spec[0].c_str());
2694 if(category < NDB_MGM_MIN_EVENT_CATEGORY ||
2695 category > NDB_MGM_MAX_EVENT_CATEGORY){
2696 ndbout <<
"Unknown category: \"" << spec[0].c_str() <<
"\"" << endl;
2701 int level = atoi(spec[1].c_str());
2702 if(level < 0 || level > 15){
2703 ndbout <<
"Invalid level: " << spec[1].c_str() << endl;
2707 ndbout <<
"Executing LOGLEVEL on node " << processId << flush;
2718 ndbout_c(
" failed.");
2729 int CommandInterpreter::executeError(
int processId,
2730 const char* parameters,
bool )
2732 if (emptyString(parameters))
2734 ndbout_c(
"ERROR: Missing error number.");
2739 split_args(parameters, args);
2741 if (args.size() >= 2)
2743 ndbout <<
"ERROR: Too many arguments." << endl;
2748 if (! convert(args[0].c_str(), errorNo)) {
2749 ndbout <<
"ERROR: Expected an integer." << endl;
2753 return ndb_mgm_insert_error(m_mgmsrv, processId, errorNo, NULL);
2760 CommandInterpreter::executeLog(
int processId,
2761 const char* parameters,
bool all)
2765 if (! parseBlockSpecification(parameters, blocks)) {
2770 for (
unsigned i = 0; i<blocks.size(); i++)
2771 block_names.
appfmt(
"%s|", blocks[i].c_str());
2773 int result = ndb_mgm_log_signals(m_mgmsrv,
2776 block_names.
c_str(),
2779 ndbout_c(
"Execute LOG on node %d failed.", processId);
2790 CommandInterpreter::executeTestOn(
int processId,
2791 const char* parameters,
bool )
2793 if (! emptyString(parameters)) {
2794 ndbout <<
"No parameters expected to this command." << endl;
2798 int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &
reply);
2800 ndbout_c(
"Execute TESTON failed.");
2810 CommandInterpreter::executeTestOff(
int processId,
2811 const char* parameters,
bool )
2813 if (! emptyString(parameters)) {
2814 ndbout <<
"No parameters expected to this command." << endl;
2818 int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &
reply);
2820 ndbout_c(
"Execute TESTOFF failed.");
2832 CommandInterpreter::executeEventReporting(
int processId,
2833 const char* parameters,
2837 if (emptyString(parameters)) {
2838 ndbout <<
"Expected argument" << endl;
2843 split_args(parameters, specs);
2845 for (
int i=0; i < (int) specs.size(); i++)
2848 specs[
i].split(spec,
"=");
2849 if(spec.size() != 2){
2850 ndbout <<
"Invalid loglevel specification: " << specs[
i] << endl;
2854 spec[0].trim().ndb_toupper();
2855 int category = ndb_mgm_match_event_category(spec[0].c_str());
2857 if(!convert(spec[0].c_str(), category) ||
2858 category < NDB_MGM_MIN_EVENT_CATEGORY ||
2859 category > NDB_MGM_MAX_EVENT_CATEGORY){
2860 ndbout <<
"Unknown category: \"" << spec[0].c_str() <<
"\"" << endl;
2866 if (!convert(spec[1].c_str(),level))
2868 ndbout <<
"Invalid level: " << spec[1].c_str() << endl;
2872 ndbout <<
"Executing CLUSTERLOG " << spec[0] <<
"=" << spec[1]
2873 <<
" on node " << processId << flush;
2877 result = ndb_mgm_set_loglevel_clusterlog(m_mgmsrv,
2884 ndbout_c(
" failed.");
2902 unsigned int backupId;
2903 unsigned int input_backupId = 0;
2907 split_args(parameters, args);
2909 for (
unsigned i= 0; i < args.size(); i++)
2910 args[i].ndb_toupper();
2912 int sz= args.size();
2917 unsigned int backuppoint = 0;
2919 bool b_nowait =
false;
2920 bool b_wait_completed =
false;
2921 bool b_wait_started =
false;
2931 for (
int i= 1; i < sz; i++)
2933 if (i == 1 && sscanf(args[1].c_str(),
"%u", &input_backupId) == 1) {
2934 if (input_backupId > 0 && input_backupId < MAX_BACKUPS)
2937 invalid_command(parameters);
2942 if (args[i] ==
"SNAPSHOTEND") {
2944 invalid_command(parameters);
2951 if (args[i] ==
"SNAPSHOTSTART") {
2953 invalid_command(parameters);
2960 if (args[i] ==
"NOWAIT") {
2961 if (b_nowait ==
true || b_wait_completed ==
true || b_wait_started ==
true) {
2962 invalid_command(parameters);
2969 if (args[i] ==
"WAIT") {
2970 if (b_nowait ==
true || b_wait_completed ==
true || b_wait_started ==
true) {
2971 invalid_command(parameters);
2975 if (args[i+1] ==
"COMPLETED") {
2976 b_wait_completed =
true;
2980 else if (args[i+1] ==
"STARTED") {
2981 b_wait_started =
true;
2986 invalid_command(parameters);
2991 invalid_command(parameters);
2996 invalid_command(parameters);
3002 ndbout_c(
"Waiting for completed, this may take several minutes");
3004 ndbout_c(
"Waiting for started, this may take several minutes");
3008 if (flags > 0 && !interactive)
3014 ndbout <<
"Initializing start of backup failed" << endl;
3021 if (input_backupId > 0 || b_log ==
true)
3028 ndbout <<
"Backup failed" << endl;
3032 ndb_mgm_destroy_logevent_handle(&log_handle);
3039 if (log_handle && !interactive)
3048 switch (log_event.
type) {
3066 Guard g(m_print_mutex);
3067 printLogEvent(&log_event);
3075 }
while(res >= 0 && count < 2 && retry < 3);
3078 ndbout <<
"get backup event failed for " << retry <<
" times" << endl;
3080 ndb_mgm_destroy_logevent_handle(&log_handle);
3087 CommandInterpreter::executeAbortBackup(
char* parameters)
3091 if (emptyString(parameters))
3092 goto executeAbortBackupError1;
3095 strtok(parameters,
" ");
3096 char*
id = strtok(NULL,
"\0");
3097 if(
id == 0 || sscanf(
id,
"%d", &bid) != 1)
3098 goto executeAbortBackupError1;
3103 ndbout <<
"Abort of backup " << bid <<
" failed" << endl;
3107 ndbout <<
"Abort of backup " << bid <<
" ordered" << endl;
3111 executeAbortBackupError1:
3112 ndbout <<
"Invalid arguments: expected <BackupId>" << endl;
3117 CommandInterpreter::executeCreateNodeGroup(
char* parameters)
3122 char *
id= strchr(parameters,
' ');
3123 if (emptyString(
id))
3130 args.split(nodelist,
",");
3132 for (Uint32 i = 0; i<nodelist.size(); i++)
3134 nodes.push_back(atoi(nodelist[i].c_str()));
3138 result= ndb_mgm_create_nodegroup(m_mgmsrv, nodes.getBase(), &ng, &
reply);
3144 ndbout <<
"Nodegroup " << ng <<
" created" << endl;
3151 ndbout <<
"Invalid arguments: expected <id>,<id>..." << endl;
3156 CommandInterpreter::executeDropNodeGroup(
char* parameters)
3160 if (emptyString(parameters))
3164 char*
id = strchr(parameters,
' ');
3165 if(
id == 0 || sscanf(
id,
"%d", &ng) != 1)
3170 int result= ndb_mgm_drop_nodegroup(m_mgmsrv, ng, &
reply);
3175 ndbout <<
"Drop Node Group " << ng <<
" done" << endl;
3180 ndbout <<
"Invalid arguments: expected <NG>" << endl;