196 lines
5.4 KiB
Perl
Executable File
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
|