MySQL 备份与恢复

重点:

多种日志: 通用日志,慢查询日志

二进制日志

备份: 热备份,冷备份

mysqldump 工具( 备份与还原 )

主从复制的工作原理

主从复制的实现

5)备份和恢复

5.1)备份恢复概述 ( 数据备份一定要重视 )

备份 还原 二者缺一不可 )

5.1.1)为什么要备份

**灾难恢复:**硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景。

参考链接: https://www.toutiao.com/a6939518201961251359/

5.1.2) 备份类型

数据安全笔记: https://www.cnblogs.com/bitrabbit/p/13929478.html

完全备份,部分备份

完全备份: 整个数据集( 如果数据量不大的情况下,可以每天都全量备份 )

小技巧: 假设我们在每天的凌晨 2 点进行全量备份,但在 10 点遇到了问题,导致 2 点到 10 点之间的数据丢失,我们其实可以通过二进制日志文件来恢复数据。二进制日志文件记录了 2 点到 10 点间的所有操作,可以帮助我们将数据还原到出问题之前的状态。因此,尽管我们无法恢复 2 点到 10 点之间的具体数据,但我们可以通过操作记录将数据还原到接近10点的状态,从而减少数据丢失的影响。**因此,我们才说二进制日志很重要,**他可以帮助我们还原到出现问题前的时刻,避免数据大量丢失。

部分备份: 只备份数据子集,如部分库或表。

完全备份、 增量备份、差异备份

增量备份: 仅备份最近一次完全备份或增量备份以来变化的数据(如果存在增量),备份较快,还原复杂。

周一: 完全备份( 必须先做一个完全备份 )

周二: 增量备份( 增量备份的是什么?备份的是周一到周二 之间 变化的数据

周三: 增量备份( 增量备份的是什么?备份的是周二到周三 之间 变化的数据

周四: 增量备份( 增量备份的是什么?备份的是周三到周四 之间 变化的数据

周五: 数据被破坏如何还原? 先还原周一的完全备份,再依次还原 周二周三周四的增量备份,再基于二进制日志文件恢复 临近数据被破坏时间段之前的操作到最近一个增量备份之间的操作

差异备份: 仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单。

周一: 完全备份( 必须先做一个完全备份 )

周二: 差异备份( 差异备份的是什么?备份的是周一到周二 之间 变化的数据

周三: 差异备份( 差异备份的是什么?备份的是周一到周三 之间 变化的数据

周四: 差异备份( 差异备份的是什么?备份的是周一到周四 之间 变化的数据

周五: 数据被破坏 ( 如何还原? 先还原周一的完全备份,再还原最近的一个差异备份 即可,再基于二进制日志文件恢复 临近数据被破坏时间段之前到最后一个差异备份之间的操作

注意: 二进制日志文件 不应该与 数据文件 放在同一磁盘

冷、温、热备份

冷备: 读、写操作均不可进行,数据库停止服务( 影响业务 )

温备: 读操作可执行;但写操作不可执行( 只能读不能写 )

热备: 读、写操作均可执行,( 数据库不受影响 )

MyISAM: 温备,不支持热备

InnoDB: 都支持( 能热备就热备 )

物理和逻辑备份

**物理备份:**直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快。

**逻辑备份:**从数据库中 "导出" 数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度。

5.1.3)备份什么?

数据

二进制日志、InnoDB 的事务日志

用户帐号,权限设置,程序代码(存储过程、函数、触发器、事件调度器)

服务器的配置文件

5.1.4)备份注意要点

能容忍最多丢失多少数据

备份产生的负载

备份过程的时长

温备的持锁多久

恢复数据 需要在多长时间内完成( 建议脚本化 )

需要备份和恢复哪些数据

5.1.5)还原要点

做还原测试,用于测试备份的可用性

还原演练,写成规范的技术文档( 定期演练 )

5.1.6)备份工具

cp,tar 等复制归档工具:物理备份工具,适用所有存储引擎;只支持冷备 ;完全和部分备份。(必须: 异机器备份 或 异地域备份 )

LVM 的快照:先加读锁,做快照后解锁,几乎热备;借助文件系统工具进行备份。

mysqldump:逻辑备份工具,适用所有存储引擎,对 MyISAM 存储引擎进行温备;支持完全或部分备份;对 InnoDB 存储引擎支持热备,结合 binlog 的增量备份。( 常用 )

xtrabackup:由 Percona 提供支持对 InnoDB 做热备(物理备份)的工具,支持完全备份、增量备份。( 更专业的备份工具 )

MariaDB Backup:从 MariaDB 10.1.26 开始集成,基于 Percona XtraBackup 2.3.8 实现。

mysqlbackup:热备份, MySQL Enterprise Edition 组件。

mysqlhotcopy:PERL 语言实现,几乎冷备,仅适用于 MyISAM 存储引擎,使用 LOCK TABLES、FLUSH TABLES和 cp 或 scp 来快速备份数据库。

5.1.7)实战案例: 数据库冷备份和还原

注意: 备份与还原主机的数据库版本要保持一致

MySQL 8.0 ( 数据库冷备份与还原案例 )

冷备份: 生产环境少用,因为冷备份需要停止数据库服务

源主机:192.168.80.130

目标主机:192.168.80.150

注意: 源主机与目标主机都需要安装 rsync 软件包

---- 备份过程 ----

// 在源主机 ( 192.168.80.130 ) 执行 ( 停止数据库服务 )

[root@centos8 ~] yum install rsync -y

[root@centos8 ~] systemctl stop mysqld



// 备份数据  ( 将相关文件复制到远程主机 )

# 如果配置及二进制文件相关有特殊设置也需要备份

[root@centos8 ~] yum install rsync -y

[root@centos8 ~] rsync -a /var/lib/mysql 192.168.80.150:/data/ # 注意: 192.168.80.150 须事先存在 /data/ 目录



---- 还原过程 ----

// 目标主机安装数据库服务

[root@centos8 ~] ll /data                        # 验证冷备份过来的数据

[root@centos8 ~] yum install mysql-server -y     # 目标主机安装数据库服务 ( 需与源主机的数据库版本一致 )



// 将拷贝过来的备份文件复制到相关目录

[root@centos8 ~] cp -a /data/mysql/* /var/lib/mysql/



// 启用数据库服务

[root@centos8 ~] systemctl start mysqld

[root@centos8 ~] systemctl enable mysqld



// 验证

[root@centos8 ~] mysql

Mariadb 10.3

// 在目标服务器 (10.0.0.18) 安装 mariadb-server, 不启动服务

[root@centos8 ~] yum install mariadb-server



// 在源主机 (10.0.0.8) 执行 ( 停止数据库服务 )

[root@centos8 ~] systemctl stop mariadb



// 复制相关文件 ( 将相关文件复制到远程主机 )

[root@centos8 ~] scp -r /var/lib/mysql/* 10.0.0.18:/var/lib/mysql/

[root@centos8 ~] scp /etc/my.cnf.d/mariadb-server.cnf 10.0.0.18:/etc/my.cnf.d/

[root@centos8 ~] scp -r /data/logbin/ 10.0.0.18:/data/    # 10.0.0.18 须事先存在 /data/ 目录



// 复制相关文件并保留属性: 可以用 rsync

[root@centos8 ~] rsync /etc/my.cnf.d/mariadb-server.cnf 10.0.0.18:/etc/my.cnf.d/

[root@centos8 ~] rsync -av /var/lib/mysql/ 10.0.0.18:/var/lib/mysql/

[root@centos8 ~] rsync -av/data/logbin/ 10.0.0.18:/data/    # 10.0.0.18 须事先存在 /data/ 目录



// 在目标主机 (10.0.0.18) 执行

[root@centos8 ~] chown -R mysql.mysql /var/lib/mysql/

[root@centos8 ~] chown -R mysql.mysql /data/logbin/

[root@centos8 ~] systemctl start mariadb

5.2)mysqldump 备份工具

5.2.1)mysqldump 说明

逻辑备份工具:

mysqldump,mydumper,phpMyAdmin( MySQL 数据库服务必须是启动状态 )

Schema 和数据存储在一起、巨大的 SQL 语句、单个巨大的备份文件。

mysqldump 是 MySQL 的客户端命令,通过 mysql 协议连接至 mysql 服务器进行备份。

mysqldump 是 MySQL 自带的逻辑备份工具。

它的备份原理是通过协议连接到 MySQL 数据库,将需要备份的数据查询出来,将查询出的数据转换成对应的 insert 语句,当我们需要还原这些数据时,只要执行这些 insert 语句,即可将对应的数据还原。

命令格式

mysqldump 参考:MySQL :: MySQL 5.7 Reference Manual :: 4.5.4 mysqldump --- A Database Backup Program

// 支持指定数据库和指定多表的备份, 但数据库本身定义不备份

1) 备份指定数据库或指定数据表

mysqldump [OPTIONS] database [tables]



// 支持指定数据库备份, 包含数据库本身定义也会备份

2) -B 备份多个数据库

mysqldump [OPTIONS] -B DB1 [DB2 DB3...]



// 备份所有数据库, 包含数据库本身定义也会备份

3) -A 备份所有数据库

mysqldump [OPTIONS] -A [OPTIONS]


演示:

// 备份单个数据库 hellodb

mysqldump -uroot -p hellodb > /root/hellodb.sql



// 查看备份的 SQL 文件

cat /root/hellodb.sql | grep -i create    ( 发现该 SQL 文件并没有创建数据库的 SQL )
// 还需要我们"手动创建数据库"

// 才能导入成功该 SQL 文件

// ( 但我们并不知道当时创建该数据库时的字符集等等信息 )

// ( 因此不建议使用该备份方式~ )

mysql> create database hellodb;

Query OK, 1 row affected (0.01 sec)



mysql hellodb < hellodb.sql

演示: ( 推荐使用 -B 选项备份数据库 )

// 使用 -B 选项备份数据库

mysqldump -B hellodb hellodb_2 > hellodb_all.sql



// 备份的 SQL 文件存在创建数据库的 SQL 语法

cat hellodb_all.sql | grep -i create
// 非交互式: 删除 hellodb 数据库

mysql -e 'drop database hellodb'

mysql -e 'show databases'



// 导入验证

mysql < /root/hellodb_all.sql

mysql -e 'show databases'

​​​​​​​

演示:( -A 选项: 导出 mysql 数据库 + 自建的数据库

// 备份所有数据库

mysqldump -A > /root/all.sql



// 删库跑路

systemctl stop mysqld

rm -rf /var/lib/mysql/*



// 启用数据库

systemctl start mysqld



# 如果无法启用数据库服务

# 卸载重装数据库服务试试

yum remove mysql-server -y

yum install mysql-server -y



// 还原数据库

mysql < /root/all.sql



// 验证

mysql -e 'show databases'

mysqldump 常见通用选项:

-A, --all-databases         // 备份所有数据库, 含 create database

-B, --databases db_name...  // 指定备份的数据库, 包括 create database 语句

-E, --events:               // 备份相关的所有事件 event scheduler

-R, --routines:             // 备份所有存储过程和自定义函数

--triggers:                 // 备份表相关触发器, 默认启用, 用 --skip-triggers, 不备份触发器

--default-character-set=utf8    // 指定字符集 ( 备份时候建议加该选项 )

--master-data[=N]               // ( "此选项数据库服务需启用二进制日志") "很重要的一个选项"

# 我们使用该选项指定当前备份的时间点

# 后续可以基于二进制日志文件恢复

# 数据被破坏时间段之前 到 最近一个备份数据之间的操作

  1: 所备份的数据之前加一条记录为 CHANGE MASTER TO 语句, 非注释, 不指定 #, 默认为 1, 适合于主从复制多机使用

  2: 记录为被注释的 # CHANGE MASTER TO 语句, 适合于单机使用, ( 适用于备份还原 )

  此选项会自动关闭 --lock-tables 功能, 自动打开-x | --lock-all-tables 功能 (除非开启 --single-transaction)



-F, --flush-logs // 备份前滚动日志, 锁定表完成后, "执行 flush logs 命令, 生成新的二进制日志文件" 配合 -A 或 -B 选项时, 会导致刷新多次数据库. 建议在同一时刻执行转储和日志刷新, 可通过和 --single-transaction 或 -x, "--master-data 一起使用实现, 此时只刷新一次二进制日志" ( 这样就不需要找二进制日志的位置,因为刷新了新的二进制文件,直接将新的二进制文件恢复即可 )

--compact        // 去掉注释, 适合调试, 节约备份占用的空间, ( 生产不建议 )

-d, --no-data    // "只备份表结构,不备份数据" 即只备份 create table

-t, --no-create-info    // "只备份数据,不备份表结构" 即不备份 create table 

-n, --no-create-db       // 不备份 create database, 可被 -A 或 -B 覆盖 ( 默认 )

--flush-privileges      // 备份 MySQL 或相关时需要使用 ( 刷新权限 )

-f, --force            // 忽略 SQL 错误, 继续执行 ( 强制执行 )

--hex-blob             // 使用十六进制符号转储二进制列, 当有包括 BINARY, VARBINARY, BLOB, BIT 的数据类型的列时使用 ( 避免乱码 )

-q, --quick            // 不缓存查询, 直接输出, 加快备份速度

5.2.2)实战案例 ( 重点 )

利用二进制日志,将数据库还原至最新状态

演示:( MySQL 小技巧: 删库跑路如何恢复

实战案例: 利用二进制日志,将数据库还原至最新状态

参考: 记一次mysql从删库到恢复-CSDN博客

参考: 【MySQL】删库跑路?了解下bin-log! - 掘金

mysqldump --master-data[=N]

--master-data=2 ( 适用于备份还原 )( 记录二进制日志文件名和位置 )

0) "前置条件" ( 开启二进制日志功能 )

## 并将二进制日志文件与数据库文件分开存放

1. 创建二进制日志文件的存放目录

mkdir /mysql/data/logbin -pv

chown -R mysql:mysql /mysql/data/logbin/



2. 定义二进制日志文件路径 ( 服务器选项: log-bin )

vim /etc/my.cnf

vim /etc/my.cnf.d/mysql-server.cnf      # MySQL 8.0

[mysqld]

log_bin                                 # 开启二进制日志功能 ( 必须 )

log-bin=/mysql/data/logbin/mysql-bin    # 定义二进制日志文件路径



3. 重启 mariadb 服务

setenforce 0         # 关闭 SELinux ( 重要 )

systemctl restart mariadb.service

# 如重启报错 ( 可以尝试查看日志 tail -f /var/log/mysql/mysqld.log )

# 将报错信息发送至 ChatGPT 为你提供解决思路



4. 验证

ll /mysql/data/logbin

cat /mysql/data/logbin/mysql-bin.index ( 该文件记录当前已有的二进制日志文件列表 )



5. 验证

select @@sql_log_bin;

select @@log_bin;

1) 基于 mysqldump 完全备份数据库

mysqldump -A --master-data=2 > /data/all.sql

mysqldump -A --master-data=2 | gzip > /data/all.sql.gz # 建议: 备份并压缩



2) 备份完成后, "继续操作数据库"

mysql hellodb;

insert teachers values(5,'xiaoming',20,'M');

insert teachers values(6,'xiaohong',18,'F');

select * from teachers;



// 瞅瞅二进制日志

ll /mysql/data/logbin



// 查看完全备份文件

vim /data/all.sql        // 该备份文件 ( 记录着当时二进制文件的备份位置 )

如图:该行记录着 mysqldump 命令运行时

二进制日志文件 binlog 的起始位置, 这有助于我们恢复近期的二进制日志数据

3) 直接"删库跑路"

systemctl stop mysqld

rm -rf /var/lib/mysql/*

4) 先导出有用处的二进制日志文件

# 查看二进制日志文件中记录的备份位置信息

cat /data/all.sql | grep '^-- CHANGE MASTER TO'



# 然后进入二进制日志文件存放目录

cd /mysql/data/logbin



# 从特定的二进制日志位置开始提取数据,并将结果保存到一个新的SQL文件中

# 将有用处的二进制日志信息都导入一个新的 sql 文件

# 也就是执行完完全备份命令后 ( 记录的二进制日志内容 )

mysqlbinlog --start-position=7667 mysql-bin.000002 > /data/binlog.sql



# 验证文件

vim /data/binlog.sql



5) 恢复数据库

systemctl start mysqld  # 启用数据库服务 ( 现在的数据库相当于是新安装的 )



set sql_log_bin=0;      # 先临时禁用二进制日志记录功能 ( 避免在恢复过程中产生更多的日志数据 )

source /data/all.sql    # 还原 mysqldump 数据库文件 ( 完全备份数据 )

source /data/binlog.sql # 还原 binlog 二进制日志数据

set sql_log_bin=1;      # 继续开启二进制日志功能



6) 验证数据库

use hellodb;

select * from teachers;

mysqldump 的 MyISAM 存储引擎相关的备份选项:

MyISAM 不支持事务,只能支持温备;不支持热备

所以必须先锁定要备份的库,而后启动备份操作。

x,--lock-all-tables // "加全局读锁,锁定所有库的所有表" 同时加 --single-transaction 或 --lock-tables 选项会关闭此选项功能, 注意: 数据量大时, 可能会导致长时间无法并发访问数据库

-l,--lock-tables // 对于需要备份的每个数据库, 在启动备份之前分别锁定其所有表, 默认为 on, --skip-lock-tables 选项可禁用, 对备份 MyISAM 的多个库, 可能会造成数据不一致

// 注: 以上选项对 InnoDB 表一样生效, 实现温备, 但不推荐使用

mysqldump 的 InnoDB 存储引擎相关的备份选项:

InnoDB 存储引擎支持事务,可以利用事务的相应的隔离级别,实现热备, 也可以实现温备但不建议用。

--single-transaction

// 此选项 Innodb 中推荐使用, 不适用 MyISAM

// "此选项会开始备份前, 先执行 START TRANSACTION 指令开启事务" ( 热备 )

// 此选项通过在单个事务中转储所有表来创建一致的快照. 仅适用于存储在支持多版本控制的存储引擎中的表 ( 目前只有 InnoDB 可以); 转储不保证与其他存储引擎保持一致. 在进行单事务转储时,要确保有效的转储文件 ( 正确的表内容和二进制日志位置 ), 没有其他连接应该使用以下语句: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, 此选项和 --lock-tables ( 此选项隐含提交挂起的事务 ) 选项是相互排斥, 备份大型表时,建议将 --single-transaction 选项和 --quick 结合一起使用

5.2.3) 生产环境实战备份策略

InnoDB 建议备份策略

--single-transaction 确保备份在单个事务中完成。

--master-data=1 这个选项的作用是在备份中包含复制相关的信息。

--flush-privileges 在备份后刷新 MySQL 的权限

--default-character-set=utf8确保了导出的数据使用 UTF-8 编码

mysqldump -uroot -pP@ssw0rd123456 -A -F -E -R --triggers --single-transaction --master-data=1 --flush-privileges --default-character-set=utf8 --hex-blob

>{BACKUP}/fullbak_{BACKUP_TIME}.sql

MyISAM 建议备份策略

-X ( 全局读锁 )

mysqldump -uroot -pP@ssw0rd123456 -A -F -E -R -x --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob >{BACKUP}/fullbak_{BACKUP_TIME}.sql

5.2.3) mysqldump 备份还原实战案例

5.2.3.1)实战案例: 特定数据库 的备份脚本

[root@centos8 ~] vim mysql_backup.sh

#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

TIME=`date +%F_%H-%M-%S`

DIR=/backup # 备份数据库的目录

DB=hellodb # 注意修改需要备份的数据库名称

PASS=P@ssw0rd123456 # 数据库密码

[ -d $DIR ] || mkdir $DIR

mysqldump -uroot -p "$PASS" -F -E -R --triggers --single-transaction --master-data=2 --default-character-set=utf8 -q -B $DB | gzip > {DIR}/{DB}_${TIME}.sql.gz

// 授权

chmod +x mysql_backup.sh

// 计划任务

crontab -e

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

18 * * * * /root/mysql_backup.sh

// 验证

ll /backup

// 测试备份数据是否可以用于还原 ( "重要" )

cd /backup && gzip -d hellodb_2024-02-02_22-18-01.sql.gz

// 删库跑路

mysql

drop database hellodb;

// 测试还原

set sql_log_bin=0; # 临时禁用二进制日志功能

source /backup/hellodb_2024-02-02_22-18-01.sql

set sql_log_bin=1; # 开启二进制日志功能

// 验证数据库

show tables;

5.2.3.2)实战案例: 分库备份并压缩

// 方式一

[root@centos8 ~] for db in `mysql -uroot -e 'show databases' | grep -Ev '^(Database|information_schema|performance_schema)$'`;do mysqldump -B db \| gzip \> /backup/db.sql.gz;done

// 方式二

[root@centos8 ~] mysql -uroot -e 'show databases' | grep -Ev '^(Database|information_schema|performance_schema)$' | while read db;do mysqldump -B db \| gzip \> /backup/db.sql.gz;done

// 方式三

[root@centos8 ~] mysql -uroot -e 'show databases' | grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' | bash

// 方式四

[root@centos8 ~] mysql -uroot -e 'show databases' | sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' | bash

5.2.3.3)实战案例: 分库备份 的实战脚本

// 列出 MySQL 服务器上的所有数据库

// 并从中排除 Database、schema和 sys 这三个数据库

mysql -uroot -e'show databases'

mysql -uroot -e'show databases' | grep -Ev "^Database|.*schema$|sys"

[root@centos8 ~] cat backup_db.sh

#!/bin/bash

TIME=`date +%F_%H-%M-%S`

DIR=/backup # 备份数据库的目录

PASS=P@ssw0rd123456 # 数据库密码

[ -d "$DIR" ] || mkdir $DIR

for DB in `mysql -uroot -p "PASS" -e 'show databases' \| grep -Ev "\^Database\|.\*schema|sys"`;do

mysqldump -F --single-transaction --master-data=2 --default-character-set=utf8 -q -B $DB | gzip > {DIR}/{DB}_${TIME}.sql.gz

done

// 运行脚本

bash backup_db.sh

// 验证

ll /backup

5.2.3.4)实战案例: 完全备份和还原

// 开启二进制日志

[root@centos8 ~] vim /etc/my.cnf.d/mariadb-server.cnf

[mysqld]

log-bin

// 备份

[root@centos8 ~] mysqldump -uroot -pmagedu -A -F --single-transaction --master-data=2 | gzip > /backup/all-`date +%F`.sql.gz

// 还原

[root@centos8 backup] yum install mariadb-server

[root@centos8 backup] gzip -d all-2019-11-27.sql.gz

[root@centos8 ~] mysql

MariaDB [(none)]> set sql_log_bin=off;

MariaDB [(none)]> source /backup/all-2019-11-27.sql

MariaDB [(none)]> set sql_log_bin=on;

5.2.3.5)实战案例: 利用二进制日志,还原数据库最新状态

// 二进制日志独立存放

[mysqld]

log-bin=/data/mysql/mysql-bin

// 完全备份, 并记录备份的二进制位置

mysqldump -uroot -pmagedu -A -F --default-character-set=utf8 --single-transaction --master-data=2 | gzip > /backup/all_`date +%F`.sql.gz

// 修改数据库

insert students (name,age,gender)value('mage',20,'M');

insert students (name,age,gender)value('wang',22,'M');

// 损坏数据库

rm -rf /var/lib/mysql/*

// 还原

cd /backup

gzip -d all_2019-11-25.sql.gz

// CentOS 8 需要事先生成数据库相关文件, CentOS7 不需要执行此步

mysql_install_db --user=mysql

systemctl restart mariadb

MariaDB [(none)]> show master logs;

+------------------+-----------+

| Log_name | File_size |

+------------------+-----------+

| mysql-bin.000001 | 998 |

| mysql-bin.000002 | 28090 |

| mysql-bin.000003 | 342 |

+------------------+-----------+

3 rows in set (0.000 sec)

MariaDB [(none)]> set sql_log_bin=0;

MariaDB [(none)]> source /data/all_2019-11-25.sql

[root@centos8 ~] grep '^-- CHANGE MASTER TO' /data/all_2019-11-25.sql -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=328;

// 二进制日志的备份

[root@centos8 mysql] mysqlbinlog mysql-bin.000001 --start-position=328 > /backup/inc.sql

[root@centos8 mysql] mysqlbinlog mysql-bin.000002 >> /backup/inc.sql

MariaDB [(none)]> set sql_log_bin=0;

MariaDB [(none)]> source /backup/inc.sql

MariaDB [(none)]> set sql_log_bin=1;

5.2.3.6)实战案例:mysqldump 和二进制日志结合实现差异(增量)备份

[root@centos8 ~] mysqldump -uroot -p -A -F --single-transaction --master-data=2 | gzip > /backup/all-`date +%F`.sql.gz

// 观察上面备份文件中记录的二进制文件和位置, 定期将其之后生成的所有二进制日志进行复制备份

[root@centos8 ~] cp /var/lib/mysql/mariadb-bin.000003 /backup // 假设 mariadb-bin.000003 是后续生成的二进制日志

[root@centos8 ~] mysqlbinlog backup/mariadb-bin.000003 > /backup/inc.sql

5.2.3.7)实战案例: 恢复误删除的表

案例说明

每天 2:30 做完全备份 ,早上 10:00 误删除 了表 students,10:10 才发现故障

现需要将数据库还原到 10:10 的状态,且恢复被删除的 students 表。

思路分析

停止数据库服务

将数据 还原到 2:30 的完全备份状态

再通过二进制日志还原

默认:二进制日志记录到了 10:10 你停止数据库的时间

因此:此二进制日志文件中记录着 10:00 删表的动作

所以:我们可以 将该二进制日志文件中的删表动作去除

然后基于 该去除了删除操作的二进制日志内容将数据还原( 此期间需要关闭二进制日志记录功能 )

实际操作

前置操作

验证数据库的二进制日志功能是否开启( 且二进制日志文件存放在不同目录 )

二进制日志类型( ROW 行类型 )

  1. "前置条件" ( 开启二进制日志功能 )

并将二进制日志文件与数据库文件分开存放

  1. 创建二进制日志文件的存放目录

mkdir /mysql/data/logbin -pv

chown -R mysql:mysql /mysql/data/logbin/

  1. 定义二进制日志文件路径 ( 服务器选项: log-bin )

vim /etc/my.cnf

vim /etc/my.cnf.d/mysql-server.cnf # MySQL 8.0

[mysqld]

log_bin # 开启二进制日志功能 ( 必须 )

log-bin=/mysql/data/logbin/mysql-bin # 定义二进制日志文件路径

  1. 重启 mariadb 服务

setenforce 0 # 关闭 SELinux ( 重要 )

systemctl restart mariadb.service

如重启报错 ( 可以尝试查看日志 tail -f /var/log/mysql/mysqld.log )

将报错信息发送至 ChatGPT 为你提供解决思路

  1. 验证

ll /mysql/data/logbin

cat /mysql/data/logbin/mysql-bin.index ( 该文件记录当前已有的二进制日志文件列表 )

  1. 验证

select @@sql_log_bin;

select @@log_bin;

select @@binlog_format; # 查看二进制日志类型

模拟 误删数据

模拟 2:30 的完全备份

模拟 2:30 -10:00 之间的数据更新

模拟 10:00 误删除了一个重要的表

模拟 10:00 后其他表数据还在更新

模拟 10:10 发现异常

模拟 还原过程

停止数据库服务

基于 mysqlbinlog 导出二进制日志文件内容

将二进制日志文件中的删表操作去除!

准备还原数据库

启用数据库服务

登录数据库,临时关闭二进制日志功能

先还原完全备份数据

再还原二进制日志文件数据

开启二进制日志功能

验证数据库内容

// 模拟 2:30 的完全备份

// -F 选项会刷新使用一个新的二进制日志文件

[root@centos8 ~] mysqldump -uroot -p -A -F --single-transaction --master-data=2 > /backup/allbackup_`date +%F_%T`.sql

[root@centos8 ~] ll /backup/

-rw-r--r--. 1 root root 1235591 Feb 3 13:31 allbackup_2024-02-03_13:31:12.sql

// 完全备份后的数据更新 ( 模拟 2:30 -10:00 之间的数据更新 )

use hellodb;

insert students (stuid,name,age,gender) values('50','rose',20,'f');

insert students (stuid,name,age,gender) values('60','bob',20,'m');

// 模拟 10:00 误删除了一个重要的表

drop table students;

// 后续其它表继续更新 ( 模拟 10:00 后其他表数据还在更新 )

use hellodb1;

insert teachers (tid,name,age,gender) values('50','wangj',20,'f');

insert teachers (tid,name,age,gender) values('60','wangjun',20,'m');

MariaDB [hellodb1]> select * from teachers;

+-----+---------------+-----+--------+

| TID | Name | Age | Gender |

+-----+---------------+-----+--------+

| 1 | Song Jiang | 45 | M |

| 2 | Zhang Sanfeng | 94 | M |

| 3 | Miejue Shitai | 77 | F |

| 4 | Lin Chaoying | 93 | F |

| 50 | wangj | 20 | f |

| 60 | wangjun | 20 | m |

+-----+---------------+-----+--------+

6 rows in set (0.00 sec)

// 10:10 发现表删除 ( 模拟 10:10 发现异常 )

// 先停止数据库

systemctl stop mysqld

// 从完全备份中, 找到二进制位置 ( 找到 2:30 - 10:10 使用的二进制日志文件名称 )

[root@centos8 ~] grep '\-\- CHANGE MASTER TO' /backup/allbackup_2024-02-03_13\:31\:12.sql

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=156; # 得到的信息

// "基于 mysqlbinlog 导出二进制日志文件内容"

[root@centos8 ~] mysqlbinlog --start-position=156 /mysql/data/logbin/mysql-bin.000003 > /backup/inc.sql

// 找到误删除的语句, 从备份文件中删除此语句

// 也就是将二进制日志文件中的删表操作去除!

[root@centos8 ~] vim /backup/inc.sql

DROP TABLE `student_info` /* generated by server */

// 注: 如果文件过大, 可以使用 sed 实现 ( "重要" )

[root@centos8 ~] sed -i.bak '/^DROP TABLE/d' /backup/inc.sql

// 利用完全备份和修改过的二进制日志进行还原操作

[root@centos8 ~] systemctl start mysqld # 启用数据库服务

[root@centos8 ~] mysql -uroot -p

MariaDB [hellodb]> set sql_log_bin=0; # 临时关闭二进制日志功能

MariaDB [hellodb]> source /backup/allbackup_2024-02-03_13:31:12.sql;

MariaDB [hellodb]> source /backup/inc.sql;

MariaDB [hellodb]> set sql_log_bin=1; # 开启二进制日志功能

// "验证数据库"

mysql -e 'show databases';

mysql -e 'select * from hellodb.students;'

mysql -e 'select * from hellodb1.teachers;'

基于如上案例,我们可以得知开启二进制日志功能的重要性,以及每天做全量备份的重要性。

注意: 二进制日志文件不要与数据库文件存放同一个目录。全量备份的文件也应该不存放于本机,而存放在其他主机。异机器备份。

5.3)xtrabackup 备份工具

5.3.1)xtrabackup 工具介绍

由于 mysqldump 工具 只能对数据库进行全量备份,无法做增量备份与差异备份。

因此 xtrabackup 闪亮登场。( xtrabackup 可以做增量与差异备份 )

Percona 公司

官网: www.percona.com

percona-server

InnoDB --> XtraDB

Xtrabackup 备份工具

percona 提供的 mysql 数据库备份工具

唯一开源的能够对 innodb 和 xtradb 数据库进行热备的工具。

手册: Percona XtraBackup

下载: Software Downloads - Percona

xtrabackup 2.4 和 8.0 区别

xtrabackup 2.4: 它仅支持备份 MySQL 5.1、5.5、5.6 和 5.7 服务器上的 InnoDB、XtraDB 和 MyISAM 表中的数据,不支持备份 MySQL 8.0。

xtrabackup 8.0: 仅支持备份 MySQL 8.0。

xtrabackup 特点:

备份还原过程快速、可靠

备份过程不会打断正在执行的事务

能够基于压缩等功能节约磁盘空间和流量

自动实现备份检验

开源,免费

xtrabackup 工具文件组成

Xtrabackup 2.2 版之前 包括 4 个可执行文件:

innobackupex:Perl 脚本

xtrabackup:C/C++,编译的二进制程序

xbcrypt:加解密

xbstream:支持并发写的流文件格式

说明:

xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 MySQL Server 没有交互。

innobackupex 脚本 用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 MySQL Server 发送命令进行交互,如加全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即 innobackupex 是在 xtrabackup 之上做了一层封装实现的。

xtrabackup 的新版变化

xtrabackup 版本升级到 2.4 后,相比之前的 2.1 有了比较大的变化:

innobackupex 功能全部集成到 xtrabackup 里面,只有一个 binary 程序,另外为了兼容考虑,innobackupex 作为 xtrabackup 的软链接,即 xtrabackup 现在支持非 Innodb 表备份,并且 Innobackupex 在下一版本中移除,建议通过 xtrabackup 替换 innobackupex。

xtrabackup 备份过程

参考:https://www.cnblogs.com/allenhu320/p/11311056.html

参考:https://www.cnblogs.com/linuxk/p/9372990.html

备份生成的相关文件

使用 innobackupex 备份时,其会调用 xtrabackup 备份所有的 InnoDB 表,复制所有关于表结构定义的相关文件(.frm)、以及 MyISAM、MERGE、CSV 和 ARCHIVE 表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命名的目录中,在备份时, innobackupex 还会在备份目录中创建如下文件:

xtrabackup_info:文本文件,innobackupex 工具执行时的相关信息,包括版本,备份选项,备份时长,备份 LSN( log sequence number 日志序列号 ),BINLOG 的位置。

xtrabackup_checkpoints:文本文件,备份类型(如完全或增量)、备份状态(如是否已经为 prepared 状态)和 LSN 范围信息,每个 InnoDB 页(通常为 16k 大小)都会包含一个日志序列号 LSN。LSN 是整个数据库系统的系统版本号,每个页面相关的 LSN 能够表明此页面最近是如何发生改变的。

xtrabackup_binlog_info:文本文件,MySQL 服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置,可利用实现基于 binlog 的恢复。

backup-my.cnf:文本文件,备份命令用到的配置选项信息。

xtrabackup_logfile:备份生成的二进制日志文件。

**范例:**相关文件

[root@centos8 ~] ll /backup/

total 12340

-rw-r----- 1 root root 487 Jun 12 15:07 backup-my.cnf

drwxr-x--- 2 root root 272 Jun 12 15:07 hellodb

-rw-r----- 1 root root 425 Jun 12 15:07 ib_buffer_pool

-rw-r----- 1 root root 12582912 Jun 12 15:07 ibdata1

drwxr-x--- 2 root root 4096 Jun 12 15:07 mysql

drwxr-x--- 2 root root 8192 Jun 12 15:07 performance_schema

drwxr-x--- 2 root root 8192 Jun 12 15:07 sys

-rw-r----- 1 root root 25 Jun 12 15:07 xtrabackup_binlog_info

-rw-r----- 1 root root 135 Jun 12 15:07 xtrabackup_checkpoints

-rw-r----- 1 root root 479 Jun 12 15:07 xtrabackup_info

-rw-r----- 1 root root 2560 Jun 12 15:07 xtrabackup_logfile

[root@centos8 ~] cat /backup/xtrabackup_info

uuid = 55a26ea0-ac7b-11ea-a8ab-000c293f7395

name =

tool_name = xtrabackup

tool_command = -uroot -pmagedu --backup --target-dir=/backup/

tool_version = 2.4.20

ibbackup_version = 2.4.20

server_version = 5.7.29-log

start_time = 2020-06-12 15:07:08

end_time = 2020-06-12 15:07:10

lock_time = 1

binlog_pos = filename 'centos8-bin.000002', position '10185'

innodb_from_lsn = 0

innodb_to_lsn = 2687527

partial = N

incremental = N

format = file

compact = N

compressed = N

encrypted = N

[root@centos8 ~] cat /backup/xtrabackup_checkpoints

backup_type = full-backuped

from_lsn = 0

to_lsn = 2687527

last_lsn = 2687536

compact = 0

recover_binlog_info = 0

flushed_lsn = 2687536

[root@centos8 ~] cat /backup/xtrabackup_binlog_info

centos8-bin.000002 10185

[root@centos8 ~] cat /backup/backup-my.cnf

This MySQL options file was generated by innobackupex.

The MySQL server

[mysqld]

innodb_checksum_algorithm=crc32

innodb_log_checksum_algorithm=strict_crc32

innodb_data_file_path=ibdata1:12M:autoextend

innodb_log_files_in_group=2

innodb_log_file_size=50331648

innodb_fast_checksum=false

innodb_page_size=16384

innodb_log_block_size=512

innodb_undo_directory=./

innodb_undo_tablespaces=0

server_id=1

redo_log_version=1

server_uuid=6fb9641a-ac79-11ea-8bed-000c293f7395

master_key_id=0

[root@centos8 ~] file /backup/xtrabackup_logfile

/backup/xtrabackup_logfile: data

5.3.2)xtrabackup 安装

// CentOS7 默认 EPEL 源中的 xtrabackup 版本比较老 2.3 的

[root@centos7 ~] yum info percona-xtrabackup

Available Packages

Name : percona-xtrabackup

Arch : x86_64

Version : 2.3.6

Release : 1.el7

Size : 4.6 M

Repo : epel/7/x86_64

Summary : Online backup for InnoDB/XtraDB in MySQL, Percona Server and MariaDB

URL : http://www.percona.com/software/percona-xtrabackup/

License : GPLv2

Description : Online backup for InnoDB/XtraDB in MySQL, MariaDB and Percona Server.

// CentOS 8 默认没有提供 xtrabackup 软件包

[root@centos8 ~] yum info percona-xtrabackup

范例: xtrabackup 软件包的下载及安装

Software Downloads - Percona

Index of /percona/centos/7/RPMS/x86_64/

Index of /pub/percona/percona/yum/release/8/RPMS/x86_64/

// CentOS7 默认的数据库版本比较老,因此建议使用 xtrabackup 2.4 版本

// 安装 CentOS7 默认数据库

[root@centos7 ~] yum install mariadb-server -y

[root@centos7 ~] systemctl enable --now mariadb

// 上传 CentOS7 版本的 xtrabackup 2.4 版本软件包 ( 并安装 )

[root@centos7 ~] yum install percona-xtrabackup-24-2.4.20-1.el7.x86_64.rpm -y

[root@centos7 ~] rpm -ql percona-xtrabackup-24-2.4.20

[root@centos7 ~] file /usr/bin/xtrabackup

// 验证版本

[root@centos7 ~] xtrabackup -v

// CentOS8 默认的数据库版本为 MySQL8.0,因此建议使用 xtrabackup 8.0 版本

// 安装 CentOS8 默认数据库

[root@centos8 ~] yum install mysql-server -y

[root@centos8 ~] systemctl enable --now mysqld

// 上传 CentOS8 版本的 xtrabackup 8.0 版本软件包 ( 并安装 )

[root@centos8 ~] ll percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

[root@centos8 ~] yum install percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm -y

[root@centos8 ~] rpm -ql percona-xtrabackup-80-8.0.23

[root@centos8 ~] file /usr/bin/xtrabackup

// 验证版本

[root@centos8 ~] xtrabackup -v

5.3.3)xtrabackup 用法

xtrabackup 工具备份和还原,需要三步实现

备份:对数据库做完全或增量备份

预准备: 还原前,先对备份的数据,整理至一个临时目录

还原:将整理好的数据,复制回数据库目录中

xtrabackup 选项参考:

Percona XtraBackup

备份:

innobackupex [option] BACKUP-ROOT-DIR

选项说明:

--user 该选项表示备份账号

--password 该选项表示备份的密码

--host 该选项表示备份数据库的地址

--databases: 该选项接受的参数为数据库名, 如果要指定多个数据库, 彼此间需要以空格隔开;

如:"xtra_test dba_test" 同时, 在指定某数据库时, 也可以只指定其中的某张表.

如:"mydatabase.mytable" 该选项对innodb引擎表无效, 还是会备份所有innodb表

--defaults-file: 该选项指定从哪个文件读取MySQL配置, 必须放在命令行第一个选项位置

--incremental: 该选项表示创建一个增量备份, 需要指定 --incremental-basedir

--incremental-basedir: 该选项指定为前一次全备份或增量备份的目录, 与 --incremental 同时使用

--incremental-dir: 该选项表示还原时增量备份的目录

--include=name: 指定表名, 格式: databasename.tablename

Prepare 预准备:

innobackupex --apply-log [option] BACKUP-DIR

选项说明:

--apply-log // 一般情况下, 在备份完成后, 数据尚且不能用于恢复操作, 因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务. 因此, 此时数据文件仍处理不一致状态. 此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态.

--use-memory // 和 --apply-log 选项一起使用, 当 prepare 备份时, 做 crash recovery 分配的内存大小, 单位字节, 也可 1MB, 1M, 1G, 1GB 等, 推荐 1G

--export: // 表示开启可导出单独的表之后再导入其他 MySQL 中

--redo-only // 此选项在 prepare base full backup, 往其中合并增量备份时候使用, 但不包括对最后一个增量备份的合并

还原:

innobackupex --copy-back [选项] BACKUP-DIR

innobackupex --move-back [选项] [--defaults-group=GROUP-NAME] BACKUP-DIR

选项说明:

--copy-back: 做数据恢复时将备份数据文件拷贝到 MySQL 服务器的 datadir

--move-back: 这个选项与 --copy-back 相似, 唯一的区别是它不拷贝文件, 而是移动文件到目的地

这个选项移除backup文件, 用时候必须小心. 使用场景: 没有足够的磁盘空间同事保留数据文件和 Backup 副本

--force-non-empty-directories: 指定该参数时候, 使得 innobackupex --copy-back 或 --move-back 选项转移文件到非空目录, 已存在的文件不会被覆盖.

如果 --copy-back 和 --move-back 文件需要从备份目录拷贝一个在 datadir 已经存在的文件, 会报错失败

还原注意事项

datadir 目录必须为空。除非指定 innobackupex --force-non-empty-directorires 选项指定,否则 --copy-back 选项不会覆盖。

在 restore 之前,必须 shutdown MySQL 实例,不能将一个运行中的实例 restore 到 datadir 目录中

由于文件属性会被保留,大部分情况下需要在启动实例之前将文件的属主改为 mysql,这些文件将属于创建备份的用户,执行 chown -R mysql:mysql /data/mysql,以上需要在用户调用 innobackupex 之前完成。

5.3.4)实战案例:利用 xtrabackup 实现完全备份及还原

**注意:**目前 percona-xtrabackup-24-2.4.18-1.el8.x86_64.rpm 不支持 CentOS 8 上的 mariadb-10.3 版本

案例: 利用 xtrabackup 8.0 ( 完全备份和还原 MySQL8.0 )

  1. 安装 xtrabackup 包

[root@centos8 ~] yum -y install percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

  1. 在原主机做完全备份到 /backup

[root@centos8 ~] mkdir /backup

[root@centos8 ~] xtrabackup -uroot -pmagedu --backup --target-dir=/backup/base

// 目标主机无需创建 /backup 目录, 直接复制目录本身

[root@centos8 ~] scp -r /backup/ 目标主机:/


  1. 在目标主机上还原
  1. 预准备: 确保数据一致, 提交完成的事务, 回滚未完成的事务

[root@centos8 ~] yum -y install percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

[root@centos8 ~] xtrabackup --prepare --target-dir=/backup/base

  1. 复制到数据库目录

注意: 数据库目录必须为空, MySQL 服务不能启动

[root@centos8 ~] xtrabackup --copy-back --target-dir=/backup/base

  1. 还原属性

[root@centos8 ~] chown -R mysql:mysql /var/lib/mysql

  1. 启动服务

[root@centos8 ~] service mysqld start

演示: 使用xtrabackup 2.4 实现 完全备份及还原

本案例基于 CentOS 7 的 Mariadb5.5 实现,也支持 MySQL5.5 和 MySQL5.7

  1. 安装 xtrabackup 包

// 先安装 Mariadb5.5 和 xtrabackup 包

[root@centos7 ~] yum install mariadb-server -y

[root@centos7 ~] systemctl enable --now mariadb

[root@centos7 ~] yum -y install percona-xtrabackup-24-2.4.20-1.el7.x86_64.rpm

  1. 在源主机做"完全备份" ( 备份到 /backup 目录 )

[root@centos7 ~] mkdir /backup

将源主机数据库数据完全备份至 /backup 目录 ( 注意修改数据库密码 )

[root@centos7 ~] xtrabackup -uroot -pP@ssw0rd --backup --target-dir=/backup/base

[root@centos7 ~] ll /backup/base # 验证完全备份目录

[root@centos7 ~] cat /backup/base/xtrabackup_info

[root@centos7 ~] cat /backup/base/xtrabackup_checkpoints # 可以看出是完全备份 ( full-backuped )

backup_type = full-backuped

flushed_lsn = 1628418 # LSN 是 InnoDB 用来标记日志记录位置的数字, 它表示了数据修改的顺序. 每当有数据变更 (插入,更新或删除) 发生时, LSN 都会递增.

// 将 /backup 目录数据 "拷贝至远程主机"

目标主机无需创建 /backup 目录

[root@centos7 ~] scp -r /backup/ 目标主机:/

[root@centos7 ~] scp -r /backup/ 192.168.80.220:/

目标主机验证数据 ( 完成异机备份 )

[root@centos7 ~] ll /backup/base/


  1. 在"目标主机还原"

3.1) 预准备: 确保备份数据的完整性和可用性 ( 提交完成的事务,回滚未完成的事务 )

[root@centos7 ~] yum install mariadb-server -y

[root@centos7 ~] yum -y install percona-xtrabackup-24-2.4.20-1.el7.x86_64.rpm

[root@centos7 ~] xtrabackup --prepare --target-dir=/backup/base # 执行预准备操作

InnoDB: FTS optimize thread exiting.

InnoDB: Starting shutdown...

InnoDB: Shutdown completed; log sequence number 1628712

240203 17:05:58 completed OK!

完成

3.2) "将备份的数据文件复制回原始位置"

// 注意: 数据库目录必须为空 ( 且 MySQL 服务不能启动 )

[root@centos7 ~] ll /var/lib/mysql # 验证数据库目录

[root@centos7 ~] systemctl stop mariadb # 关闭 MySQL 服务

[root@centos7 ~] xtrabackup --copy-back --target-dir=/backup/base

240203 17:09:48 [01] ...done

240203 17:09:48 completed OK!

完成

[root@centos7 ~] ll /var/lib/mysql # 验证数据库目录 ( 有数据咯 )

3.3) 还原属性

[root@centos7 ~] chown -R mysql:mysql /var/lib/mysql

3.4) 启动服务

[root@centos7 ~] systemctl enable --now mariadb

3.5) 验证数据

[root@centos7 ~] mysql

案例: 旧版 xtrabackup 2.2 完全备份及还原

  1. 在源主机备份

innobackupex --user=root /backup

scp -r /backup/2018-02-23_11-55-57/ 目标主机:/data/

  1. 在目标主机预准备并还原

// 预准备

innobackupex --apply-log /data/2018-02-23_11-55-57/

// 还原过程

systemctl stop mariadb

rm -rf /var/lib/mysql/*

innobackupex --copy-back /data/2018-02-23_11-55-57/

chown -R mysql.mysql /var/lib/mysql/

systemctl start mariadb

5.3.5)实战案例:利用 xtrabackup 完全备份, 增量备份及还原

案例: 利用 xtrabackup 8.0 完全备份, 增量备份及还原 MySQL8.0

在面对海量数据时,我们无法做到每天全量备份,因此 只能每周做一次全量备份

而每天的话则进行增量备份 ,确保数据安全。

注意点: MySQL 8.0.26 版本对应需要安装 8.0.26 版本的 xtrabackup 软件包

Index of /pub/percona/percona/yum/release/8/RPMS/x86_64/

  1. 前置条件 ( 源主机与目标主机都安装好 MySQL 服务 )

[root@centos8 ~] yum install mysql-server -y

[root@centos8 ~] systemctl enable --now mysqld


  1. 备份过程

1.1) 先做"完全备份"

[root@centos8 ~] yum install percona-xtrabackup-80-8.0.26-18.1.el8.x86_64.rpm -y

[root@centos8 ~] mkdir /backup/

[root@centos8 ~] xtrabackup -uroot -pP@ssw0rd123456 --backup --target-dir=/backup/base --no-server-version-check # 完全备份

验证备份目录

[root@centos8 ~] ll /backup

1.2) 第一天: 修改数据

insert teachers values(20,'wang',18,'M');

insert teachers values(21,'mage',18,'M');

1.3) 第一次"增量备份"

基于 完全备份 做增量备份

基于 /backup/base 做增量备份, 备份在 /backup/inc1 目录

[root@centos8 ~] xtrabackup -uroot -pP@ssw0rd123456 --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base --no-server-version-check # 增量备份

验证备份目录

[root@centos8 ~] ll /backup

1.4) 第二天: 修改数据

insert teachers values(25,'wangj',18,'M');

insert teachers values(26,'wangjun',18,'M');

1.5) 第二次"增量备份"

基于 第一次增量备份 继续做增量备份

基于 /backup/inc1 做增量备份, 备份在 /backup/inc2 目录

[root@centos8 ~] xtrabackup -uroot -pP@ssw0rd123456 --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1 --no-server-version-check # 增量备份

验证备份目录

[root@centos8 ~]# ll /backup

total 12

drwxr-x---. 6 root root 4096 Feb 4 10:48 base # 全量备份数据库

drwxr-x---. 6 root root 4096 Feb 4 10:50 inc1 # 第一次增量备份

drwxr-x---. 6 root root 4096 Feb 4 10:50 inc2 # 第二次增量备份

1.6) 复制所有备份数据到目标主机 ( 目标主机需要存在 /backup 目录 )

[root@centos8 ~] scp -r /backup/* 目标主机:/backup/

[root@centos8 ~] scp -r /backup/* 192.168.80.150:/backup/

备份过程会生成三个备份目录

/backup/{base,inc1,inc2}


  1. 还原过程

2.1) "预准备"完全备份 ( 此选项 --apply-log-only 阻止回滚未完成的事务 )

[root@centos8 ~] yum install percona-xtrabackup-80-8.0.26-18.1.el8.x86_64.rpm -y

预处理完全备份数据

[root@centos8 ~] xtrabackup --prepare --apply-log-only --target-dir=/backup/base

2.2) 合并第 1 次增量备份到完全备份

[root@centos8 ~] xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1

2.3) 合并第 2 次增量备份到完全备份

// 最后一次还原不需要加选项 --apply-log-only

[root@centos8 ~] xtrabackup --prepare --target-dir=/backup/base --incremental-dir=/backup/inc2

2.4) 复制备份数据到数据库目录

注意: 数据库目录必须为空, MySQL 服务不能启动

[root@centos8 ~] systemctl stop mysqld # MySQL 服务不能启动

[root@centos8 ~] rm -rf /var/lib/mysql/* # 数据库目录必须为空

[root@centos8 ~] xtrabackup --copy-back --target-dir=/backup/base # 复制备份数据到数据库目录

2.5) 还原属性

[root@centos8 ~] chown -R mysql:mysql /var/lib/mysql

2.6) 启动服务

[root@centos8 ~] systemctl enable --now mysqld

2.7) 验证数据

[root@centos8 ~] mysql

mysql> select * from teachers;

+-----+---------------+-----+--------+

| TID | Name | Age | Gender |

+-----+---------------+-----+--------+

| 1 | Song Jiang | 45 | M |

| 2 | Zhang Sanfeng | 94 | M |

| 3 | Miejue Shitai | 77 | F |

| 4 | Lin Chaoying | 93 | F |

| 20 | wang | 18 | M |

| 21 | mage | 18 | M |

| 25 | wangj | 18 | M |

| 26 | wangjun | 18 | M |

+-----+---------------+-----+--------+

8 rows in set (0.00 sec)

案例: 新版 xtrabackup 完全备份,增量备份及还原


  1. 备份过程

1.1) 完全备份

[root@centos8 ~] mkdir /backup/

[root@centos8 ~] xtrabackup -uroot -pmagedu --backup --target-dir=/backup/base

1.2) 第一次修改数据

1.3) 第一次增量备份

[root@centos8 ~] xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base

// 查看 xtrabackup 相关文件

[root@centos8 ~] cat /backup/inc1/xtrabackup_info

[root@centos8 ~] cat /backup/inc1/xtrabackup_checkpoints

[root@centos8 ~] cat /backup/inc1/xtrabackup_binlog_info

1.4) 第二次修改数据

1.5) 第二次增量

[root@centos8 ~] xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1

// 查看 xtrabackup 相关文件

[root@centos8 ~] cat /backup/inc2/xtrabackup_info

[root@centos8 ~] cat /backup/inc2/xtrabackup_checkpoints

[root@centos8 ~] cat /backup/inc2/xtrabackup_binlog_info

1.6)

[root@centos8 ~] scp -r /backup/* 目标主机:/backup/

// 备份过程生成三个备份目录

/backup/{base,inc1,inc2}


  1. 还原过程

2.1) 预准备完成备份, 此选项 --apply-log-only 阻止回滚未完成的事务

[root@centos8 ~] xtrabackup --prepare --apply-log-only --target-dir=/backup/base

2.2) 合并第 1 次增量备份到完全备份

[root@centos8 ~] xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1

2.3) 合并第 2 次增量备份到完全备份: 最后一次还原不需要加选项 --apply-log-only

[root@centos8 ~] xtrabackup --prepare --target-dir=/backup/base --incremental-dir=/backup/inc2

2.4) 复制到数据库目录, 注意数据库目录必须为空, MySQL 服务不能启动

[root@centos8 ~] xtrabackup --copy-back --target-dir=/backup/base

2.5) 还原属性:

[root@centos8 ~] chown -R mysql:mysql /var/lib/mysql

2.6) 启动服务:

[root@centos8 ~] service mysqld start

案例: 旧版 xtrabackup 完全备份,增量备份及还原

  1. 在源主机备份

innobackupex /backup

mkdir /backup/inc{1,2}

// 修改数据库内容

innobackupex --incremental /backup/inc1 --incremental-basedir=/backup/2018-02-23_14-21-42 (完全备份生成的路径 )

// 再次修改数据库内容

innobackupex --incremental /backup/inc2 --incremental-basedir=/backup/inc1/2018-02-23_14-26-17 ( 上次增量备份生成的路径 )

scp -r /backup/* 目标主机:/data/

  1. 在目标主机还原

// 预准备过程

innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/

innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/ --incremental-dir=/data/inc1/2018-02-23_14-26-17

innobackupex --apply-log /data/2018-02-23_14-21-42/ --incremental-dir=/data/inc2/2018-02-23_14-28-29/

// 还原过程

// 不启动 mariadb

systemctl stop mariadb

rm -rf /var/lib/mysql/*

innobackupex --copy-back /data/2018-02-23_14-21-42/

chown -R mysql.mysql /var/lib/mysql/

systemctl start mariadb

5.3.6)实战案例:xtrabackup 单表导出和导入

// 导出

  1. 单表备份

innobackupex -uroot -pmagedu --include='hellodb.students' /backup

  1. 备份表结构

mysql -e 'show create table hellodb.students' > student.sql

  1. 删除表

mysql -e 'drop table hellodb.students'

// 导出

  1. innobackupex --apply-log --export /backups/2018-02-23_15-03-23/

  2. 创建表

mysql> CREATE TABLE `students` (

`StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,

`Name` varchar(50) NOT NULL,

`Age` tinyint(3) unsigned NOT NULL,

`Gender` enum('F','M') NOT NULL,

`ClassID` tinyint(3) unsigned DEFAULT NULL,

`TeacherID` int(10) unsigned DEFAULT NULL,

PRIMARY KEY (`StuID`)

) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8

  1. 删除表空间

alter table students discard tablespace;

  1. cp /backups/2018-02-23_15-03-23/hellodb/students.{cfg,exp,ibd} /var/lib/mysql/hellodb/

  2. chown -R mysql.mysql /var/lib/mysql/hellodb/

  3. mysql> alter table students import tablespace;

相关推荐
kaixin_learn_qt_ing1 小时前
解析Xml文件并修改QDomDocument的值
xml·数据库·qt
森林猿2 小时前
mongodb-数据备份和恢复
数据库·mongodb
oscube3 小时前
Apache AGE中的图
数据库·apache
科学的发展-只不过是读大自然写的代码3 小时前
qt播放视频
数据库·qt·音视频
激昂~逐流3 小时前
Qt使用sqlite数据库及项目实战
数据库·qt·sqlite·学生信息管理系统
svygh1234 小时前
数据库性能优化系统设计
数据库·性能优化·软件设计·系统设计·设计文档
wilsonzane4 小时前
Mongodb性能优化方法
数据库·mongodb
InterestingFigure5 小时前
Java 使用sql查询mongodb
java·开发语言·数据库·sql·mongodb
吹吹晚风-5 小时前
深入Django(三)
数据库·django·sqlite
xyh20045 小时前
python 10个自动化脚本
数据库·python·自动化