在做项目的时候,经常会需要对数据库进行备份,基于Linux系统下的操作我还是第一次做,所以在网上查询了很多资料,分别参考了https://www.cnblogs.com/batsing/p/4938986.html 和 https://www.cnblogs.com/ityouknow/p/5923489.html的配置,探索的过程总是艰辛的,并不是那么一帆风顺,期间遇到了很多问题,下面我会给出脚本和在使用过程中遇到的问题。话不多说,直接看过程吧。
一、mysql提供了一个mysqldump的工具可以方便的导出导入数据库信息;
二、使用命令行shell测试执行mysqldump,理解必备的参数,查看生成的sql备份文件是否符合需求;
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_ZFBM $DB_NAME $DB_TABLE > $BCK_DIR/db_$DATE.sql
脚本说明:
$BIN_DIR mysql备份地址
$DB_USER 数据库用户名
$DB_PASS 数据库密码
$DB_HOST 数据库地址(IP或者是localhost之类的)
$DB_ZFBM 字符集编码设置(这个很关键,解决导出文件中中文乱码)
$DB_NAME 数据库名称
$DB_TABLE 要备份的表名(如果只对单一表进行备份,可以加此字段,全库备份的可以省略掉)
$BCK_DIR/db_$DATE.sql 备份的地址和备份文件名称
三、下面是我亲自试验过得,在两位前辈的基础上加以修改过的脚本
#!/bin/bash
# Name:bakmysql.sh
# This is a ShellScript For Auto DB Backup and Delete old Backup
#
# Database info
DB_USER="root" #mysql login name
DB_PASS="123456" #password
DB_HOST="localhost" #db_address
DB_NAME="bosh_education" #db_name
DB_ZFBM="--default-character-set=utf8" #character
DB_TABLE="exam_quest_bank" #table name
# Others vars
BIN_DIR="/usr/bin" #the mysql bin path
BCK_DIR="/usr/mysqlbeifen" #the backup file directory
DATE=`date +%F`
#--skip-lock-tables zg backup
#$BIN_DIR/mysqldump -u $DB_USER -p$DB_PASS $DB_ZFBM $DB_NAME $DB_TABLE | gzip > $BCK_DIR/db_$DATE.sql.gz
#sql back
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_ZFBM $DB_NAME $DB_TABLE > $BCK_DIR/db_$DATE.sql
#
find $BCK_DIR -name "db_*.sql" -type f -mtime +3 -exec rm {} \; > /dev/null 2>&1
#
完成文件后保存并上传到指定的目录下(/usr/local/apache/htdocs/timepusher/sqlBak/)如下图所示:
四、测试脚本是否可用
1、进入到该脚本文件目录
cd /usr/local/apache/htdocs/timepusher/sqlBak
2、给刚才的脚本附加权限(否则会报错 Permission denied )
chmod +x bakmysql.sh
3、在此目录下执行脚本,验证脚本是否正确
./bakmysql.sh
此时我也遇到了前面两位笔者提到的错误,提示如下:
/bin/sh^M: bad interpreter: No such file or directory
这是因为在windows编写上传的文件导致,是不同系统编码格式引起的:在 windows系统中编辑的 .sh文件可能有不可见字符,所以在 Linux系统下执行会报以上异常信息。可以在Windows上使用Notepad++转换成Unix格式(菜单中选择:编辑>档案格式转换>转换成UNIX),按照此不方法操作后即可正常执行了。操作如下:
4、修改后上传继续执行 ./bakmysql.sh ,没有报错。再查看导出的sql文件。如下图所示:
到此就完成了所有的脚本编写和测试。下面再详细说一下导出时候的脚本语言:
$BIN_DIR/mysqldump -u $DB_USER -p$DB_PASS $DB_ZFBM $DB_NAME $DB_TABLE | gzip > $BCK_DIR/db_$DATE.sql.gz
$BIN_DIR/mysqldump -u $DB_USER -p$DB_PASS $DB_ZFBM $DB_NAME | gzip > $BCK_DIR/db_$DATE.sql.gz
由于导出整个数据的文件较大,所以建议使用压缩文件的形式,上述是导出压缩文件的脚本,加上表名($DB_TABLE)可以指定表导出,不加表名的导出整个数据库表,根据自己的情况实际使用。直接导出sql文件的也是这个道理,就不细说了。
由于每天定时备份数据库,会导致很占内存,所以此处也给出了定时删除备份数据库的脚本,如下所示:
find $BCK_DIR -name "db_*.sql" -type f -mtime +3 -exec rm {} \; > /dev/null 2>&1
解释一下:
-type f 表示查找普通类型的文件,f表示普通文件。
-mtime +3 按照文件的更改时间来查找文件,+3表示文件更改时间距现在3天以前;如果是 -mmin +5 表示文件更改时间距现在5分钟以前。
-exec rm {} \; 表示执行一段shell命令,exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{},一个空格和一个,最后是一个分号。
/dev/null 2>&1 把标准出错重定向到标准输出,然后扔到/DEV/NULL下面去。通俗的说,就是把所有标准输出和标准出错都扔到垃圾桶里面;其中的& 表示让该命令在后台执行。
五、定时脚本的编写
1、编辑定时任务列表
crontab -e
如下图所示:
2、按【i】键进入编辑权限,插入如下脚本,按【Esc】后输入:wq即可保存退出编辑了:
#每天早上 5:00am 执行
00 05 * * * /bin/sh /usr/local/apache/htdocs/timepusher/sqlBak/bakmysql.sh
定时的一些说明:
crontab配置文件格式如下:
分 时 日 月 周 命令
3、查看设置的定时任务是否成功:
crontab -l
如下图所示:
4、重启crontab(分别有给出了别的操作命令)
#重启
/bin/systemctl restart crond.service
#开启
/bin/systemctl start crond.service
#停止
/bin/systemctl stop crond.service
#重载
/bin/systemctl reload crond.service
#状态
/bin/systemctl status crond.service
六、第二天记得检查是否备份成功(也可以改时间校验,自己决定)
如果生成的文件和解压出来查看没有问题,那么这个自动定时备份数据库的脚本就算是完成了。
像前面了两位笔者致敬,我是站在巨人的肩膀上完成的任务,这是我第一次搞这个,所以参考的比较多,像第一位笔者出现的最后一个问题,我是没遇到,可以先记下来,方便以后出问题的时候查看:
问题描述为:如果该数据库的用户没有分配 锁表 的权限,则备份会报错 when using LOCK TABLES 。那是因为mysqldump命令默认在导出时是要锁定表的,所以解决方式有两个。一个是给该用户开放 锁表 的权限;另一个是在命令中加上 --skip-lock-tables 这个参数。即是:
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_NAME --skip-lock-tables| gzip > $BCK_DIR/db_$DATE.sql.gz
留此贴以方便之后自己查看!!