Files
2026-08-10 16:12:09 +02:00

196 lines
5.4 KiB
Perl
Executable File

#!/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(<CRON>) {
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