Mysql备份与恢复

烂漫一生 提交于 2019-12-04 21:03:38

通常数据库备份数据文件、binlog 日志文件和 my.cnf 配置文件都应在其他地方保存一份甚至多份
仅备份是没有任何意义, 需要在测试环境中做日常恢复演练, 测试备份的可用性, 恢复较比备份更加的重要

备份: 能够有效防止设备故障以及人为误操作带来的数据丢失, 例如:将数据文件保存在远端。
冗余: 数据有多分冗余, 但不等于备份, 只能防止机械故障丢失的数据, 例如: 主备模式、数据库集群。

toc
  • 数据库备份必须考虑因素
    • 数据的一致性
    • 服务的可用性
  • 数据库备份方式
    • 逻辑备份: 备份 DDL DML DCL 语句, 适用于中小型数据库, 效率相对低下。 mysqldump、mydumper
    • 物理备份: 直接复制数据库文件, 适用于大型数据库环境, 效率相对较高。 xtrabackup、inbackup、cp、tar、lvm snapshot
  • 数据库备份模式
    • 完全备份
    • 增量备份
    • 差异备份

Mysql逻辑备份与恢复

Mysql自带逻辑备份工具 mysqldump , 可以保证数据备份一致性, 以及服务可用性
不管物理备份还是逻辑备份, 必须开启 binlog 日志

  • mysqldump -h 服务器 -u 用户名 -p 密码 数据库名 > 备份文件.sql
    • -A, --all-databases # 备份所有库
    • -B, --databases # 备份多个库多个数据库
    • --single-transaction # InnoDB 一致性 服务可用性
    • --master-data=1|2 # 记录 binlog 日志位置与文件名 , 追加至备份文件中
    • --triggers # 备份触发器
    • -F, --flush-logs # 备份之前刷新日志
    • -E, --events # 备份事件调度器代码
    • -R, --routines # 备份存储过程和存储函数

完整备份与恢复

## 创建备份目录
[root@Mysql ~]# mkdir /backup/mysql -p
## 完整备份
[root@Mysql ~]# mysqldump -uroot -p'Sgy123.com' --all-databases --single-transaction --master-data=1 --flush-logs > /backup/mysql/`date +%F%H`-mysql-all.sql
## 查看备份结果
[root@Mysql ~]# ls /backup/mysql/
2019-04-0400-mysql-all.sql
  • 数据库完整恢复流程
    1. 停止数据库
    2. 删除破损数据库
    3. 重新初始化数据库
    4. 重置密码,否则无法恢复
    5. 恢复数据[新密码]
    6. 刷新授权[备份时密码]

模拟数据数据丢失

本人YUM安装的Mysql,我这直接卸载了,删除所有 Mysql 数据,再重新安装
其他安装方式(源码、二进制)可以在 my.cnf 里面 datadir 指定的目录内容全删,在初始化数据库

[root@Mysql ~]# systemctl stop mysqld
[root@Mysql ~]# rpm -e mysql-community-server
[root@Mysql ~]# rm -rf /var/lib/mysql/*
[root@Mysql ~]# yum install mysql-community-server -y
## 开启 binlog 日志
[root@Mysql ~]# vim /etc/my.cnf
[mysqld]
.......
server-id = 1
binlog_format = mixed 
log-bin = /log/mysql_bin/mysql-bin  ##有这个目录并且属主和属组都为 mysql
expire_logs_days = 30

重新初始化数据库后

[root@Mysql ~]# systemctl start mysqld
## 重新查看密码
[root@Mysql ~]# cat /var/log/mysqld.log
2019-04-06T07:40:50.513020Z 1 [Note] A temporary password is generated for root@localhost: Ai%u!dllz9#;
## 修改密码
[root@Mysql ~]# mysqladmin -uroot -p'Ai%u!dllz9#;' password "Sgy456.com"
## 用导入备份
[root@Mysql ~]# mysql -uroot -p'Sgy456.com' < /backup/mysql/2019-04-0400-mysql-all.sql
## 用原来的密码登陆
[root@Mysql ~]# mysql -uroot -p'Sgy123.com'

建议在恢复备份时暂停 binlog 日志记录

## 关闭 binlog 记录 , 不然容易恢复增量失败
[root@sql mysql]# sed -i '23aSET sql_log_bin=0;' /backup/mysql/2019-04-0400-mysql-all.sql
## 在 Mysql 控制台临时修改不记录 binlog 日志
mysql> set sql_log_bin=0;
mysql> source /backup/mysql/2019-04-0400-mysql-all.sql

增量备份与恢复

数据库完整备份+数据库增量备份
模拟:现在有一个运维人员误删除了数据库

## 备份之前数据准备
mysql> create database test;
mysql> use test
mysql> create table t1(id int,name varchar(30));
mysql> insert into t1 value (1,'zhangsan'),(2,'lisi'),(3,'wangwu'),(4,'zhaoliu');
mysql> select * from t1;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
+------+----------+
## 基于当前数据完整备份
[root@Mysql ~]# mysqldump -uroot -p'Sgy123.com' --all-databases --single-transaction --master-data=1 --flush-logs > /backup/mysql/`date +%F%H`-mysql-all.sql
## 再插入数据
mysql> insert into t1 value (3,'wangwu'),(4,'zhaoliu');
mysql> select * from t1;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
|    3 | wangwu   |
|    4 | zhaoliu  |
+------+----------+
## 查看最新 binlog 记录位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |   802963 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

模拟数据数据丢失

[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'drop database test;'
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| bin                |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

恢复全备数据

[root@Mysql ~]# mysql -uroot -p'Sgy123.com' < /backup/mysql/2019-04-0404-mysql-all.sql 
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| bin                |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
## 发现备份之后的数据没有恢复
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'select * from test.t1'
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
+------+----------+

恢复增量数据
< 先根据数据丢失之前最后执行命令检索编号 mysqlbinlog -v /log/mysql_bin/mysql-bin.000001 | grep -4 "(3,'wangwu'),(4,'zhaoliu')"

[root@Mysql ~]# mysqlbinlog  --stop-position=802963 /log/mysql_bin/mysql-bin.000001|mysql -uroot -p'Sgy123.com'
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'select * from test.t1'
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
|    3 | wangwu   |
|    4 | zhaoliu  |
+------+----------+

如果删除数据库又执行了其他的可以恢复时候把删除那条命令跳过

[root@Mysql ~]# mysqlbinlog --stop-position=803120  /log/mysql_bin/mysql-bin.000001 |mysql -uroot -p'Sgy123.com'
[root@Mysql ~]# mysqlbinlog --start-position=803344  /log/mysql_bin/mysql-bin.000001 |mysql -uroot -p'Sgy123.com'

Mysql物理备份与恢复

percona-xtrabackup 物理备份+ binlog
开源免费并支持 Mysql 数据库热备份的软件,它能对 InnoDBXtraDB 存储引擎的数据库非阻塞地备份。无需暂停服务备份 Mysql

支持增量备份
支持差异备份
备份不增加服务器负载
创建 replication 更加便捷

官方下载链接

## 下载 rpm 包
[root@Mysql ~]# wget https://www.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.13/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.13-1.el7.x86_64.rpm
## 用 YUM 安装(必须有 epel包)
[root@Mysql ~]# yum localinstall percona-xtrabackup-24-2.4.13-1.el7.x86_64.rpm -y

完整备份与恢复

完整备份流程

##  创建备份目录
[root@Mysql ~]# mkdir /xtrabackup/
## 执行全备操作
[root@Mysql ~]# innobackupex --user=root --password="Sgy123.com" /xtrabackup/
## 检查备份结果
[root@Mysql ~]# ls /xtrabackup/
2019-04-06_07-56-46

完全备份恢复流程

##  停止数据库
[root@Mysql ~]# systemctl stop mysqld
## 删除数据
[root@Mysql ~]# rm -rf /var/lib/mysql/*
## 重演回滚
[root@Mysql ~]# innobackupex --apply-log /xtrabackup/2019-04-06_07-56-46/
##  恢复数据
[root@Mysql ~]# innobackupex --copy-back /xtrabackup/2019-04-06_07-56-46/
## 修改权限
[root@Mysql ~]# chown -R mysql.mysql /var/lib/mysql/
## 启动数据库
[root@Mysql ~]# systemctl start mysqld
## 登陆数据库
[root@Mysql ~]# mysql -uroot -p'Sgy123.com'

增量备份与恢复

增量备份全环境准备

## Mysql数据库数据
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'select * from test.t1;'
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
|    3 | wangwu   |
|    4 | zhaoliu  |
+------+----------+
## 全备数据库
[root@Mysql ~]# innobackupex --user=root --password='Sgy123.com' /xtrabackup/
## 检查备份结果
[root@Mysql ~]# ls /xtrabackup/
2019-04-10_04-48-17

增量备份流程

## 插入数据
mysql> insert into test.t1 value (5,'dasha'),(6,'ersha');
mysql> select * from test.t1;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
|    3 | wangwu   |
|    4 | zhaoliu  |
|    5 | dasha    |
|    6 | ersha    |
+------+----------+
## 基于全备份做增量备份
[root@Mysql ~]# innobackupex --user=root --password='Sgy123.com' --incremental /xtrabackup/ --incremental-basedir=/xtrabackup/2019-04-10_04-48-17/
## 检查备份结果
[root@Mysql ~]# ls /xtrabackup/
2019-04-10_04-48-17 2019-04-10_04-55-45
## 再次插入数据
mysql> use test
mysql> create table t2(name varchar(30),password varchar(50));
mysql> insert into t2 value ('dasha','123456'),('ersha','123456');
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
+----------------+
mysql> select * from t2;
+-------+----------+
| name  | password |
+-------+----------+
| dasha | 123456   |
| ersha | 123456   |
+-------+----------+
## 基于上一个增量备份做增量备份
[root@Mysql ~]# innobackupex --user=root --password='Sgy123.com' --incremental /xtrabackup/ --incremental-basedir=/xtrabackup/2019-04-10_04-55-45/
## 检查备份结果
[root@Mysql ~]# ls /xtrabackup/
2019-04-10_04-48-17  2019-04-10_04-55-45  2019-04-10_06-15-27

模拟故障

##  停止数据库
[root@Mysql ~]# systemctl stop mysqld
## 删除数据
[root@Mysql ~]# rm -rf /var/lib/mysql/*

依次重演

## 重演全备数据
[root@Mysql ~]# innobackupex --apply-log --redo-only /xtrabackup/2019-04-10_04-48-17/
## 重演第一次备份数据
[root@Mysql ~]# innobackupex --apply-log --redo-only /xtrabackup/2019-04-10_04-48-17/ --incremental-dir=/xtrabackup/2019-04-10_04-55-45/
## 重演第二次备份数据
[root@Mysql ~]# innobackupex --apply-log --redo-only /xtrabackup/2019-04-10_04-48-17/ --incremental-dir=/xtrabackup/2019-04-10_06-15-27/

执行回滚

[root@Mysql ~]# innobackupex --copy-back /xtrabackup/2019-04-10_04-48-17/
[root@Mysql ~]# chown -R mysql.mysql /var/lib/mysql
[root@Mysql ~]# systemctl start mysqld
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'select * from test.t1;'
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
|    3 | wangwu   |
|    4 | zhaoliu  |
|    5 | dasha    |
|    6 | ersha    |
+------+----------+
[root@Mysql ~]# mysql -uroot -p'Sgy123.com' -e 'select * from test.t2;'
+-------+----------+
| name  | password |
+-------+----------+
| dasha | 123456   |
| ersha | 123456   |
+-------+----------+

增量备份每一个都指向上一个备份,差异备份指向的是上一个完整备份

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!