linux下创建定时任务备份数据库

需求背景

最近公司国资委系统上线,珍贵的业务数据批量录入,此时面临一个问题,万一数据出问题咋办,这可是上百个国资企业录入的数据啊,真丢了哭都没地哭啊,数据库数据备份需求来了。

我们系统使用的docker进行各个应用及数据库管理,数据库数据文件挂载在服务器本地目录下,因此数据库备份可以简化下,只要把数据文件挂载目录备份就好了。计划写个shell脚本定时执行。

知识点

针对此次备份涉及的知识点有:

1.shell执行时实现交互,因为要输入密码(权限问题tar挂载目录时,需要sudo;tar包需要scp到另外的服务存储,需要用scp命令。都需要输入密码)

2.linux环境下设置定时任务

准备条件

1. shell交互命令我用到expect交互工具,此工具需要安装;安装及使用教程可以网上搜索,执行如下命令,返回如下表示安装成功

  $ expect
  expect1.1>

查看命令引用目录(加粗部分):

$ whereis expect
expect: /usr/bin/expect /usr/share/man/man1/expect.1.gz

此时我们就可以使用expect工具了。 

2. 定时任务使用crontab,一般系统已默认安装,需要提前确认crond服务是否启动,执行命令systemctl status crond,返回如下表示定时任务服务运行中

$ systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-06-29 19:49:09 CST; 4 months 6 days ago
  Process: 12679 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 1389 (crond)
   Memory: 808.0K
   CGroup: /system.slice/crond.service
           └─1389 /usr/sbin/crond -n

编写脚本

 1.以下是交互输入密码完成数据库文件压缩备份的脚本,/mysql目录是数据库挂载目录。注意密码中 含特殊符号$,前面需要加上转义符

#!/usr/bin/expect           
        spawn sudo tar -zvcf /home/gridnt/mariadb-backup.tar.gz /mysql
        expect "*password for gridnt:" {send "123456$789
"}
        expect "*\$*"   {send "exit 
"}
        expect eof

expect具体语法可以网上查询学习,expect后“”范围内的内容可以参考实际执行命令的返回信息,支持模糊匹配,用*号代指多个字符

参考《Centos expect spawn、linux expect 用法https://www.cnblogs.com/zhangmingcheng/p/7449776.html》网友的文章,至少我看明白了

此处遇到一个问题,我除了使用expect外,还需要使用bash解释器做一些变量定义等简单逻辑,如何将expect与bash脚本写到一个shell脚本中呐,该难题留到最后解决

2.linux环境设置定时任务

分别使用了以下两种方式

$ crontab -e
直接添加
1
* * * * /home/backup.sh

$ vi /etc/crontab 直接添加到最后一行 1 * * * * /home/backup.sh

但是都未生效。根据网上说的修改配置文件之后需要重新加载配置文件或者重启crond才能生效,实际只要修改了配置文件即可生效,无需使用systemctl reload crond加载。

多个环境尝试后发现定时任务未生效是非root用户进行设置导致的,解决方案如下,当前用户gridnt,每天1点执行脚本,注意以下黄色标记部分:

$ vi /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=gridnt

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
* 1 * * * gridnt /home/backup.sh

困难总结

1.编写shell脚本过程中发现一个问题,我大部分脚本是#!/bin/bash开头,表示使用bash解释器,但交互部分的脚本则需要#!/usr/bin/expect开头,表示使用expect工具解释脚本。如何将bash和expect两个解释器组合使用呐,这是我遇到的第一个难题

  解决此问题用到一个知识点EOF。Shell中通常将EOF与 << 结合使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主调Shell。合并后脚本如下(未包含scp)

#!/bin/bash
DATE=$( date  +%Y%m%d)
set timeout 30

password='123456$789'
/usr/bin/expect <<-EOF
spawn
sudo tar -zvcf /home/mariadb-backup_${DATE}.tar.gz /mysql
expect
"*password for gridnt:" {send "${password} "}
expect
"*\$*" {send "exit "}
expect eof
EOF

2.我的定时任务不生效,更换多个服务器对比发现,当root用下设置定时任务时,定时任务成功,但是自定义账号时则失败。如何设置非root账号的定时任务,这是我遇到的第二个难题

  解决此问题,需要了解crontab的任务是有指定用户的;此外学会查看日志跟踪定时任务

$ tail -f /var/log/cron
Nov  4 01:00:01 sasac-001 CROND[31376]: (gridnt) CMD (/home/backup.sh)
原文地址:https://www.cnblogs.com/sylvia-liu/p/15508621.html