mysql8的备份还原/数据库灾备处理/逻辑备份/物理备份/全量备份/增量备份【mysqldump工具】【xtrabackup工具】

物理备份与逻辑备份

|--------|---------------------|-----------------------------------------------|
| 方式 | 逻辑备份 | 物理备份 |
| 内容 | 备份的是数据库的结构、数据 | 备份的是数据库文件 物理数据文件; 日志文件binlog二进制日志; 配置文件my.cnf |
| 工具 | 常用 mysqldump | 常用 xtrabackup |
| 特点 | 可读性强,跨平台,可用于部分恢复和迁移 | 备份速度快,恢复效率高 |
| 场景 | 适合中小型数据库 | 适合大规模数据库 |

逻辑备份备份的是一些命令,create啊insert into啊 所以可读性强

物理备份备份的是MySQL下面的一个data的文件,所以效率高

逻辑备份

完整灾备组合:mysqldump(逻辑全量基线) + binlog(逻辑增量变更流水)

表级的全量备份与还原

例子:现在库里有两个表

退出MySQL,对tb_student进行备份

格式是:mysqldump -u用户名 -p密码 库名 表名 > 路径/文件名.sql

复制代码
mysqldump -uroot -p123456 db_itheima tb_student > /root/tbstu.sql

进入mysql删除tb_student,现在只剩下一个表

还原备份,

格式:mysql -u用户名 -p密码 库名 < 存放备份的路径/备份文件

复制代码
mysql -uroot -p123456 db_itheima < /root/tbstu.sql

方法2,

格式:

use 空数据库

source /存放备份的路径/备份名.sql

指定库的全量备份与还原

例如:

现在有用户root 密码123456 数据库db_itheima,给数据库备份,备份放在root下

复制代码
mysqldump -uroot -p123456 --databases -F db_itheima > /root/db_itheima.sql

databases db_itheima:库级备份核心参数

  • 不加--databases:备份文件只有建表、插入数据语句,恢复前必须手动先创建库、use 库名
  • --databases:备份文件自带 CREATE DATABASE IF NOT EXISTS db_itheima; USE db_itheima;恢复时不用手动建库,直接导入自动创建数据库

-F 备份前刷新日志,主要是刷新二进制日志

还原

mysql -uroot -p'密码' < 后缀为.sql文件位置

复制代码
mysql -uroot -p123456 < /root/db_itheima.sql

方法2,进入MySQL用source导入

复制代码
source /root/db_itheima.sql;

这里不用手动新建库,执行 source /xxx/db_itheima.sql; 时,MySQL 会自动判断库是否存在,不存在就创建,存在就直接切换进去导入表数据。

全库的全量备份与还原

全库备份(-A 所有库一起导出)

用户root,密码123456,备份文件存放位置/root 备份文件名all_db_backup

复制代码
mysqldump -uroot -p123456 -A > /root/all_db_backup.sql

等价写法

复制代码
mysqldump -uroot -p --all-databases > all_db_backup.sql

搭配常用参数 --routines

复制代码
# 全库备份 + 包含存储过程/函数 + 定时推荐写法
mysqldump -uroot -p -A --routines --events > all_full.sql

恢复全库备份文件

复制代码
mysql -uroot -p123456 < all_db_backup.sql

方法2,

进入MySQL后source导入

复制代码
mysql -uroot -p123456
source /root/all_db_backup.sql

☆ mysqldump 高级选项说明

|-----------------------|--------------------------------------------------------------------|
| 选项 | 正确描述 |
| --flush-logs, -F | 备份前刷新日志,主要是刷新二进制日志,创建一个新的二进制日志文件 |
| --flush-privileges | 在备份文件中添加FLUSH PRIVILEGES语句(当备份包含mysql系统库时自动添加) |
| --lock-all-tables, -x | 对所有数据库的所有表加全局读锁,保证一致性但影响服务可用性 |
| --lock-tables, -l | 对当前备份的每个数据库的所有表分别加锁(不如--single-transaction常用) |
| --single-transaction | 对InnoDB表使用事务隔离,通过START TRANSACTION WITH CONSISTENT SNAPSHOT获取一致性视图 |

逻辑增量日志【binlog】

  • binlog:增量流水日志,不能单独恢复数据库,必须依赖一份 mysqldump 全量备份做基线,二者搭配才能恢复完整数据。
  • mysqldump:全量逻辑备份(单独导入就能恢复完整库)

mysqldump 只是某一刻的全量快照,只能恢复到备份那一刻的数据。举个例子:

  1. 凌晨 2 点执行 mysqldump 全量备份;
  2. 上午 10 点误删整张表;
  3. 只靠 dump 恢复,只能回到凌晨 2 点,2 点~10 点之间 6 小时的数据全部丢失。

开启 binlog 后:全量备份 + 备份之后的 binlog 日志,就能恢复到故障发生前任意一秒,把中间所有新增 / 修改数据补回来。完整恢复流程:

  1. 导入 mysqldump 全量基线;
  2. 回放对应时间段的 binlog,补全增量操作。

binlog小命令

查看binlog 文件的存储路径与文件名前缀

复制代码
show variables like 'log_bin_basename';
  • /export/software/mysql/data/:binlog 文件存放目录
  • binlog:日志文件前缀,真实生成文件为:binlog.000001binlog.000002binlog.index

看看binlog打开没有,打开显示on,没打开显示off

复制代码
show variables like 'log_bin';

查看正在写入的biglog文件,增量恢复的核心查询

复制代码
show master status;
  • binlog.000021:现在所有新增写操作都会写到这个文件
  • Position:当前文件内的写入偏移位点(字节位置)
  • 43094709:下一条 SQL 会写入这个字节位置,恢复时从这个位点之后取增量数据

故障恢复流程:

  • 第一步:导入 mysqldump 全量备份(还原到备份那一刻的数据)
  • 第二步:回放 binlog.000021,从位点 43094709 开始,把备份之后所有新增操作补回来

查看已生成的binlog文件

复制代码
show binary logs;

开启binlog

需要修改my.cnf文件在哪 我们找一下他的路径

MySQL 读取配置文件有固定优先级,按顺序扫描这几个位置:

  1. /etc/my.cnf
  2. /etc/mysql/my.cnf
  3. /usr/local/mysql/my.cnf
  4. ~/.my.cnf(当前用户家目录隐藏文件)

直接全盘找

复制代码
find / -name "my.cnf" 2>/dev/null
复制代码
vim /etc/my.cnf

在**[mysqld]**段添加 / 修改配置:

如果日志文件路径不存在需要手动创建,并且赋予MySQL所属用户所属组的权限

复制代码
# 开启二进制日志
log_bin = /export/software/mysql/data/binlog
# 日志文件名前缀,和你查到的basename保持一致
log_bin_basename = /export/software/mysql/data/binlog
# 可选:设置日志过期自动清理,避免磁盘占满
expire_logs_days = 7
# 生产推荐行模式binlog
binlog_format = ROW

重启

复制代码
# CentOS7/8
systemctl restart mysqld
# 或传统service
service mysqld restart

查看,输出ON即开启完成。

复制代码
show variables like 'log_bin';

增量备份

做完全量备份后,先记录当前位点,后续新增数据都从这个位点开始:

复制代码
show master status;

查看binlog日志

复制代码
 show binary logs;

恢复单个 binlog 文件

复制代码
mysqlbinlog --start-position=全量备份位点 /日志存放路径/binlog.000022 | mysql -uroot -p123456

有多个连续 binlog 文件(000022、000023)

复制代码
# 先恢复第一个增量日志
mysqlbinlog --start-position=23 /data/sqlbak/binlog.000022 | mysql -uroot -p123456
# 再恢复后续完整日志(不用加start-position,从头读到尾)
mysqlbinlog /data/sqlbak/binlog.000023 | mysql -uroot -p123456

全量备份+增量备份完整实操

我们预设每周1进行全量备份,234567进行增量备份,突然发生灾难时,恢复周一的全量备份,再回复周一后的一些数据,也就是周一到现在这几天的增量备份

全量备份

现在有数据库db_itheima,数据库中有两张表,其中一个叫tb_student的表长这样,

我们现在开始对,指定数据库,db_itheima库,进行全量备份

复制代码
mysqldump -uroot -p123456 --databases -F --routines db_itheima > /root/0624a.sql
  • -F:刷新 binlog(flush logs),全量备份完新开一个 binlog,方便后续增量恢复,这个是增量备份必带参数。
  • --databases:备份时自带 CREATE DATABASE + USE,恢复不用手动建库。
  • 专门备份存储过程、函数(procedure /function)

注意文件大小

记录当前的点位

复制代码
show master status;

也就是发生灾难的时候,binlog.000023以及,后面的都是我们需要回复的

模拟灾难

【周一到灾难这天中间新加入了数据】

现在有一条数据是我们之前进行的全量备份里没有的

再创建一个视图

复制代码
create view stu as select id,name,age,subject from tb_student;

这个视图也是全量备份里没有的

模拟【数据库丢失】

还原所有数据

还原全量备份

复制代码
source /root/0624a.sql;

还原增量备份

也就是,还原,我们之前的一个视图和小乔的数据

看一下binlog日志

复制代码
 show binary logs;

还记得我们前面在全量备份后查看的点位吗 23 也就是23和!之后的binglog日志全部都是我们需要的

执行增量恢复命令(mysqlbinlog)

先看一下bin_log存放路径

复制代码
show variables like 'log_bin%';
复制代码
mysqlbinlog -v /export/software/mysql/data/binlog.000023 | head -300

输出示例,圈错了,起始点位要begin后面的也就是317

我们记住想要恢复的数据的上下的at后面的数字

增量恢复

复制代码
mysqlbinlog --start-position=317 --stop-position=491 /export/software/mysql/data/binlog.000023 | mysql -uroot -p123456

视图那条不在这里 就找视图的上下文后面的at后面的数字 再执行一次这个命令

Xtrabackup 物理备份

Xtrabackup 是 Percona 开发的开源 MySQL 备份工具,主打高性能、低影响,能在不锁表的情况下,在线备份 InnoDB、XtraDB 等协议的数据库

**自学推荐的论坛:**https://opensource.actionsky.com/blog/

凌晨02:00开始备份,整个备份需要30分钟!

备份开始实际上只备份截止到02:00这段时间内的所有数据

**问题:**02:00 ~ 02:30这段时间,也可能会有增删改操作 => redo log重做日志中

**解决:**Xtrabackup不仅会备份截止到02:00这段时间内的所有数据,备份结束,其会把2:00-2:30这段时间的重写日志也执行一遍,写入到备份文件中。这样咱们得到的备份数据就是截止到02:30的所有内容。

  1. 工具:percona-xtrabackup-80
  2. 原理对应:
    • xtrabackup --backup:拷贝磁盘数据文件(2:00 快照),同步抓取备份期间 redo 日志
    • xtrabackup --prepare:回放包里的 redo 日志,把数据统一到备份结束时间点(原理图核心步骤)
  3. 环境:MySQL 默认数据目录 /var/lib/mysql

xtrabackup的下载安装

官方下载地址:www.percona.com/

复制代码
dnf install -y ./percona-xtrabackup-80-8.0.35-31.1.el9.x86_64.rpm

学习物理备份的操作前我们需要了解一下redo log(重做日志) 和 **binlog(二进制日志),**MySQL 中的两种核心日志系统,分别服务于不同的场景

☆ redo log vs binlog

binlog 的设计目的,是为了支持复制(Replication)、数据恢复(Recovery)和审计(Audit);binlog(二进制日志)是逻辑日志(记录 SQL 语句 / 行变更)

  • 复制:主库将 binlog 发送到从库,从库重放以同步数据;

  • 恢复:基于时间点或位置恢复数据(如误删表后,通过回放 binlog 恢复部分操作);

  • 审计:记录所有数据变更,可以用于做合规性检查;

redo log 是为了保障事务的持久性(Durability)和原子性(Atomicity)。redo log(重做日志)物理日志(记录 "磁盘哪一页改了、改成什么样")

  • 通过顺序写日志替代随机写数据页,减少磁盘I/O;

  • 确保事务提交后,即使数据库崩溃,未写入磁盘的数据也能通过redo log重做恢复;

所属维度

|------------|---------------------|------------------------|
| | redo log | binlog |
| 所属层级 | InnoDB 存储引擎层(其他引擎无) | MySQL 服务器层(与引擎无关) |
| 存储引擎依赖 | 仅 InnoDB 使用(核心机制) | 所有存储引擎的变更均记录(如 MyISAM) |
| 日志类型 | 物理日志(Physical Log) | 逻辑日志(Logical Log) |
| 格式 | InnoDB内部二进制格式,不可读 | mysqlbinlog工具解析 |
| 设计目的 | 事务保障,崩溃恢复 | 主从复制 |
| 常用关联工具 | Xtrbackup | mysqldump |

全量备份

本机正在运行的 MySQL 数据库做完整物理备份

  1. 连接对象:通过 -S /tmp/mysql.sock + bkuser 账号,连的是当前服务器本地的 MySQL 服务;
  2. 备份内容:MySQL 里所有库、表、索引、事务 redo 日志、表结构文件;
  3. 备份性质:热备份------ 不用停 MySQL,业务正常读写,不锁 InnoDB 表;
  4. 存放位置:你自己随便指定一个空目录(比如 /full_bak),所有备份文件全存在这里,和 MySQL 原数据目录完全分开。

简单说:把正在跑的 MySQL 整份数据,复制一份存到别的文件夹留作备用,防止删库、磁盘损坏丢数据

创建备份存放目录/full_alldata

复制代码
mkdir /full_alldata

创建一个备份账号

日常备份只需要少量固定权限(锁表、读取事务、备份管理),没必要动用最高权限:

  • 万一备份脚本泄露账号密码,黑客拿到 bkuser 只能做备份,无法删除业务数据

  • root 泄露会导致整个数据库被篡改、清空,风险极大

    -- 创建备份账号,允许本地登录,密码123456
    create user if not exists bkuser@localhost identified by '123456';

    -- 给xtrabackup必备备份权限
    grant backup_admin,reload,lock tables,process,replication client on . to bkuser@localhost;

    grant select on performance_schema.* to bkuser@localhost;
    grant select on mysql.* to bkuser@localhost;

    -- 刷新权限生效
    flush privileges;
    exit;

执行全量备份(核心命令)

复制代码
xtrabackup -S /tmp/mysql.sock --user=bkuser --password=123456 --backup --target-dir=/full_alldata
  • xtrabackup执行物理备份工具(你之前安装的 percona-xtrabackup-80)
  • -S /tmp/mysql.sock指定 MySQL 本地套接字文件,用来本地免端口连接数据库;你环境sock不在默认/var/lib/mysql/,不加这个参数会报连接失败。
  • --user=bkuser --password=123456使用专门创建的备份账号连接 MySQL,账号需要拥有备份相关权限。
  • --backup 【核心动作,对应原理图】开启备份模式,内部自动完成 2 件关键操作:
    • ① 拷贝磁盘上全部原始数据文件(原理图左侧:页 1 / 页 2 / 页 3 静态快照)
    • ② 拷贝文件的同时持续抓取备份期间新生成的 redo 日志(原理图右侧所有 LSN 变更记录)全程不阻塞 InnoDB 表的增删改,属于热备份。
  • --target-dir=/full_alldata指定备份文件存放目录,所有拷贝的数据、redo 日志、元数据都会存在这里。

备份完成校验

执行完后查看目录,能看到完整数据文件 + 备份期间 redo 日志:

复制代码
ls /full_alldata

所有文件就是一整套完整的 MySQL 物理副本,包含:

  1. 业务库文件夹(db_itheima 就是你上课测试的学生表库)
  2. InnoDB 核心文件 ibdata1、undo 回滚日志
  3. binlog 二进制日志
  4. redo 事务日志 xtrabackup_logfile
  5. 备份记录元文件

数据恢复

步骤 1:预备恢复(关键!回放 redo 日志,统一 LSN 版本)

复制代码
xtrabackup --prepare --target-dir=/full_alldata

步骤 2:停止 MySQL、清空旧库、还原数据文件

复制代码
#mv 迁移原有旧数据(替代 rm 删除,更安全)
mv /export/software/mysql/data /export/software/mysql/data001

#停止 MySQL 数据库服务,查看状态
systemctl stop mysqld
systemctl status mysqld


#把备份文件还原到 MySQL 数据目录
xtrabackup --copy-back --target-dir=/full_alldata

#修改数据文件的属主权限
chown -R mysql:mysql /export/software/mysql/data

systemctl start mysqld

还原的底层规则:

xtrabackup --copy-back 只会把备份里的文件复制到 MySQL 的 data 目录,它不会自动删除 data 里原来的旧文件。如果不清理旧数据,新旧文件混在一起,MySQL 启动时文件冲突、直接崩溃。