1#!@PERL_PATH@ 2 3# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. 4# 5# This program is free software; you can redistribute it and/or 6# modify it under the terms of the GNU Library General Public 7# License as published by the Free Software Foundation; version 2 8# of the License. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# Library General Public License for more details. 14# 15# You should have received a copy of the GNU Library General Public 16# License along with this library; if not, write to the Free 17# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 18# MA 02110-1301, USA 19 20use Getopt::Long; 21use POSIX qw(strftime getcwd); 22 23$|=1; 24$VER="2.16"; 25 26my @defaults_options; # Leading --no-defaults, --defaults-file, etc. 27 28$opt_example = 0; 29$opt_help = 0; 30$opt_log = undef(); 31$opt_mysqladmin = "@bindir@/mysqladmin"; 32$opt_mysqld = "@libexecdir@/mysqld"; 33$opt_no_log = 0; 34$opt_password = undef(); 35$opt_tcp_ip = 0; 36$opt_user = "root"; 37$opt_version = 0; 38$opt_silent = 0; 39$opt_verbose = 0; 40 41my $my_print_defaults_exists= 1; 42my $logdir= undef(); 43 44my ($mysqld, $mysqladmin, $groupids, $homedir, $my_progname); 45 46$homedir = $ENV{HOME}; 47$my_progname = $0; 48$my_progname =~ s/.*[\/]//; 49 50 51if (defined($ENV{UMASK})) { 52 my $UMASK = $ENV{UMASK}; 53 my $m; 54 my $fmode = "0640"; 55 56 if(($UMASK =~ m/[^0246]/) || ($UMASK =~ m/^[^0]/) || (length($UMASK) != 4)) { 57 printf("UMASK must be a 3-digit mode with an additional leading 0 to indicate octal.\n"); 58 printf("The first digit will be corrected to 6, the others may be 0, 2, 4, or 6.\n"); } 59 else { 60 $fmode= substr $UMASK, 2, 2; 61 $fmode= "06${fmode}"; } 62 63 if($fmode != $UMASK) { 64 printf("UMASK corrected from $UMASK to $fmode ...\n"); } 65 66 $fmode= oct($fmode); 67 68 umask($fmode); 69} 70 71 72main(); 73 74#### 75#### main sub routine 76#### 77 78sub main 79{ 80 my $flag_exit= 0; 81 82 if (!defined(my_which(my_print_defaults))) 83 { 84 # We can't throw out yet, since --version, --help, or --example may 85 # have been given 86 print "WARNING: my_print_defaults command not found.\n"; 87 print "Please make sure you have this command available and\n"; 88 print "in your path. The command is available from the latest\n"; 89 print "MySQL distribution.\n"; 90 $my_print_defaults_exists= 0; 91 } 92 93 # Remove leading defaults options from @ARGV 94 while (@ARGV > 0) 95 { 96 last unless $ARGV[0] =~ 97 /^--(?:no-defaults$|(?:defaults-file|defaults-extra-file)=)/; 98 push @defaults_options, (shift @ARGV); 99 } 100 101 foreach (@defaults_options) 102 { 103 $_ = quote_shell_word($_); 104 } 105 106 # Add [mysqld_multi] options to front of @ARGV, ready for GetOptions() 107 unshift @ARGV, defaults_for_group('mysqld_multi'); 108 109 # We've already handled --no-defaults, --defaults-file, etc. 110 if (!GetOptions("help", "example", "version", "mysqld=s", "mysqladmin=s", 111 "user=s", "password=s", "log=s", "no-log", 112 "tcp-ip", "silent", "verbose")) 113 { 114 $flag_exit= 1; 115 } 116 usage() if ($opt_help); 117 118 if ($opt_verbose && $opt_silent) 119 { 120 print "Both --verbose and --silent have been given. Some of the warnings "; 121 print "will be disabled\nand some will be enabled.\n\n"; 122 } 123 124 init_log() if (!defined($opt_log)); 125 $groupids = $ARGV[1]; 126 if ($opt_version) 127 { 128 print "$my_progname version $VER by Jani Tolonen\n"; 129 exit(0); 130 } 131 example() if ($opt_example); 132 if ($flag_exit) 133 { 134 print "Error with an option, see $my_progname --help for more info.\n"; 135 exit(1); 136 } 137 if (!defined(my_which(my_print_defaults))) 138 { 139 print "ABORT: Can't find command 'my_print_defaults'.\n"; 140 print "This command is available from the latest MySQL\n"; 141 print "distribution. Please make sure you have the command\n"; 142 print "in your PATH.\n"; 143 exit(1); 144 } 145 usage() if (!defined($ARGV[0]) || 146 (!($ARGV[0] =~ m/^start$/i) && 147 !($ARGV[0] =~ m/^stop$/i) && 148 !($ARGV[0] =~ m/^report$/i))); 149 150 if (!$opt_no_log) 151 { 152 w2log("$my_progname log file version $VER; run: ", 153 "$opt_log", 1, 0); 154 } 155 else 156 { 157 print "$my_progname log file version $VER; run: "; 158 print strftime "%a %b %e %H:%M:%S %Y", localtime; 159 print "\n"; 160 } 161 if ($ARGV[0] =~ m/^start$/i) 162 { 163 if (!defined(($mysqld= my_which($opt_mysqld))) && $opt_verbose) 164 { 165 print "WARNING: Couldn't find the default mysqld binary.\n"; 166 print "Tried: $opt_mysqld\n"; 167 print "This is OK, if you are using option \"mysqld=...\" in "; 168 print "groups [mysqldN] separately for each.\n\n"; 169 } 170 start_mysqlds(); 171 } 172 else 173 { 174 if (!defined(($mysqladmin= my_which($opt_mysqladmin))) && $opt_verbose) 175 { 176 print "WARNING: Couldn't find the default mysqladmin binary.\n"; 177 print "Tried: $opt_mysqladmin\n"; 178 print "This is OK, if you are using option \"mysqladmin=...\" in "; 179 print "groups [mysqldN] separately for each.\n\n"; 180 } 181 if ($ARGV[0] =~ m/^report$/i) 182 { 183 report_mysqlds(); 184 } 185 else 186 { 187 stop_mysqlds(); 188 } 189 } 190} 191 192# 193# Quote word for shell 194# 195 196sub quote_shell_word 197{ 198 my ($option)= @_; 199 200 $option =~ s!([^\w=./-])!\\$1!g; 201 return $option; 202} 203 204sub defaults_for_group 205{ 206 my ($group) = @_; 207 208 return () unless $my_print_defaults_exists; 209 210 my $com= join ' ', 'my_print_defaults', @defaults_options, $group; 211 my @defaults = `$com`; 212 chomp @defaults; 213 return @defaults; 214} 215 216#### 217#### Init log file. Check for appropriate place for log file, in the following 218#### order: my_print_defaults mysqld datadir, @datadir@ 219#### 220 221sub init_log 222{ 223 foreach my $opt (defaults_for_group('mysqld')) 224 { 225 if ($opt =~ m/^--datadir=(.*)/ && -d "$1" && -w "$1") 226 { 227 $logdir= $1; 228 } 229 } 230 if (!defined($logdir)) 231 { 232 $logdir= "@datadir@" if (-d "@datadir@" && -w "@datadir@"); 233 } 234 if (!defined($logdir)) 235 { 236 # Log file was not specified and we could not log to a standard place, 237 # so log file be disabled for now. 238 if (!$opt_silent) 239 { 240 print "WARNING: Log file disabled. Maybe directory or file isn't writable?\n"; 241 } 242 $opt_no_log= 1; 243 } 244 else 245 { 246 $opt_log= "$logdir/mysqld_multi.log"; 247 } 248} 249 250#### 251#### Report living and not running MySQL servers 252#### 253 254sub report_mysqlds 255{ 256 my (@groups, $com, $i, @options, $pec); 257 258 print "Reporting MySQL servers\n"; 259 if (!$opt_no_log) 260 { 261 w2log("\nReporting MySQL servers","$opt_log",0,0); 262 } 263 @groups = &find_groups($groupids); 264 for ($i = 0; defined($groups[$i]); $i++) 265 { 266 $com= get_mysqladmin_options($i, @groups); 267 $com.= " ping >> /dev/null 2>&1"; 268 system($com); 269 $pec = $? >> 8; 270 if ($pec) 271 { 272 print "MySQL server from group: $groups[$i] is not running\n"; 273 if (!$opt_no_log) 274 { 275 w2log("MySQL server from group: $groups[$i] is not running", 276 "$opt_log", 0, 0); 277 } 278 } 279 else 280 { 281 print "MySQL server from group: $groups[$i] is running\n"; 282 if (!$opt_no_log) 283 { 284 w2log("MySQL server from group: $groups[$i] is running", 285 "$opt_log", 0, 0); 286 } 287 } 288 } 289 if (!$i) 290 { 291 print "No groups to be reported (check your GNRs)\n"; 292 if (!$opt_no_log) 293 { 294 w2log("No groups to be reported (check your GNRs)", "$opt_log", 0, 0); 295 } 296 } 297} 298 299#### 300#### start multiple servers 301#### 302 303sub start_mysqlds() 304{ 305 my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $info_sent); 306 307 if (!$opt_no_log) 308 { 309 w2log("\nStarting MySQL servers\n","$opt_log",0,0); 310 } 311 else 312 { 313 print "\nStarting MySQL servers\n"; 314 } 315 @groups = &find_groups($groupids); 316 for ($i = 0; defined($groups[$i]); $i++) 317 { 318 @options = defaults_for_group($groups[$i]); 319 320 $basedir_found= 0; # The default 321 $mysqld_found= 1; # The default 322 $mysqld_found= 0 if (!length($mysqld)); 323 $com= "$mysqld"; 324 for ($j = 0, $tmp= ""; defined($options[$j]); $j++) 325 { 326 if ("--mysqladmin=" eq substr($options[$j], 0, 13)) 327 { 328 # catch this and ignore 329 } 330 elsif ("--mysqld=" eq substr($options[$j], 0, 9)) 331 { 332 $options[$j]=~ s/\-\-mysqld\=//; 333 $com= $options[$j]; 334 $mysqld_found= 1; 335 } 336 elsif ("--basedir=" eq substr($options[$j], 0, 10)) 337 { 338 $basedir= $options[$j]; 339 $basedir =~ s/^--basedir=//; 340 $basedir_found= 1; 341 $options[$j]= quote_shell_word($options[$j]); 342 $tmp.= " $options[$j]"; 343 } 344 else 345 { 346 $options[$j]= quote_shell_word($options[$j]); 347 $tmp.= " $options[$j]"; 348 } 349 } 350 if ($opt_verbose && $com =~ m/\/(safe_mysqld|mysqld_safe)$/ && !$info_sent) 351 { 352 print "WARNING: $1 is being used to start mysqld. In this case you "; 353 print "may need to pass\n\"ledir=...\" under groups [mysqldN] to "; 354 print "$1 in order to find the actual mysqld binary.\n"; 355 print "ledir (library executable directory) should be the path to the "; 356 print "wanted mysqld binary.\n\n"; 357 $info_sent= 1; 358 } 359 $com.= $tmp; 360 $com.= " >> $opt_log 2>&1" if (!$opt_no_log); 361 $com.= " &"; 362 if (!$mysqld_found) 363 { 364 print "\n"; 365 print "FATAL ERROR: Tried to start mysqld under group [$groups[$i]], "; 366 print "but no mysqld binary was found.\n"; 367 print "Please add \"mysqld=...\" in group [mysqld_multi], or add it to "; 368 print "group [$groups[$i]] separately.\n"; 369 exit(1); 370 } 371 if ($basedir_found) 372 { 373 $curdir=getcwd(); 374 chdir($basedir) or die "Can't change to datadir $basedir"; 375 } 376 system($com); 377 if ($basedir_found) 378 { 379 chdir($curdir) or die "Can't change back to original dir $curdir"; 380 } 381 } 382 if (!$i && !$opt_no_log) 383 { 384 w2log("No MySQL servers to be started (check your GNRs)", 385 "$opt_log", 0, 0); 386 } 387} 388 389#### 390#### stop multiple servers 391#### 392 393sub stop_mysqlds() 394{ 395 my (@groups, $com, $i, @options); 396 397 if (!$opt_no_log) 398 { 399 w2log("\nStopping MySQL servers\n","$opt_log",0,0); 400 } 401 else 402 { 403 print "\nStopping MySQL servers\n"; 404 } 405 @groups = &find_groups($groupids); 406 for ($i = 0; defined($groups[$i]); $i++) 407 { 408 $com= get_mysqladmin_options($i, @groups); 409 $com.= " shutdown"; 410 $com.= " >> $opt_log 2>&1" if (!$opt_no_log); 411 $com.= " &"; 412 system($com); 413 } 414 if (!$i && !$opt_no_log) 415 { 416 w2log("No MySQL servers to be stopped (check your GNRs)", 417 "$opt_log", 0, 0); 418 } 419} 420 421#### 422#### Sub function for mysqladmin option parsing 423#### 424 425sub get_mysqladmin_options 426{ 427 my ($i, @groups)= @_; 428 my ($mysqladmin_found, $com, $tmp, $j); 429 430 @options = defaults_for_group($groups[$i]); 431 432 $mysqladmin_found= 1; # The default 433 $mysqladmin_found= 0 if (!length($mysqladmin)); 434 $com = "$mysqladmin"; 435 $tmp = " -u $opt_user"; 436 if (defined($opt_password)) { 437 my $pw= $opt_password; 438 # Protect single quotes in password 439 $pw =~ s/'/'"'"'/g; 440 $tmp.= " -p'$pw'"; 441 } 442 $tmp.= $opt_tcp_ip ? " -h 127.0.0.1" : ""; 443 for ($j = 0; defined($options[$j]); $j++) 444 { 445 if ("--mysqladmin=" eq substr($options[$j], 0, 13)) 446 { 447 $options[$j]=~ s/\-\-mysqladmin\=//; 448 $com= $options[$j]; 449 $mysqladmin_found= 1; 450 } 451 elsif ((($options[$j] =~ m/^(\-\-socket\=)(.*)$/) && !$opt_tcp_ip) || 452 ($options[$j] =~ m/^(\-\-port\=)(.*)$/)) 453 { 454 $tmp.= " $options[$j]"; 455 } 456 } 457 if (!$mysqladmin_found) 458 { 459 print "\n"; 460 print "FATAL ERROR: Tried to use mysqladmin in group [$groups[$i]], "; 461 print "but no mysqladmin binary was found.\n"; 462 print "Please add \"mysqladmin=...\" in group [mysqld_multi], or "; 463 print "in group [$groups[$i]].\n"; 464 exit(1); 465 } 466 $com.= $tmp; 467 return $com; 468} 469 470# Return a list of option files which can be opened. Similar, but not 471# identical, to behavior of my_search_option_files() 472sub list_defaults_files 473{ 474 my %opt; 475 foreach (@defaults_options) 476 { 477 return () if /^--no-defaults$/; 478 $opt{$1} = $2 if /^--defaults-(extra-file|file)=(.*)$/; 479 } 480 481 return ($opt{file}) if exists $opt{file}; 482 483 my %seen; # Don't list the same file more than once 484 return grep { defined $_ and not $seen{$_}++ and -f $_ and -r $_ } 485 ('/etc/my.cnf', 486 '/etc/mysql/my.cnf', 487 '@sysconfdir@/my.cnf', 488 ($ENV{MYSQL_HOME} ? "$ENV{MYSQL_HOME}/my.cnf" : undef), 489 $opt{'extra-file'}, 490 ($ENV{HOME} ? "$ENV{HOME}/.my.cnf" : undef)); 491} 492 493 494# Takes a specification of GNRs (see --help), and returns a list of matching 495# groups which actually are mentioned in a relevant config file 496sub find_groups 497{ 498 my ($raw_gids) = @_; 499 500 my %gids; 501 my @groups; 502 503 if (defined($raw_gids)) 504 { 505 # Make a hash of the wanted group ids 506 foreach my $raw_gid (split ',', $raw_gids) 507 { 508 # Match 123 or 123-456 509 my ($start, $end) = ($raw_gid =~ /^\s*(\d+)(?:\s*-\s*(\d+))?\s*$/); 510 $end = $start if not defined $end; 511 if (not defined $start or $end < $start or $start < 0) 512 { 513 print "ABORT: Bad GNR: $raw_gid; see $my_progname --help\n"; 514 exit(1); 515 } 516 517 foreach my $i ($start .. $end) 518 { 519 # Use $i + 0 to normalize numbers (002 + 0 -> 2) 520 $gids{$i + 0}= 1; 521 } 522 } 523 } 524 525 my @defaults_files = list_defaults_files(); 526 #warn "@{[sort keys %gids]} -> @defaults_files\n"; 527 foreach my $file (@defaults_files) 528 { 529 next unless open CONF, "< $file"; 530 531 while (<CONF>) 532 { 533 if (/^\s*\[\s*(mysqld)(\d+)\s*\]\s*$/) 534 { 535 #warn "Found a group: $1$2\n"; 536 # Use $2 + 0 to normalize numbers (002 + 0 -> 2) 537 if (not defined($raw_gids) or $gids{$2 + 0}) 538 { 539 push @groups, "$1$2"; 540 } 541 } 542 } 543 544 close CONF; 545 } 546 return @groups; 547} 548 549#### 550#### w2log: Write to a logfile. 551#### 1.arg: append to the log file (given string, or from a file. if a file, 552#### file will be read from $opt_logdir) 553#### 2.arg: logfile -name (w2log assumes that the logfile is in $opt_logdir). 554#### 3.arg. 0 | 1, if true, print current date to the logfile. 3. arg will 555#### be ignored, if 1. arg is a file. 556#### 4.arg. 0 | 1, if true, first argument is a file, else a string 557#### 558 559sub w2log 560{ 561 my ($msg, $file, $date_flag, $is_file)= @_; 562 my (@data); 563 564 open (LOGFILE, ">>$opt_log") 565 or die "FATAL: w2log: Couldn't open log file: $opt_log\n"; 566 567 if ($is_file) 568 { 569 open (FROMFILE, "<$msg") && (@data=<FROMFILE>) && 570 close(FROMFILE) 571 or die "FATAL: w2log: Couldn't open file: $msg\n"; 572 foreach my $line (@data) 573 { 574 print LOGFILE "$line"; 575 } 576 } 577 else 578 { 579 print LOGFILE "$msg"; 580 print LOGFILE strftime "%a %b %e %H:%M:%S %Y", localtime if ($date_flag); 581 print LOGFILE "\n"; 582 } 583 close (LOGFILE); 584 return; 585} 586 587#### 588#### my_which is used, because we can't assume that every system has the 589#### which -command. my_which can take only one argument at a time. 590#### Return values: requested system command with the first found path, 591#### or undefined, if not found. 592#### 593 594sub my_which 595{ 596 my ($command) = @_; 597 my (@paths, $path); 598 599 # If the argument is not 'my_print_defaults' then it would be of the format 600 # <absolute_path>/<program> 601 return $command if ($command ne 'my_print_defaults' && -f $command && 602 -x $command); 603 604 @paths = split(':', $ENV{'PATH'}); 605 foreach $path (@paths) 606 { 607 $path .= "/$command"; 608 return $path if (-f $path && -x $path); 609 } 610 return undef(); 611} 612 613 614#### 615#### example 616#### 617 618sub example 619{ 620 print <<EOF; 621# This is an example of a my.cnf file for $my_progname. 622# Usually this file is located in home dir ~/.my.cnf or /etc/my.cnf 623# 624# SOME IMPORTANT NOTES FOLLOW: 625# 626# 1.COMMON USER 627# 628# Make sure that the MySQL user, who is stopping the mysqld services, has 629# the same password to all MySQL servers being accessed by $my_progname. 630# This user needs to have the 'Shutdown_priv' -privilege, but for security 631# reasons should have no other privileges. It is advised that you create a 632# common 'multi_admin' user for all MySQL servers being controlled by 633# $my_progname. Here is an example how to do it: 634# 635# GRANT SHUTDOWN ON *.* TO multi_admin\@localhost IDENTIFIED BY 'password' 636# 637# You will need to apply the above to all MySQL servers that are being 638# controlled by $my_progname. 'multi_admin' will shutdown the servers 639# using 'mysqladmin' -binary, when '$my_progname stop' is being called. 640# 641# 2.PID-FILE 642# 643# If you are using mysqld_safe to start mysqld, make sure that every 644# MySQL server has a separate pid-file. In order to use mysqld_safe 645# via $my_progname, you need to use two options: 646# 647# mysqld=/path/to/mysqld_safe 648# ledir=/path/to/mysqld-binary/ 649# 650# ledir (library executable directory), is an option that only mysqld_safe 651# accepts, so you will get an error if you try to pass it to mysqld directly. 652# For this reason you might want to use the above options within [mysqld#] 653# group directly. 654# 655# 3.DATA DIRECTORY 656# 657# It is NOT advised to run many MySQL servers within the same data directory. 658# You can do so, but please make sure to understand and deal with the 659# underlying caveats. In short they are: 660# - Speed penalty 661# - Risk of table/data corruption 662# - Data synchronising problems between the running servers 663# - Heavily media (disk) bound 664# - Relies on the system (external) file locking 665# - Is not applicable with all table types. (Such as InnoDB) 666# Trying so will end up with undesirable results. 667# 668# 4.TCP/IP Port 669# 670# Every server requires one and it must be unique. 671# 672# 5.[mysqld#] Groups 673# 674# In the example below the first and the fifth mysqld group was 675# intentionally left out. You may have 'gaps' in the config file. This 676# gives you more flexibility. 677# 678# 6.MySQL Server User 679# 680# You can pass the user=... option inside [mysqld#] groups. This 681# can be very handy in some cases, but then you need to run $my_progname 682# as UNIX root. 683# 684# 7.A Start-up Manage Script for $my_progname 685# 686# In the recent MySQL distributions you can find a file called 687# mysqld_multi.server.sh. It is a wrapper for $my_progname. This can 688# be used to start and stop multiple servers during boot and shutdown. 689# 690# You can place the file in /etc/init.d/mysqld_multi.server.sh and 691# make the needed symbolic links to it from various run levels 692# (as per Linux/Unix standard). You may even replace the 693# /etc/init.d/mysql.server script with it. 694# 695# Before using, you must create a my.cnf file either in @sysconfdir@/my.cnf 696# or /root/.my.cnf and add the [mysqld_multi] and [mysqld#] groups. 697# 698# The script can be found from support-files/mysqld_multi.server.sh 699# in MySQL distribution. (Verify the script before using) 700# 701 702[mysqld_multi] 703mysqld = @bindir@/mysqld_safe 704mysqladmin = @bindir@/mysqladmin 705user = multi_admin 706password = my_password 707 708[mysqld2] 709socket = /tmp/mysql.sock2 710port = 3307 711pid-file = @localstatedir@2/hostname.pid2 712datadir = @localstatedir@2 713language = @datadir@/mysql/english 714user = unix_user1 715 716[mysqld3] 717mysqld = /path/to/mysqld_safe 718ledir = /path/to/mysqld-binary/ 719mysqladmin = /path/to/mysqladmin 720socket = /tmp/mysql.sock3 721port = 3308 722pid-file = @localstatedir@3/hostname.pid3 723datadir = @localstatedir@3 724language = @datadir@/mysql/swedish 725user = unix_user2 726 727[mysqld4] 728socket = /tmp/mysql.sock4 729port = 3309 730pid-file = @localstatedir@4/hostname.pid4 731datadir = @localstatedir@4 732language = @datadir@/mysql/estonia 733user = unix_user3 734 735[mysqld6] 736socket = /tmp/mysql.sock6 737port = 3311 738pid-file = @localstatedir@6/hostname.pid6 739datadir = @localstatedir@6 740language = @datadir@/mysql/japanese 741user = unix_user4 742EOF 743 exit(0); 744} 745 746#### 747#### usage 748#### 749 750sub usage 751{ 752 print <<EOF; 753$my_progname version $VER by Jani Tolonen 754 755Description: 756$my_progname can be used to start, or stop any number of separate 757mysqld processes running in different TCP/IP ports and UNIX sockets. 758 759$my_progname can read group [mysqld_multi] from my.cnf file. You may 760want to put options mysqld=... and mysqladmin=... there. Since 761version 2.10 these options can also be given under groups [mysqld#], 762which gives more control over different versions. One can have the 763default mysqld and mysqladmin under group [mysqld_multi], but this is 764not mandatory. Please note that if mysqld or mysqladmin is missing 765from both [mysqld_multi] and [mysqld#], a group that is tried to be 766used, $my_progname will abort with an error. 767 768$my_progname will search for groups named [mysqld#] from my.cnf (or 769the given --defaults-extra-file=...), where '#' can be any positive 770integer starting from 1. These groups should be the same as the regular 771[mysqld] group, but with those port, socket and any other options 772that are to be used with each separate mysqld process. The number 773in the group name has another function; it can be used for starting, 774stopping, or reporting any specific mysqld server. 775 776Usage: $my_progname [OPTIONS] {start|stop|report} [GNR,GNR,GNR...] 777or $my_progname [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...] 778 779The GNR means the group number. You can start, stop or report any GNR, 780or several of them at the same time. (See --example) The GNRs list can 781be comma separated or a dash combined. The latter means that all the 782GNRs between GNR1-GNR2 will be affected. Without GNR argument all the 783groups found will either be started, stopped, or reported. Note that 784syntax for specifying GNRs must appear without spaces. 785 786Options: 787 788These options must be given before any others: 789--no-defaults Do not read any defaults file 790--defaults-file=... Read only this configuration file, do not read the 791 standard system-wide and user-specific files 792--defaults-extra-file=... Read this configuration file in addition to the 793 standard system-wide and user-specific files 794Using: @{[join ' ', @defaults_options]} 795 796--example Give an example of a config file with extra information. 797--help Print this help and exit. 798--log=... Log file. Full path to and the name for the log file. NOTE: 799 If the file exists, everything will be appended. 800 Using: $opt_log 801--mysqladmin=... mysqladmin binary to be used for a server shutdown. 802 Since version 2.10 this can be given within groups [mysqld#] 803 Using: $mysqladmin 804--mysqld=... mysqld binary to be used. Note that you can give mysqld_safe 805 to this option also. The options are passed to mysqld. Just 806 make sure you have mysqld in your PATH or fix mysqld_safe. 807 Using: $mysqld 808 Please note: Since mysqld_multi version 2.3 you can also 809 give this option inside groups [mysqld#] in ~/.my.cnf, 810 where '#' stands for an integer (number) of the group in 811 question. This will be recognised as a special option and 812 will not be passed to the mysqld. This will allow one to 813 start different mysqld versions with mysqld_multi. 814--no-log Print to stdout instead of the log file. By default the log 815 file is turned on. 816--password=... Password for mysqladmin user. 817--silent Disable warnings. 818--tcp-ip Connect to the MySQL server(s) via the TCP/IP port instead 819 of the UNIX socket. This affects stopping and reporting. 820 If a socket file is missing, the server may still be 821 running, but can be accessed only via the TCP/IP port. 822 By default connecting is done via the UNIX socket. 823--user=... mysqladmin user. Using: $opt_user 824--verbose Be more verbose. 825--version Print the version number and exit. 826EOF 827 exit(0); 828} 829