#!/usr/bin/perl ################################################################################ mysql/mariadb backup (mwx'2021) use Getopt::Std;getopts('bza'); use DBI; use Term::ReadKey; $VERSION='4.0.0'; $HOST = 'localhost'; # settings $USER = 'mybackup'; $PASSWD = 'iexae3aitathoo4k'; $PATH = '/db/backup/mysql'; $KEEPDAILYBACKUPS = 21; $TAR = "/bin/tar"; $RM = "/bin/rm"; $MYSQLDUMP = "/usr/bin/mysqldump"; $GZIP = "/bin/gzip"; if (!$opt_a && !$opt_b && !$opt_z) { # show usage print <<"ENDOFHELP"; mybackup, MySQL/MariaDB backup, mwx'2021, v$VERSION usage: mybackup -a add backup user to db (root password required) mybackup -b run database backup mybackup -z run database backup and compress output ENDOFHELP exit(0); } if ($opt_a) { # add backup user to db use Term::ReadPassword; $rootdbpw = read_password('Enter password: '); $dbh=DBI->connect("DBI:mysql:mysql:localhost:","root",$rootdbpw,{RaiseError=>1,PrintError=>1}); $dbh->do("CREATE USER 'mybackup' IDENTIFIED BY '$PASSWD'"); $dbh->do("GRANT SELECT, SHOW VIEW, LOCK TABLES, RELOAD,REPLICATION CLIENT ON *.* TO 'mybackup'"); # # # # CREATE USER 'mybackup' IDENTIFIED BY 'Yooch0esh9Ah'; # # # $sth=$dbh->prepare("SHOW COLUMNS FROM user");$sth->execute; # find authentication fields # $HASPW=0;$HASAS=0; # while ($dat = $sth->fetchrow_hashref) { # $HASPW=1 if ($$dat{Field} eq 'Password'); # $HASAS=1 if ($$dat{Field} eq 'authentication_string'); # } # # $sql="INSERT INTO user SET User='$USER',Host='localhost',"; # $sql.="Password=password('$PASSWD')," if ($HASPW); # $sql.="authentication_string=password('$PASSWD')," if ($HASAS); # $sql.="ssl_cipher='',x509_issuer='',x509_subject='',". # "Select_priv='Y',Reload_priv='Y',Lock_tables_priv='Y',Show_view_priv='Y',Process_priv='Y'"; # # $dbh->do($sql); $dbh->do("flush privileges"); if (&yesno('Write /root/.my.cnf file',1)) { system("rm -f /root/.my.cnf"); open(OUT,"> /root/.my.cnf"); print OUT "[client]\nuser=root\npassword=$rootdbpw\n[mysqldump]\nuser=mybackup\npassword=$PASSWD\n"; close(OUT); system("chmod 600 /root/.my.cnf"); } &setupcron(); exit; } &cleanup(); @DBS=&autogetdbs(); my(@z)=localtime(time());$z[4]+=1;$z[6]+=1;$z[5]-=100; $z=sprintf("%02d%02d%02d%02d%02d%02d",$z[3],$z[4],$z[5],$z[2],$z[1],$z[0]); if (!-d "$PATH/$z") { # make target dir mkdir("$PATH/$z",448); } for $db (@DBS) { # dump databaeses if ($db ne 'information_schema' && $db ne 'performance_schema' && $db ne 'sys') { my($fdb)=$db;$fdb=~s/\s/\./g; if (!$IGNOREDB{$db}) { if ($DBPARAM{$db}) {;$db=$DBPARAM{$db};} &cmd("$MYSQLDUMP -h $HOST -u $USER -f -F -R --skip-extended-insert $db >$PATH/$z/$fdb.mysql"); } } } $cmd="$MYSQLDUMP -h $HOST -u $USER -c -f -F -R --skip-extended-insert -A -v >$PATH/$z.mysql"; &cmd($cmd); &cmd("$GZIP $PATH/$z.mysql"); chdir($PATH); if (-d "$PATH/$z" && $opt_z) { &cmd("$TAR czvf $z.tar.gz $z"); &cmd("$RM -rf $PATH/$z"); } ######################################################################################################## SUPPORT sub cleanup() { use Date::Parse; opendir(DIR,"$PATH"); while($file=readdir(DIR)) { if (-f "$PATH/$file" && $file=~/(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/) { $m=$1; $a=$3+2000; $time = str2time("$a/$2/$1 $4:$5:$6"); my(@z)=localtime($time);$z[4]+=1;$z[5]-=100;$z[6]+=1; $z=sprintf("%02d\.%02d\.%02d %02d\:%02d\:%02d",$z[3],$z[4],$z[5],$z[2],$z[1],$z[0]); $t=(time()-$time)/86400; if ($m!=1 && $t>$KEEPDAILYBACKUPS) { &cmd("/bin/rm -f $PATH/$file") if (-f "$PATH/$file"); } } } } sub setupcron() { open(CRON,"crontab -l |"); while() { chomp(); push(@CRON,$_) if (!/\/db\/bin\/mybackup/); } push(@CRON,"0 12 * * * /db/bin/mybackup -z > /dev/null 2>&1"); open(OUT,"> /tmp/cron.$$"); for (@CRON) { print OUT "$_\n"; } close(OUT); system("/usr/bin/crontab /tmp/cron.$$"); system("rm -f /tmp/cron.$$"); } sub cmd() { my($cmd)=@_; print "$cmd\n"; system($cmd); } sub autogetdbs() { my(@dbs); $dbh=DBI->connect("DBI:mysql::$HOST:",$USER,$PASSWD,{RaiseError=>1,PrintError=>1}); $sth=$dbh->prepare("SHOW DATABASES");$sth->execute ; while ($dat = $sth->fetchrow_hashref) { push(@dbs,$$dat{Database}); } return (@dbs); } sub yesno { my($prom,$def)=@_; my($ans); if ($def) {;$ans=&getkey("$prom Y/n ? ");} else {;$ans=&getkey("$prom y/N ? ");} if ($ans=~/^\s*$/) { if ($def) {;return(1);} else {;return(0);} } if ($ans=~/^\s*y\s*$/i || $ans=~/^\s*yes\s*$/i) { return 1; } return 0; } sub getkey { $|=1; print "$_[0]"; system "stty", '-icanon', '-echo', 'eol', "\001"; $key = getc(STDIN);$key=~s/[\r\n\t]//g; system "stty", 'icanon', 'echo', 'eol', "^@"; print "$key\n"; return $key; } ############################################################################################################ END