• 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)
  • 相关阅读:
    相对路径与绝对路径问题
    javaee自定义servlet的步骤
    Struts1.X与Spring集成——另外一种方案
    菜鸟也能学cocos2dx3.0 浅析刀塔传奇(下)
    JAVA之了解类载入器Classloader
    IOS 编程中引用第三方的方类库的方法及常见问题
    通过eclipse的egit插件提交提示Auth fail
    定时器0的方式1 定时器1的方式1 数码管和led
    MongoDB入门学习(四):MongoDB的索引
    J2EE--JDBC
  • 原文地址:https://www.cnblogs.com/sylvia-liu/p/15508621.html
Copyright © 2020-2023  润新知