Linux上Mysql备份与恢复

1.完全备份

完整备份是将所选的全部数据都备份起来,将备份文件生成一个镜像,再保存到其他的硬盘分区中。

1.1 完全备份一个或多个完整的库

ps: 博主mysql是用docker部署的,这时候需要进入docker容器进行操作。

docker exec -it hjt-mysql /bin/bash

先去/opt目录下 新建 mysqlData

mkdir mysqlData

进入容器后,进入 /var/lib/mysql目录。这是我们存储数据的地方

docker定期备份 docker备份数据库_mysql

先备份一个库,执行命令。

mysqldump -u root -p数据库密码 --databases hjt-data > /opt/mysqlData/hjt-data.sql

docker定期备份 docker备份数据库_mysql_02

这时候sql文件就生成了

docker定期备份 docker备份数据库_docker_03

如果是要备份整个数据库,执行的命令是

mysqldump -u root -p数据库密码 --all databases > /opt/mysqlData/hjt-data.sql

查看备份文件

cat /opt/mysqlData/hjt-data.sql

1.2 完全备份恢复

先把hjt-data数据库删除

docker定期备份 docker备份数据库_linux_04

先新建数据库 hjt-data

docker定期备份 docker备份数据库_docker定期备份_05

然后执行命令

mysql -uroot -p hjt-data </opt/mysqlData/hjt-data.sql

输入mysql密码后

docker定期备份 docker备份数据库_docker定期备份_06

可见数据已经恢复

docker定期备份 docker备份数据库_docker定期备份_07

2.增量备份+完全备份

增量备份是一种智能备份方式,只备份有变化的部分,也就是在上一次备份之后,将新增的或有变化的数据备份起来,每一次增量备份都是和上一次备份(可以是完整备份、差异备份或增量备份)相对比。比如周一进行了一次完整备份,周三进行了一次增量备份,那么周三这次增量备份会将周一完整备份之后有变化的数据备份起来,若周五又进行了一次增量备份,那么这一次将会备份周三增量备份之后有变化的数据。

首先需要开启二进制日志功能
vim /etc/my.cnf

[mysqld]
log-bin=mysql-bin
binlog_format = MIXED				指定二进制日志(binlog)的记录格式为 MIXED
server-id = 1

③ 二进制日志的格式
A) binlog_format 在mysql5.7默认是row, 不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候会让日志暴涨

例如:update a < 10 的数据,statement模式会记录这一条sql,而row模式的话,会记录a=1,a=2到a=9所有的记录的更改

B) STATEMENT模式 每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题

C) MIXED模式 以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。

2.1 可对每周进行完全备份

下面是完全备份备份库的

mysqldump -u root -p  hjt-data > /opt/mysqlData/hjt-data_$(date +%F).sql

docker定期备份 docker备份数据库_Data_08

如果是备份某个库中的某张表

docker定期备份 docker备份数据库_docker_09

mysqldump -u root -p  hjt-data sys_file  > /opt/mysqlData/hjt-data_sys_file$(date +%F).sql

2.2 每天进行增量备份

生成新的二进制日志文件(例如 mysql-bin.000002)

插入新数据,以模拟数据的增加或变更

docker定期备份 docker备份数据库_docker_10

再次生成新的二进制日志文件

mysqladmin -u root -p flush-logs

docker定期备份 docker备份数据库_docker_11

查看二进制日志

mysqlbinlog --no-defaults --base64-output=decode-rows -v /var/lib/mysql/mysql-binlog.000001

如果想看到我们写入的sql语句格式,则需要设置 binlog_rows_query_log_events = 1

--start-position 可以通过偏移量进行查询

--start-datetime 通过开始时间来查询

--stop-datetime 通过结束时间查询

mysqlbinlog  --base64-output=decode-rows -v /var/lib/mysql/mysql-binlog.000001 --start-datetime='2022-11-23 09:18:22'

2.3 MySQL增量恢复

一般恢复

首先我们先创建一张表test

docker定期备份 docker备份数据库_docker_12

然后执行sql命令 ,生成二进制日志。

mysqladmin -u root -p flush-logs

docker定期备份 docker备份数据库_Data_13

这时候我们把test表删除

docker定期备份 docker备份数据库_linux_14

然后再执行一下命令,进行增量恢复。

mysqlbinlog --no-defaults  /var/lib/mysql/mysql-binlog.000002  | mysql -u root -p

docker定期备份 docker备份数据库_docker定期备份_15

这是test表就恢复了

docker定期备份 docker备份数据库_linux_16

3.定时任务完成备份

docker容器内安装crontab

进入容器,执行命令

apt update

#安装 cron
apt install -y cron

安装成功后,执行

touch /var/log/cron.log

# 更改时区

rm -rf /etc/localtime

ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

cron && tail -f /var/log/cron.log

然后执行命令 ,会报一下错误

crontab -e

docker定期备份 docker备份数据库_docker定期备份_17

这个报错是因为你docker容器没有安装vi命令

解决方案:

apt-get update 

apt-get install vim

在宿主机新建mysqlData.sh脚本,并把复制到容器内部

docker定期备份 docker备份数据库_docker_18

脚本内容如下:

#!/bin/bash
echo '开始执行mysql备份操作'
mysqldump -u root -p970628hjt.  hjt-data > /opt/mysqlData/hjt-data_$(date +%F).sql
echo 'mysql备份完成'

执行命令

docker cp  /mydata/sh/mysqlData.sh hjt-mysql:/sh/

再执行命令 crontab -e ,然后输入

* * * * * /sh/mysqlData.sh > /opt/log/mysql.log 2>&1

docker定期备份 docker备份数据库_mysql_19

查看定时任务列表

crontab -l

查看生成好的sql文件

docker定期备份 docker备份数据库_mysql_20

因为我宿主机映射容器/var/lib/mysql/是这个目录