推荐一个定时备份数据库的脚本

2020-07-01  本文已影响0人  aimleo

在线上数据库,为了保证数据安全,我们经常要做一些定时的数据备份。这个过程既繁琐又枯燥,我花了几天时间整理了一个备份脚本,并在生产环境测试并使用。

项目地址:https://github.com/aim-leo/db-auto-backup
如果你喜欢,请给我一个star,如有issue,请提交给我。

db-backup说明文档

特性

备份脚本 db-backup.sh

示例

// 将本地的mongodb数据库的test实例导出到/tmp/test-db-backup下
bash db-backup.sh -d test -o /tmp/test-db-backup


// 从名称为mysql的docker容器内导出test数据库.并压缩,到当前目录
bash db-backup.sh -d test -t mysql -z

// 使用yaml文件配置导出mysql下test数据库,并上传到对应的git
bash db-backup.sh -f example.yaml

// example.ymal
database:
  type: mysql
  name: test
  user: root
  pwd: 123456-abc
docker_container: mysql  // mysql在docker容器中,容器名是mysql
output_dir: /tmp/test-db-backup
max_file: 30    // 超过30个备份自动删除最开始的备份
push2git: true  // 上传到git
gzip: true   // 用tar压缩成.tar.gz文件
git:
  remote: git@github/***/***.git  // 你的git地址,需要在远程git上新建项目
  branch: master

所有参数

 Usage:
     bash db-backup.sh -d [database] -o [output_dir] ...
   
   Database options: (recommand define it at yaml)
     -d | --database_name [name]                Input the database you want to dump(required)
     -t | --database_type [type]                Input the database type, enum: [mysql, mongo]
     -h | --database_host [host]                Input the database host, defalut localhost
     -p | --database_port [port]                Input the database port, defalut { mysql: 3306, mongodb: 27017 }
     -u | --database_user [user]                Input the database user, mysql is required, mongo is optional
     -s | --database_pwd  [pwd]                 Input the database pwd, mysql is required, mongo is optional
   
   Git options: (recommand define it at yaml, required when push2git set true)
     -e | --git_user_name [name]                Input the git user name, required when use http protocol
     -w | --git_user_pwd [pwd]                  Input the git user pwd, required when use http protocol
     -i | --git_user_email [email]              Input the git user email, required when use http protocol
     -r | --git_remote [remote]                 Input the git remote, accept http | ssh protocol
     -b | --git_branch [branch]                 Input the git branch, default master
   
   Optional options:
     -o | --output_dir [output_dir]             Input the dir you want to output the file, defalut current path
     -f | --config_yaml [config_yaml]           Input the yaml path contain your config, defalut at output_dir/backup.yaml
     -n | --file_name [filename]                Input the filename, default DATABASE_db_TIME
     -l | --log_dir [log_dir]                   Input the dir you want to output the log, defalut /tmp/db-backup
     -c | --docker_container [container]        If your database is runing at docker, Input the container ID or name here
     -m | --max_file [max_file]                 Expect a Number, if backup file overflow, it will auto remove the oldest file
     -g | --push2git                            Whether to auto add && commit && push to git, default false
     -z | --gzip                                Whether to gzip the dir, default false
   
   Auxiliary options:
     -h | --help                                Get help
     -v | --version                             Get current version

-o | --output_dir [output_dir]

-f | --config_yaml [config_yaml]

-n | --file_name [filename]

-l | --log_dir [log_dir]

-c | --docker_container [container]

-m | --max_file [max_file]

-g | --push2git

-z | --gzip

-h | --help

-v | --version

数据库相关

-d | --database_name [name]

-t | --database_type [type]

-h | --database_host [host]

-p | --database_port [port]

-u | --database_user [user]

-s | --database_pwd [pwd]

GIT相关

当指定参数-g,或者--push2git时,脚本会把备份后的文件传到指定的git地址,此时需要指定以下参数

注意, 当使用cron自动运行此脚本时, git无法获取到当前的ssh-keygen,而手动运行脚本时则正常,这是因为cron是以root用户身份运行脚本,而ssh-key保存在当前用户(可能不是root)下,
此时备份会失败,可选的解决办法有:

-e | --git_user_name [name]

-w | --git_user_pwd [pwd]

-i | --git_user_email [email]

-r | --git_remote [remote]

-b | --git_branch [branch]

挂载自动备份 add-schedule.sh

用法

sudo bash add-schedule.sh [yaml_path] [cron_time_config]

我们使用cron来运行定时任务,该程序在ubuntu下默认安装

该脚本提供简单的方法来挂在定时任务,你也可以手动添加脚本到/etc/crontab下,使用sudo vim /etc/crontab

确保使用sudo运行该脚本, 每个yaml只能在crontab中同时注册一次,当该yaml文件已注册时,会自动覆盖之前的配置

yaml_path
cron_time_config

挂载自动备份 delete-schedule.sh

用法

删除已注册在crontab下的yaml配置

sudo bash delete-schedule.sh [yaml_path]

配置文件示例 example.yaml

database:
  type: mysql
  name: <database>
  user: <name>
  pwd: <pwd>
docker_container: mysql
output_dir: /home/<database>-db-backup
max_file: 30
push2git: false
gzip: true
git:
  user:
    name: <name>
    email: ***@gmail.com
    pwd: <pwd>
  remote: git@github/***/***.git
  branch: master

常见问题

为什么我配置了git,文件也正常导出了,但是不能自动提交?

通常的原因是无法获取到git配置,查看log, 最后的输出一般停在Begin push to origin/master

当使用cron自动运行此脚本时, git无法获取到当前的ssh-keygen,而手动运行脚本时则正常,这是因为cron是以root用户身份运行脚本,而ssh-key保存在当前用户(可能不是root)下,
此时备份会失败,可选的解决办法有:

在脚本中指定用户的用户名 密码 邮箱

// 在yaml中指定这部分:
git:
  user:
    name: <name>
    email: ***@gmail.com
    pwd: <pwd>
  remote: https://github/***/***.git (必须是https协议的git地址)

或者
在root下生成ssk-keygen,并添加到git服务器

// 以root当时登录,确保cron可访问到ssh-key
sudo su

ssh-keygen -t rsa -C "***@gmail.com"

然后将/root/.ssh/id_rsa.pub的内容添加到你的git服务器的ssh-key列表, 参考connect github with ssh

当我配置output_dir为/home/mysql-db-backup, 但我的git项目名是mysql-db-backup2时,实际导出目录是什么?

output_dir指定的就是最终导出目录,不管git的项目名称是什么,最后导出的目录就是配置目录

在脚本首次运行时,如果output_dir不存在,则会新建它,如果配置了git,则会首先拉取该项目,然后再导出文件

使用的导出方法是

git clone $GIT_REMOTE $OUTPUT_DIR

所以最后导出的路径是mysql-db-backup

当我使用tar -zxvf $NAME.tar.gz时,为什么会解压失败?

请使用tar -zxvPf $NAME.tar.gz来解压文件

为什么我指定了log_dir,但是某些输出没有写到该文件夹下?

在脚本未读取到配置的log_dir前, 输出的内容将被写到/tmp/db-backup/tmp.log下

我指定了max_file,到文件数量超过之后,为什么脚本并没有删除最原始的备份?

请检查是否错误指定了file_name,因为脚本默认以时间命名文件,默认以文件名排序,当文件名不统一时,排序将会混乱,请使用默认命名

当我把多个数据库备份到同一个文件夹会怎么样?

理论上是支持的, 但是不推荐这么做, 最好是一个数据库一个导出文件夹,一个git地址

为什么我在导出的目录下运行git命令,会报权限错误?

cron默认用root用户来运行命令, 当首次运行时, 程序拉取了远程分支的文件, 则该目录的权限为最高,普通用户无法操作,请使用sudo来运行

上一篇下一篇

猜你喜欢

热点阅读