全局认知:一张图记住整章
备份的三种粒度
| 粒度 | 含义 | 典型场景 |
|---|---|---|
| 表级 | 只备份某一张表 | 改表前临时保命、单表迁移 |
| 库级 | 备份整个数据库(含建库语句) | 单个业务库迁移 / 回滚 |
| 全库级 | 备份所有库(--all-databases) | 整机灾备,需先开启 binlog |
全量 vs 增量
| 类型 | 备份内容 | 速度 / 空间 | 恢复方式 |
|---|---|---|---|
| 全量 | 某一时刻的完整数据 | 慢、占用大 | 直接恢复 |
| 增量 | 上次备份以来的变化部分 | 快、占用小 | 先恢复全量,再依次应用增量 |
关键结论:mysqldump本身不能做增量。所谓 "mysqldump + binlog 增量",是拿全量快照打底,再用 binlog 回放快照之后的操作。增量能力来自 binlog,不是来自 mysqldump。
底层原理:为什么要懂存储引擎
备份方式不是随便选的,是由存储引擎决定的。不懂这层,后面所有命令都是死记。
MyISAM:一张表 = 一个 Excel 文件,表结构、数据、索引分开存成 3 个小文件。关掉数据库,直接复制文件粘贴到另一台 5.7 数据库,就能打开。
InnoDB:所有表都存在一个超大 Excel 工作簿里,每张表只是工作簿里的一个工作表,单独复制工作表拿出来,放到另一台电脑的 Excel 里打不开。
MySQL 三层结构(重点)
连接层 → SQL 层 →存储引擎层。备份打交道的就是最底下的存储引擎层,它决定"数据到底怎么存到磁盘上"。
磁盘上到底有哪些文件
MyISAM 的表
.sdi元数据(表结构、字段类型).MYI索引文件(INDEX).MYD数据文件(DATA)
5.7 及以前是.frm,没有 .sdi
create database db_ttttt default charset=utf8; use db_ttttt; create table tb_user1(id int, name char(1)) engine=myisam default charset=utf8;InnoDB 的表
.ibd每表独立,存该表数据和索引ibdata1共享表空间、数据字典redo log事务日志,保证崩溃可恢复
8.0 起 redo 在#innodb_redo/目录
user.ibd:单表的数据 + 索引文件(附属账本页)ibdata1:全局总账本(最重要!)里面记录:所有表的花名册。每一张.ibd文件都有一个唯一编号space_id,总账本里登记了这个编号属于哪张表。- redo 日志文件:相当于操作草稿。数据库修改数据先写草稿,万一断电,靠草稿恢复数据,保证不丢数据。
- undo 文件:回滚用,事务撤销、MVCC 版本控制
create database db_tinnodb default charset=utf8; use db_tinnodb; create table tb_userinnodb(id int, name char(1)) engine=innodb default charset=utf8;mysqldump 逻辑备份
mysqldump不是 SQL 语句,是操作系统命令行工具,在终端执行,不要进 mysql> 里敲。
三种基本语法
# 表级别备份 mysqldump [OPTIONS] database [tables] # 库级别备份(推荐,带建库语句) mysqldump [OPTIONS] --databases DB1 [DB2 DB3...] # 全库级别备份(必须先开启 binlog) mysqldump [OPTIONS] --all-databases [OPTIONS]关于密码的正确写法:mysqldump db_itheima tb_student > x.sql -p,实际操作中-p应该放在前面,且不要在 -p 后直接写密码(会被history记录、被ps看到)。推荐:-p后回车交互式输入。
命令速查
备份单表 mysqldump -uroot -p db_itttt tb_student > /tmp/sqlbak/tb_student.sql 备份单库 mysqldump -uroot -p --databases db_itttt > /tmp/sqlbak/db_itheima.sql 备份全库 mysqldump -uroot -p --all-databases --single-transaction --flush-logs --master-data > /tmp/sqlbak/all.sql 带存储过程 在上面基础上加 --routines 还原表/库 mysql -uroot -p db_itttt < /tmp/sqlbak/tb_student.sql 还原全库 mysql -uroot -p < /tmp/sqlbak/all.sql 登录内还原 mysql> use db_itttt; 然后 mysql> source /tmp/sqlbak/tb_student.sql; 不进终端执行 SQL mysql -uroot -p -e "show databases;"(-e 直接在命令行执行)四个参数高级选项(必考)
| 选项 | 作用 |
|---|---|
--single-transaction | InnoDB 专用。开启一个事务拿一致性快照,不锁表,业务不中断(热备)。这是最重要的一个 |
--flush-logs / -F | 备份前刷新日志,切换出新的 binlog 文件(binlog.000001 → 000002)。把"全量之后"的增量数据单独隔离到一个新文件里 |
--master-data | 把当前 binlog 文件名和位置点记入备份文件。值 1 会注释掉;值 2 不注释,主要给主从复制用 |
--lock-all-tables / -x | 锁全库全表,MyISAM 保证一致性用。业务会阻塞,能不用就不用 |
--routines | 一并备份存储过程和函数 |
为什么存储过程要单独备份?
mysqldump 默认只备份数据库和视图。视图本质是条 SELECT 语句,会跟着库一起走;但存储过程不会自动包含,必须显式加--routines。运维自己用得少,但开发大量使用,漏了就出事。
只备份存储过程:mysqldump --routines --no-create-info --no-data --databases db_itheima > backup.sql -p
--routines:包括存储过程和存储函数
--no-create-info:不备份表结构
--no-data:不备份表中的数据
--all-databases:备份所有数据库(如果只备份某个数据库,改成 --databases dbname)
备份的视图
mysqldump + binlog 增量备份
生产节奏:周日做一次全量,周一到周六做增量。增量部分实际就是把新产生的 binlog 文件拷走。
binlog 是什么
二进制日志,记录所有对数据库的增、删、改操作(不记录 SELECT)。MySQL 8.0 起默认开启。它既是增量备份的数据源,也是主从复制的通道
开启 binlog(/etc/my.cnf)
[mysqld] server-id=10 log-bin=/export/server/mysql/data/binlog log_error=/export/server/mysql/logs/error.log binlog_format=statement # 让日志里能直观看到 SQL 语句 # logs 目录要提前建好,且属主必须是 mysql mkdir /export/server/mysql/logs chown -R mysql.mysql /export/server/mysql systemctl restart mysqld完整演练六步
准备数据:建库建表插几条记录(刘备、关羽、张飞、貂蝉、大乔)
mysql> drop database db_tttt; mysql> create database db_tttt default charset=utf8; mysql> use db_itheima; mysql> create table tb_student( id int not null auto_increment, name varchar(20), age tinyint unsigned default 0, gender enum('male','female'), subject enum('ui', 'java', 'yunwei', 'bigdata'), primary key(id) ) engine=innodb default charset=utf8; mysql> insert into tb_student values (null,'刘备',33,'male','bigdata'); mysql> insert into tb_student values (null,'关羽',32,'male','yunwei'); mysql> insert into tb_student values (null,'张飞',30,'male','yunwei'); mysql> insert into tb_student values (null,'貂蝉',18,'female','ui'); mysql> insert into tb_student values (null,'大乔',18,'female','ui')开 binlog + 全量备份:
mysqldump --routines --single-transaction --flush-logs --master-data --all-databases > /tmp/sqlbak/all.sql -p
备份后务必确认最新的 binlog 文件名(如 binlog.000013),--flush-logs 会切出新文件继续增删改:插入"小乔",删除 id=3(张飞)——这些数据还没备份,只存在于 binlog 里
模拟故障:
mysql -e "drop database db_itheima;" -p抢先备份 binlog:
cp /export/server/mysql/data/binlog.000013 /tmp/sqlbak/
这一步要快,MySQL 还在跑就可能继续写日志先恢复全量,再回放 binlog(见下方命令)
# 1. 先恢复全量(只回到备份那一刻) mysql -uroot -p < /tmp/sqlbak/all.sql # 2. 先看看 binlog 里发生了什么,找到"事故临界点"的 at 位置 mysqlbinlog /tmp/sqlbak/binlog.000013 | less # 3. 按位置回放增量(--start-position 到 --stop-position) mysqlbinlog --start-position=157 --stop-position=952 /tmp/sqlbak/binlog.000013 | mysql -uroot -p # 4. 也可以按时间点回放 mysqlbinlog --start-datetime="2025-04-28 17:57:11" --stop-datetime="2025-04-28 17:58:35" \ /tmp/sqlbak/binlog.000013 | mysql -uroot -p为什么能防"删库跑路":mysqlbinlog | less先翻一遍,找到那条drop database的位置(比如 at 952),回放时把终点停在它前面,误操作就被跳过了。这就是按位置恢复的意义——不是无脑回放全部。
全库还原的限制
全库还原只能恢复业务数据,恢复不了 mysql 系统库。千万不要删 mysql、sys、performance_schema 这些系统库,删了备份救不回来。
xtrabackup 物理备份
区别:物理备份比较适合超大型数据库备份操作,逻辑备份就是把数据导出成一个.sql文件,物理备份直接针对物理文件、binlog二进制日志、/etc/my.cnf也会进行备份
官方下载地址:www.percona.com/
yum install percona-xtrabackup-80-8.0.35-31.1.el9.x86_64.rpm -y需要的权限:
# 创建专用备份用户并授权 mysql> create user 'admin'@'localhost' identified with mysql_native_password by '123'; mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'admin'@'localhost'; mysql> GRANT SELECT ON performance_schema.log_status TO 'admin'@'localhost'; mysql> GRANT SELECT ON performance_schema.replication_group_members TO 'admin'@'localhost'; mysql> GRANT SELECT ON performance_schema.keyring_component_status TO 'admin'@'localhost'; mysql> flush privileges;xtrabackup(Percona XtraBackup)是物理热备工具,备份的时候不能停库、不能锁全表(InnoDB 引擎),它需要:读 redo log、读 ibd 文件、拷贝数据文件、获取 binlog 位点、锁表(MyISAM)、拿集群状态。 所以这个admin用户不是业务账号,专门给 xtrabackup 跑备份用的备份账号,下面一条一条拆开讲,大白话讲清楚:为什么 xtrabackup 非要这个权限,缺了会怎么样。
1.GRANT BACKUP_ADMIN ON *.* TO 'admin'@'localhost';
✅BACKUP_ADMIN:MySQL8 专门给备份工具新增的权限MySQL 8.0 之前没有这个权限,8.0 把备份相关能力收拢到这个权限里。 作用:
- 允许执行
LOCK INSTANCE FOR BACKUP(实例备份锁)
这个锁和
FLUSH TABLES WITH READ LOCK不一样:它不会阻塞 InnoDB DML,只会阻塞 DDL(建表、改表、删表)
- xtrabackup 在备份开始阶段会加这个锁,拿到全局一致性位点,防止备份过程有人改表结构导致备份包损坏
- 还允许读取一些内部备份元数据、控制 redo log 归档 ❌ 缺了这个:xtrabackup 直接报错,无法获取实例备份锁,8.0 下备份大概率失败。
重点区分: FTWRL(FLUSH TABLES WITH READ LOCK)会锁所有表,写全部卡住;
LOCK INSTANCE FOR BACKUP只拦 DDL,业务读写基本不受影响,这是 MySQL8 热备优化。
2.GRANT PROCESS ON *.* TO 'admin'@'localhost';
✅PROCESS:查看所有正在运行的线程、进程信息作用: xtrabackup 需要拿到 MySQL 内部线程状态、事务信息,查看当前有没有长事务、后台线程。 xtrabackup 底层会通过SHOW PROCESSLIST/information_schema.threads采集信息。 ❌ 缺了:看不到完整线程列表,部分版本 xtrabackup 警告,极端场景下一致性判断异常。
注意:PROCESS 不能杀线程,只是看,没有危险。
3.GRANT RELOAD ON *.* TO 'admin'@'localhost';
✅RELOAD:刷新权限、刷新表、刷新日志(FLUSH 系列命令)作用: xtrabackup 里面会用到FLUSH LOGS(切换 binlog),用来拿到一个干净的 binlog 起点,记录备份对应的 binlog 文件名 + position,后续做 binlog 增量恢复需要这个位点。
增量备份、基于备份做时间点恢复(PITR)高度依赖这个。 ❌ 缺了:不能刷日志,拿不到准确 binlog 位点,备份包里面的 binlog 信息为空,恢复的时候没法接续 binlog。
4.GRANT LOCK TABLES ON *.* TO 'admin'@'localhost';
✅LOCK TABLES:手动锁表权限
划重点:只针对 MyISAM、MEMORY 这类非事务引擎InnoDB 是事务引擎,xtrabackup 靠 redo log 实现热备,不需要锁 InnoDB 表; 但是库里面如果混有 MyISAM 表,MyISAM 没有 redo log,xtrabackup 只能
LOCK TABLES ... READ把它锁住再拷贝,保证数据一致。 ❌ 缺了:如果库里面存在 MyISAM 表,备份到 MyISAM 的时候直接报错;纯 InnoDB 环境,这个权限暂时可以不用,但生产环境谁也不敢保证完全没有 MyISAM,所以标准模板都会带上。
5.GRANT REPLICATION CLIENT ON *.* TO 'admin'@'localhost';
✅REPLICATION CLIENT:允许查询主从复制相关信息作用: 允许执行SHOW MASTER STATUS、SHOW BINARY LOGS,拿到 binlog 文件和位点。 xtrabackup 备份结束后,会把这个位点写入xtrabackup_binlog_info文件。
这个文件是备份包里面最核心文件之一:后续搭建从库、PITR 恢复全靠它。 ❌ 缺了:拿不到 binlog 位点,
xtrabackup_binlog_info无内容,备份包只能单独恢复,不能做主从搭建、不能做时间点恢复。
下面三个是单独给 performance_schema 的 SELECT,属于 MySQL8.0 / InnoDB Cluster(组复制)配套权限
如果你不是组复制(InnoDB Cluster)环境,这三条其实可以删掉,很多单实例、普通主从备份脚本是不带这三条的。 xtrabackup 8.0 增加了对 MGR(MySQL 组复制)的支持,所以需要读取这几张监控表:
6.GRANT SELECT ON performance_schema.log_status TO 'admin'@'localhost';
performance_schema.log_status:这张表汇总了当前实例的 redo、binlog、gtid、备份状态的统一快照。 MGR 环境下,xtrabackup 优先读这张表获取一致性状态信息,替代传统show master status。 ❌ MGR 环境缺这个:备份无法正确获取 GTID 和日志状态;普通主从 / 单实例,有没有无所谓。
7.GRANT SELECT ON performance_schema.replication_group_members TO 'admin'@'localhost';
replication_group_members:MGR 组复制成员列表,记录集群里有哪些节点、每个节点状态(ONLINE、OFFLINE)。 xtrabackup 在 MGR 节点备份时,会检查当前节点状态,确保不在异常节点上备份,避免拿到不一致的数据。 ❌ 非 MGR 环境:这张表是空的,权限给了也没用。
8.GRANT SELECT ON performance_schema.keyring_component_status TO 'admin'@'localhost';
keyring_component_status:密钥环组件状态。 MySQL 支持透明数据加密 TDE(InnoDB 表加密),TDE 靠 keyring 管理密钥。 xtrabackup 备份加密表的时候,要读取 keyring 状态,确认密钥组件正常,备份的时候才能正确处理加密 ibd 文件。 ❌ 没有开启 TDE 加密:这张表信息无关紧要,权限可以不给。
9.flush privileges;
不是授权,是让权限立即生效MySQL 权限加载机制:权限存在 mysql 系统表,flush privileges 会重新加载权限表,不用重启 MySQL 账号权限立刻生效。
| 权限 | 核心用途 | 什么时候必须要 |
|---|---|---|
| BACKUP_ADMIN | 执行 LOCK INSTANCE FOR BACKUP,8.0 备份核心 | MySQL8.0 + xtrabackup8.0,必选 |
| PROCESS | 查看 MySQL 线程事务状态 | 推荐带上 |
| RELOAD | FLUSH LOGS,切换 binlog 拿位点 | 需要 PITR、搭建从库,必选 |
| LOCK TABLES | 锁 MyISAM 等非事务引擎表 | 库存在 MyISAM 则必选 |
| REPLICATION CLIENT | SHOW MASTER STATUS 获取 binlog 位点 | 需要 PITR、搭建从库,必选 |
| performance_schema.log_status | MGR 环境获取日志快照 | 仅 MGR 组复制 |
| performance_schema.replication_group_members | MGR 检查集群节点状态 | 仅 MGR 组复制 |
| performance_schema.keyring_component_status | TDE 加密表备份校验密钥环 | 仅开启 TDE 加密 |
全量备份与恢复(六步)
备份:
xtrabackup -S /tmp/mysql.sock --user=admin --password=123 --backup --target-dir=/full_xtrabackup
默认会去找 /var/lib/mysql/mysql.sock,找不到就报错。用-S显式指定套接字(推荐),或建软链接(不推荐)预备(prepare):
xtrabackup --user=admin --password=123 --prepare --target-dir=/full_xtrabackup
把备份期间产生的 redo log 整合进备份,让它变成"可直接用"的状态模拟故障:
rm -rf /export/server/mysql/data+systemctl stop mysqld(不行就pkill mysqld)恢复:
xtrabackup --defaults-file=/etc/my.cnf --copy-back --target-dir=/full_xtrabackup
不加--defaults-file会报datadir must be specified——它要靠 my.cnf 找到数据目录改权限:
chown -R mysql.mysql /export/server/mysql/data
不改的话 mysqld 起不来,这是新手最高频的坑启动验证:
systemctl start mysqld然后查数据
LSN(Log Sequence Number)可以看作每个数据页的版本戳。全量备份会记下当时的to_lsn;做增量时,xtrabackup 只拷贝 LSN 大于这个值的页