#!/usr/bin/perl -w # # A script for making backups of InnoDB and MyISAM tables, indexes and .frm # files. # # Copyright 2003, 2009 Innobase Oy. All Rights Reserved. # use strict; use Getopt::Long; use POSIX "strftime"; use POSIX ":sys_wait_h"; use POSIX "tmpnam"; use FileHandle; use File::Basename; $ENV{PATH}= dirname($ENV{EXE_MYSQL}).(":").$ENV{PATH}; my $mysql_stdout='mysql-stdout'; my $mysql_stderr='mysql-stderr'; my $mysql_port= $ARGV[0]; my $hello_id = 0; my $options = "--unbuffered --host=127.0.0.1 --user=tom --port=$mysql_port"; my $mysql_pid= 0; $SIG{PIPE} = \&catch_sigpipe; sub Die { my $message = shift; my $extra_info = ''; # kill all child processes of this process kill_child_processes(); die "innobackup Error: $message$extra_info"; } sub catch_sigpipe { my $rcode; if ($mysql_pid && (-1 == ($rcode = waitpid($mysql_pid, &WNOHANG)) || $rcode == $mysql_pid)) { my $reason = `cat $mysql_stderr`; print "Pipe to mysql child process broken: $reason at"; system("date +'%H:%M:%S'"); exit(1); } else { Die "Broken pipe"; } } $SIG{PIPE} = \&catch_sigpipe; sub kill_child_processes { if ($mysql_pid) { kill(15, $mysql_pid); $mysql_pid = ''; } } sub current_time { return strftime("%y%m%d %H:%M:%S", localtime()); } # run mysql as a child process with a pipe connection my $now = current_time(); print "$now innobackup Starting mysql with options: $options\n"; $mysql_pid = open(*MYSQL_WRITER, "| mysql $options >$mysql_stdout 2>$mysql_stderr ") or Die "Failed to spawn mysql child process: $!"; MYSQL_WRITER->autoflush(1); $now = current_time(); print "$now innobackup Connected to database with mysql child process (pid=$mysql_pid)\n"; my $hello_message = "innobackup hello $hello_id"; print MYSQL_WRITER "select '$hello_message';\n" or Die "Connection to mysql child process failed: $!"; # mysql check code comes now # wait for reply eval { local $SIG{ALRM} = sub { kill_child_processes(); die "alarm clock restart" }; my $stdout = ''; my $stderr = ''; alarm 900; while (index($stdout, $hello_message) < 0) { sleep 2; if ($mysql_pid && $mysql_pid == waitpid($mysql_pid, &WNOHANG)) { my $reason = `cat $mysql_stderr`; $mysql_pid = ''; kill_child_processes(); die "satya: mysql child process has died: $reason"; } $stdout = `cat $mysql_stdout`; $stderr = `cat $mysql_stderr`; if ($stderr) { # mysql has reported an error, do exit kill_child_processes(); die "mysql error: $stderr"; } } alarm 0; }; if ($@ =~ /alarm clock restart/) { Die "Connection to mysql child process (pid=$mysql_pid) timedout." . " (Time limit of 900 seconds exceeded." . " You may adjust time limit by editing the value of parameter" . " \"\$mysql_response_timeout\" in this script.)"; } elsif ($@) { Die $@; }