作者:田逸(formyz)
目标需求
接到一个任务,需要在凌晨四点对一个数据库进行备份,不是进行全库备份,而是只对制定的数据库进行逐一导出,并生成以库为关键字的“.sql”文件。数据库的版本为MySQL 8.0.28 MySQL Community Server,存在三个以“v8_”为前缀的独立数据库(如下图所示)。
需求方还进一步要求,备份的“sql”文件带日期,如“202402230400v8_byzz.sql”。
虽然只要三个需要备份的数据库,数据量也不是很大,手动执行“mysqldump”逐一备份也不是什么问题,但是因为身体原因,那个时候起来熬夜甚是疲惫,昏昏沉沉很可能出错。于是就写一个MySQL自动备份的脚本,交给系统让其在凌晨四点的时候自动执行。
Shell脚本思路
登录MySQL数据库,查询所有数据库并抽取制定的数据库。用指令“mysql -e”与“grep”组合,就可以到达目的,具体的操作就输出如下。
[root@MySQL-T-200-125 ~]#mysql -p -e 'show databases' |grep v8_ v8_byzz v8_jzcj v8_zxg |
mysql -p -e 'show databases' |grep v8_
将上述的输出数据库库名做为参数,遍历此参数表,以变量的形式传递给备份工具“mysqldump”。具体的做法是定义一个变量,将数据库表名赋值给该变量,具体的语句如下。
DBS=$( mysql -p -e 'show databases' |grep v8_) for i in $DBS do mysqldump --set-gtid-purged=OFF $i … done |
为验证思路的正确性、避免风险,撰写一个完整的脚本,将备份的脚本中“mysqldump”指令改成“echo”,逐行输出库名,完整的Shell脚本(文件被命名为bkdb.sh)内容如下.
#!/bin/bash source /etc/profile DBS=$( mysql -p -e 'show databases' |grep v8_) for i in $DBS do echo $(date +%Y%m%d)$i.sql done |
系统命令行,运行这个脚本,具体的指令和操作如下。
[root@MySQL-T-200-125 ~]# sh -n bkdb.sh [root@MySQL-T-200-125 ~]# sh bkdb.sh 20240224v8_byzz.sql 20240224v8_jzcj.sql 20240224v8_zxg.sql |
sh -n bkdb.sh
sh bkdb.sh
输出的确如我所期待,再将“echo”所在的行改成“mysqldump”备份的文本,修改后的备份脚本“bkdb.sh”的完整内容如下。
#!/bin/bash source /etc/profile DBS=$( mysql -p -e 'show databases' |grep v8_) for i in $DBS do mysqldump --set-gtid-purged=OFF $i>/backup/$(date +%Y%m%d)$i.sql done |
手动执行备份脚本“bkdb.sh”,通过查验备份目录“/backup”看是否生成相应的“.sql”验证脚本的有效性和正确性。在执行这个脚本时,会有警告信息出现,如下图所示。
这个警告,是MySQL的一种的保护机制,它的要求是:不要在“mysql”指令与“mysqldump”指令后,不要显示的指定密码选项“-p”。如何解决这个问题呢?我采取的措施是在MySQL的选项文件“/etc/my.cnf”做更新,修改或新增后的文本内容如下.
[mysql] default-character-set = utf8 socket = /tmp/mysql.sock host = localhost user = root password = 'UAtmvMi0xGhihu' [mysqldump] default-character-set = utf8 socket = /tmp/mysql.sock host = localhost user = root password = 'UAtmvMi0xGhihu' |
保存修改,再对MySQL备份脚本“bkdb.sh”做修改,去掉命令行选项“-p”,再次执行脚本,验证其有效性及正确性。此时执行脚本,不需输入密码,也不在警告。
启动自动备份任务
运行命令“systemctl status crond”查验服务“crond”处于运行状态,如果状态不是“active”,需要执行命令手动启动。
执行命令 “crontab -e”编辑自动任务,增加如下文本行。
00 04 * * * sh /usr/local/bin/v8_bk.sh |
如果担心脚本到设定的时间不会执行,可以将备份脚本稍微修改一下,仅备份一个数据量小的数据库,执行时间改动到离当前时间比较近的时间点,比如现在是夜里8:35,就将执行时间改到“40 22”(20点40分)。五分中通过查看备份目录是否生成文件、系统进程列表之中是否存在“mysqldump”、日志文件“/var/log/cron”是否存在执行脚本的记录(如下图所示)。无误后,再恢复备份脚本和将计划任务的时间设定到凌晨四点。