#!/usr/local/bin/perl -w ## MEId: confluence/ibin/mysql/mysql_watch,v 1.6 2006/05/10 23:47:16 mbelnap Exp $ # # This script checks whether mysql is running for all users which # desire it, and restarts it as necessary. # It works in a single shot and should be scheduled to run as appropriate. # use strict; use Getopt::Long; use Pod::Usage; # parse arguments. my $help = ''; my $verbose = ''; my $dryrun = ''; GetOptions('verbose' => \$verbose, 'dryrun|n' => \$dryrun, 'help|?' => \$help, ) or pod2usage(2); pod2usage(0) if $help; # make sure this script is not already running under another PID -- # Get an exclusive lock and leave the file open until we exit. my $pidfile = "/var/run/mysql_watch.pid"; use Fcntl qw(:DEFAULT :flock); sysopen(FH, $pidfile, O_RDWR | O_CREAT) or die "ERROR: can't open $pidfile: $!"; flock(FH, LOCK_EX | LOCK_NB) or die "ERROR: can't lock $pidfile: $!"; truncate(FH, 0) or die "ERROR: can't truncate $pidfile: $!"; my $oldfh = select FH; $| = 1; select $oldfh; print FH $$; # get accountid my $accountid = `cat /etc/ctrinfo.json | jq -r '.server_admin'`; chomp($accountid); print("account id: $accountid\n"); # get current version my $unitname = ""; my $ver = ""; my $path1 = ""; my $path2 = ""; if( -l "/etc/my.cnf" ) { my $currentlink=readlink("/etc/my.cnf"); print("Current link is $currentlink\n"); if ( $currentlink =~ /\/etc\// ) { ( $path1, $path2, $ver ) = split (/\//, $currentlink ); print("Current ver is $ver\n"); } else { $ver = "$currentlink"; } if ( $ver =~ /my.cnf-mysql84/ ) { $unitname = "mysqld84"; } if ( $ver =~ /my.cnf-mysql80/ ) { $unitname = "mysqld8"; } if ( $ver =~ /my.cnf-mysql57/ ) { $unitname = "mysqld"; } } else { $unitname = "mysqld"; } print("Unit file name is $unitname\n"); my @psinfo; my $netstat_connceted; my $alarm_time = 30; eval { local $SIG{ALRM} = sub { die "pgrep_timeout"}; alarm $alarm_time; $netstat_connceted = `netstat -nap | grep CONNECTED | grep /var/lib/mysql/mysql.sock | wc -l`; chomp($netstat_connceted); @psinfo = `pgrep -fla 'mysqld' -u 27`; if ( $? == 0 && $netstat_connceted < 150 ) { print("OK: mysqld is running for $accountid\n"); exit(0); } else { print("ERROR: current mysql connection num \($netstat_connceted\) reached 150 or pgrep command error \n"); } alarm 0; }; if ($@) { if ($@ =~ /pgrep_timeout/) { print "ERROR: command pgrep timeout!\n"; } else { alarm 0; } } # mis-configuration should log. if( !-e "/usr/home/$accountid" ) { exit(1); } # check existing processes. my @lines; @lines = `/usr/bin/systemctl is-enabled $unitname`; if ( $? != 0 ) { print("OK: mysqld is stopped as disabled\n"); exit(0); } print("Starting account mysqld via script..\n"); # if mysqld is enabled $alarm_time = 90; eval { local $SIG{ALRM} = sub { die "restart_timeout"}; alarm $alarm_time; @psinfo = `systemctl restart $unitname`; if ( $? == 0 ) { print("OK: mysqld is running for $accountid\n"); exit(0); } alarm 0; }; if ($@) { if ($@ =~ /restart_timeout/) { print "command restart timeout!\n"; } else { alarm 0; } } # Fix mysqld proccess print("ERROR: mysqld enabled but not running for $accountid\n"); # Kill mysqld my $mysql_pid = `ps auxww | grep -e '/usr/sbin/mysqld' -e '/usr/local/mysql/bin/mysqld' -e '/usr/local/mysql84/bin/mysqld'| grep -v grep | awk '{print \$2}'`; if ($mysql_pid) { my $ret = `kill -9 $mysql_pid`; print("kill mysqld proccess. PID: $mysql_pid"); } # Start mysqld $alarm_time = 30; my $start_ret = 0; eval { local $SIG{ALRM} = sub { die "start_timeout"}; alarm $alarm_time; $start_ret = system( '/usr/bin/systemctl', 'start', $unitname ); if ( $? == 0 ) { print("OK: mysqld is running for $accountid\n"); exit(0); } alarm 0; }; if ($@) { if ($@ =~ /start_timeout/) { print "command start timeout!\n"; } else { alarm 0; } } my $exit_value = $start_ret >> 8; my $signal_num = $start_ret & 127; my $dumped_core = $start_ret & 128; system( '/usr/local/bin/snmptrap.sh', 'mysql' ); print("ERROR: mysql start ret:$exit_value sig:$signal_num core:$dumped_core for $accountid\n"); print("Done!\n"); __END__ =head1 NAME B - check and restart mysql processes on the server. =head1 SYNOPSIS B [options] B [-n] | [-dryrun] [[-]-v[erbose]] [[-]-h[elp]] =head1 DESCRIPTION B is a simple script that checks a number of conditions that indicate whether mysql is functioning properly for individual users. It utilizes both output from ps as well as key file checks. In the end, it attempts to restart mysql for users who do not already have it running (unless the -n dry-run option is specified). It logs pertinent information along the way. =head1 OPTIONS B's behavior is controlled by a number of commandline options: =over 4 =item B<-n>, B<--dryrun> This option enables non-intrusive checking without attempting restarts. =item B<-v>, B<--verbose> This directs B to output more informative information. (not enabled) =item B<-h>, B<--help> Prints a simple help message. =back =head1 EXAMPLES B Starts B in the default operational mode. B -n Just obtain a check of the status of all mysql processes. =head1 RESTRICTIONS some =head1 BUGS probably =head1 AUTHOR Mark Belnap (mbelnap@veiro.net) s/ir/ri/ Kazuya Noguchi (kazuya.noguchi@ntt.com) s/ir/ri/