简介

在生产环境上,为了避免数据的丢失,通常情况下都会定时的对数据库进行备份。而Linux的crontab指令则可以帮助我们实现对数据库定时进行备份。首先我们来简单了解crontab指令,如果你会了请跳到下一个内容mysql备份。
本文章的mysql数据库是安装在docker容器当中,以此为例进行讲解。没有安装到docker容器当中也可以参照参照。

contab定时任务

使用crontab -e来编写我们的定时任务。

0 5 * * 1 [command]
0 8 * * * [command]
  • crontab -l 可以查看自己的定时任务
  • crontab -r 删除当前用户的所有定时任务

mysql备份

快速上手

这里我的mysql数据库是docker容器。假如你需要在每天晚上8点整执行定时任务,那么可以这么写。
首先执行命令crontab -e。

0 8 * * * docker exec mysql_container mysqldump -uroot -proot_password database_name > /var/backups/mysql/$(date +%Y%m%d_%H%M%S).sql

如果你没什么要求,单纯的只是想要备份,那么上面那个命令就可以帮你进行定时备份。

小坑: mysql备份的时候我使用了docker exec -it mysqldump ... 这样的命令去做bash脚本,因为-i参数是有互动的意思,导致在crontab中执行定时任务的时候,没有输出数据到sql文件当中。所以使用crontab定时的对docker容器进行备份命令的时候不要添加-i参数。

crontab优化

我不建议直接在crontab -e里面写要执行的命令,任务多了就把这个文件写的乱七八招了。
建议把数据库备份的命令写成一个bash脚本。在crontab这里调用就好了
如:建立一个/var/backups/mysql/mysqldump.sh文件,内容如下

docker exec mysql_container mysqldump -uroot -pmypassword database_name > /var/backups/mysql/$(date +%Y%m%d_%H%M%S).sql
chmod 711 /var/backups/mysql/mysqldump.sh
0 20 * * * /var/backups/mysql/mysqldump.sh

mysql备份优化

因为sql文件比较大,所以一般情况下都会对sql文件进行压缩,不然的话磁盘占用就太大了。
假设你做了上面这一步 crontab优化,我们可以把mysqldump.sh脚本改成下面这样:

export mysqldump_date=$(date +%Y%m%d_%H%M%S) && \docker exec mysql_container mysqldump -uroot -pmypassword database_name> /var/backups/mysql/$mysqldump_date.sql && \gzip /var/backups/mysql/$mysqldump_date.sqlfind /var/backups/mysql/ -name "*.sql" -mtime +15 -exec rm -f {} \;

数据恢复

若一不小心你执行drop database,稳住,淡定。我们首先要创建数据库被删除的数据库。

>mysql create database database_name;
docker exec -i mysql_container mysql -uroot -proot_password database_name < /var/backups/mysql/20200619_120012.sql

binlog日志

binlog 是mysql的一个归档日志,记录的数据修改的逻辑,如:给 ID = 3 的这一行的 money 字段 + 1。
首先登录mysql后查询当前有多少个binlog文件:

> mysql show binary logs;+---------------+-----------+-----------+| Log_name   | File_size | Encrypted |+---------------+-----------+-----------+| binlog.000001 |    729 | No    || binlog.000002 |   1749 | No    || binlog.000003 |   1087 | No    |+---------------+-----------+-----------+
mysql> show master status\G;
mysql> flush logs
mysql> show binlog events in 'binlog.000003';

恢复数据

拿回上面例子的这段话。

晚上8点进行定时备份,但是却在晚上9点drop database,那么晚上8点到晚上9点这一个小时之内的数据却没有备份到。。

首先进入到mysql容器后,切换到/var/lib/mysql目录下,查看binlog文件的创建日期

cd /var/lib/mysqlls -l...-rw-r----- 1 mysql mysql   729 Jun 19 15:54 binlog.000001-rw-r----- 1 mysql mysql   1749 Jun 19 18:45 binlog.000002-rw-r----- 1 mysql mysql   1087 Jun 19 20:58 binlog.000003...

恢复命令格式:

mysqlbinlog [options] file | mysql -uroot -proot_password database_name

--start-datetime 开始时间,格式 2020-06-19 18:00:00
--stop-datetime 结束时间,格式同上
--start-positon 开始位置,(需要查看binlog文件)
--stop-position 结束位置,同上
...

恢复备份数据和binlog数据前建议先登录mysql后执行flush logs生成新的binlog日志,这样可以专注需要恢复数据的binlog文件。
首先我们需要查看binlog日志,在哪个位置进行了drop database操作:

mysql> show binlog events in 'binlog.000003';+---------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+| Log_name   | Pos | Event_type   | Server_id | End_log_pos | Info                                                                    |+---------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+| binlog.000003 |  4 | Format_desc  |     1 |     125 | Server ver: 8.0.20, Binlog ver: 4                                                      || binlog.000003 | 125 | Previous_gtids |     1 |     156 |                                                                       || binlog.000003 | 156 | Anonymous_Gtid |     1 |     235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                    || binlog.000003 | 235 | Query     |     1 |     318 | BEGIN                                                                    || binlog.000003 | 318 | Rows_query   |     1 |     479 | # INSERT INTO `product_category` SET `name` = '床上用品' , `create_time` = 1592707634 , `update_time` = 1592707634 , `lock_version` = 0   || binlog.000003 | 479 | Table_map   |     1 |     559 | table_id: 139 (hotel_server.product_category)                                                || binlog.000003 | 559 | Write_rows   |     1 |     629 | table_id: 139 flags: STMT_END_F                                                       || binlog.000003 | 629 | Xid      |     1 |     660 | COMMIT /* xid=2021 */                                                            || binlog.000004 | 660 | Anonymous_Gtid |     1 |     739 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                    || binlog.000004 | 739 | Query     |     1 |     822 | drop database hotel_server /* xid=26 */                                                   |+---------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------
mysqlbinlog --start-datetime=2020-06-19 20:00:00 --stop-position=660 /var/lib/mysql/binlog.000003 | mysql -uroot -proot_password datbase_name

总结

因为mysql定时备份是在生产环境上必须的任务。是很常用的。所以我就迫不及待的写博客。当然也很感谢我同事的帮助。这篇文章已经写了三天了,因为我也是在不断地试错,不断的更新文章。避免把错误的知识点写出来。如果帮到你了,关注我一波呗!谢谢。

更多相关文章

  1. Android(安卓)之 AsyncTask 异步任务
  2. Android(安卓)任务和回退堆栈---启动任务
  3. Android(安卓)后台任务(五)Service
  4. Windows环境下Android(安卓)Studio系列4—界面介绍
  5. Android监听Home键和最近任务
  6. Android中对后台任务线程性能的说明及优化
  7. Android(安卓)线程池管理工具类
  8. Android(安卓)创建线程执行任务
  9. 获取Android正在运行的任务和服务

随机推荐

  1. Android之实现滑动开关组件
  2. Android 传感器概述
  3. java的 Timer
  4. Android JNI(Java Native Interface)技术介
  5. android Activity 组件
  6. Eclipse New菜单中没有Android(安卓)Proj
  7. Android(安卓)binder学习一:主要概念
  8. android sqlite批量插入数据速度慢解决方
  9. Android串口通信(基于Tiny6410平台)
  10. Android的消息推送系列之消息推送原理