Linux定时任务+Mailx实现数据库自动备份并发送备份文件到指定邮箱

前段时间不是出了腾讯云服务器丢失导致一家创业公司几乎被摧毁的事件嘛,云服务终归不是百分之百可靠,虽然我还是比较相信阿里,但是有备无患不是吗;服务器上的数据库我是有每天做定时备份的,但都是备份到服务器本地,现在我想的是,能不能把备份的文件文件定时发送到我自己的邮箱,多做一份远程备份;这里就用到了mailx发送邮件的功能了;

先要说一下的是,现在很多博客文档复制粘贴的太多了,我找的好多mailx的教程都是各种不能用,后面各种折腾终于配置成功后我决定要自己写一篇博文记录一下;

一、安装和配置mailx

首先需要安装mailx,yum安装方式非常简单

1
yum install mailx -y

配置:配置文件默认是/etc/mail.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vim /etc/mail.rc
# 直接在文件末尾添加如下内容:

set ssl-verify=ignore
# 这里使用的是我服务器的默认位置,此处有个坑,下面会讲
set nss-config-dir=/etc/pki/nssdb
# 发送地址
set from=123456@qq.com
# 邮件服务商smtp服务地址
set smtp=smtps://smtp.qq.com:465
# 登陆邮箱,同上发送地址相同即可
set smtp-auth-user=123456@qq.com
# 邮箱登陆授权密码,不是登陆密码,SMTP服务通常都是授权码登陆,开通SMTP服务时会提供登陆授权码
# 具体怎么开通SMTP服务及获取授权码请自行百度,这里不作展开
set smtp-auth-password=abcabc
set smtp-auth=login

正常来说,这么配置完成之后就可以使用mailx命令发送邮件了;

发送一封测试邮件:

1
2
3
4
5
6
mailx -vs "测试邮件" -a ./test.txt xianjian-mail@qq.com<./test.txt
命令参数说明:
-v 是显示发送过程
-s 是指定邮件主题
-a 是发送附件,后面是附件文件地址
邮件地址后面的 <./test.txt 是写入到邮件正文的文本文件地址,需要提前编辑好

发送成功显示内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Resolving host smtp.qq.com . . . done.
Connecting to 14.17.57.241:465 . . . connected.
Error in certificate: Peer's certificate issuer is not recognized.
Comparing DNS name: "pop.qq.com"
Comparing DNS name: "ex.qq.com"
Comparing DNS name: "imap.exmail.qq.com"
Comparing DNS name: "rtx.exmail.qq.com"
Comparing DNS name: "smtp.exmail.qq.com"
Comparing DNS name: "mxbiz1.qq.com"
Comparing DNS name: "mx1.qq.com"
Comparing DNS name: "cloudmx.qq.com"
Comparing DNS name: "mx2.qq.com"
Comparing DNS name: "dav.qq.com"
Comparing DNS name: "mxbiz2.qq.com"
Comparing DNS name: "smtp.qq.com"
SSL parameters: cipher=AES-128, keysize=128, secretkeysize=128,
issuer=CN=GeoTrust RSA CA 2018,OU=www.digicert.com,O=DigiCert Inc,C=US
subject=CN=pop.qq.com,OU=R&D,O=Shenzhen Tencent Computer Systems Company Limited,L=Shenzhen,ST=Guangdong,C=CN
220 smtp.qq.com Esmtp QQ Mail Server
>>> EHLO qingbaobao
250-smtp.qq.com
250-PIPELINING
250-SIZE 73400320
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN
250-MAILCOMPRESS
250 8BITMIME
>>> AUTH LOGIN
334 VXNlcm5hbWU6
>>> MjQzODE4MTczQHFxLmNvbQ==
334 UGFzc3dvcmQ6
>>> andsemJycmR0aWlqY2FnZA==
235 Authentication successful
>>> MAIL FROM:<243818173@qq.com>
250 Ok
>>> RCPT TO:<xianjian-mail@qq.com>
250 Ok
>>> DATA
354 End data with <CR><LF>.<CR><LF>
>>> .
250 Ok: queued as
>>> QUIT
221 Bye

如果有问题请看下面:

  1. 以上第二行配置:set nss-config-dir=/etc/pki/nssdb;我的服务器是Centos7 默认的文件位置是:/etc/pki/nssdb,如果不确定使用find命令搜索一下;

    1
    find / -name "cert*.db"

    如果nss-config-dir配置错误会有如下提示:

    1
    2
    3
    4
    5
    Resolving host smtp.qq.com . . . done.
    Connecting to 14.17.57.241:465 . . . connected.
    Error initializing NSS: Unknown error -8015.
    "/root/dead.letter" 29/821
    . . . message not sent.
  2. 正常来说,使用smtp://smtp.qq.com服务器就能发送邮件了,但我这里配置的是smtps://smtp.qq.com:465,这里是因为阿里云出于安全考虑,默认封禁TCP 25端口出方向的访问流量,所以这里改用465端口;

    详情看这里:https://help.aliyun.com/knowledge_detail/56130.html,确实需要使用25端口可以按照步骤提交解封;

    如果直接使用25端口发送会有下面的提示,并且一直无响应直到超时:

    1
    2
    Resolving host smtp.qq.com . . . done.  
    Connecting to 14.18.245.164:smtp . . .

二、配置备份脚本

邮件能发送了,那么现在开始配置备份脚本,实现把备份出来的sql文件打包发送到自己的邮箱上;

先贴上我自己写的备份脚本,非常简单,没什么技术含量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 备份邮箱  改成自己的邮箱
MAIL=xianjian-mail@qq.com

# 数据库源 改成自己的配置
HOST=localhost
USERNAME=root
PASSWORD=root

# 数据库名列表,每个数据库名用空格分开 改成自己要备份的数据库名
DATABASE_LIST='diguo wordpress discuz'

# 备份路径
BACKUPDIR=/data/backup/mysql

# 获取系统时间用于文件名格式化
#DATE=` date +%Y-%m-%d `
TIME=` date +%Y-%m-%d_%H-%M-%S `

# 循环数据库名列表,挨个备份数据库并打包为sql.gz文件
for DATABASE in $DATABASE_LIST ; do

# 初始化备份文件夹
if [ ! -d $BACKUPDIR/$TIME ]; then
mkdir -p $BACKUPDIR/$TIME
fi

# 开始备份
# /usr/local/mysql/bin/mysqldump 位置根据个人安装数据库的位置进行配置,每个人安装方式可能不一样,地址也不一样
/usr/local/mysql/bin/mysqldump -h $HOST -u$USERNAME -p$PASSWORD $DATABASE | gzip > $BACKUPDIR/$TIME/mysql_$DATABASE'_'$TIME.sql.gz

done

# 查找并删除180天之前的备份文件
find $BACKUPDIR -name "mysql_*.sql.gz" -type f -mtime +180 -exec rm {} \; > /dev/null 2>&1

# 打包文件并发送邮件到我的邮箱
cd $BACKUPDIR && tar -zcvf /root/mysql_backup_$TIME.tar.gz $TIME
mailx -vs "【数据库备份】$TIME - SQL压缩包" -a /root/mysql_backup_$TIME.tar.gz $MAIL</usr/local/bakshell/mail_mysql.txt
\rm -rf /root/mysql_backup_$TIME.tar.gz

以上脚本修改一下前面的三项为自己的配置之后应该就可以用了,脚本里面的命令也是linux里面比较基础的命令了,这里只展开记录一下MySQL的备份和还原命令以及文件查找命令;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# MySQL导出数据库为sql文件
/usr/local/mysql/bin/mysqldump -u root -proot database > abc.sql
# MySQL导入sql文件到数据库
mysql -uroot -proot database < abc.sql

# MySQL导出数据库为sql文件并压缩,
/usr/local/mysql/bin/mysqldump -u root -proot database | gzip > abc.sql.gz
# MySQL导入压缩的sql文件到数据库
gzip < abc.sql.gz | mysql -uroot -proot database

find $BACKUPDIR -name "mysql_*.sql.gz" -type f -mtime +180 -exec rm {} \; > /dev/null 2>&1
# type f 表示查找普通类型的文件,f表示普通文件。
# mtime +180 按照文件的更改时间来查找文件,+180表示文件更改时间距现在180天以前;如果是 -mmin +180 表示文件更改时间距现在180分钟以前。
# exec rm {} \ 表示执行一段shell命令,exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{},一个空格和一个,最后是一个分号。
# /dev/null 2>&1 把标准出错重定向到标准输出,然后扔到/DEV/NULL下面去。通俗的说,就是把所有标准输出和标准出错都扔到垃圾桶里面;其中的& 表示让该命令在后台执行。

三、配置定时任务

脚本能够正常备份并发送邮件了,那么应该开始配置定时任务,让脚本按照设定的周期自动执行了;

Centos7的定时计划是在 /etc/crontab 文件中记录的

1
2
3
4
5
6
7
8
vim /etc/crontab
# 在最后面添加任务计划

# crontab配置文件格式如下:
# 分 时 日 月 周  命令
# /usr/local/bakshell/bakmysql.sh 是第二步保存的备份脚本路径,填写你自己的实际路径即可
00 02 * * * root /usr/local/bakshell/bakmysql.sh
# 上面这条任务表示每天凌晨2点执行bakmysql.sh脚本

配置完成保存之后命令就生效了,到了时间就会自动执行脚本了; 教程到此结束;

明人不说暗话,如果你觉得可以的话,你懂的!