系列文章目录
MySQL存储过程和触发器_mysql 存储过程-CSDN博客
目录
[一、MySQL 日志](#一、MySQL 日志)
[1. 介绍](#1. 介绍)
[2. 作用](#2. 作用)
[3. 配置](#3. 配置)
[4. 磁盘文件](#4. 磁盘文件)
[5. 日志格式](#5. 日志格式)
[6. 刷盘策略](#6. 刷盘策略)
[7. mysqlbinlog 工具](#7. mysqlbinlog 工具)
[8. 远程备份 binlog 日志](#8. 远程备份 binlog 日志)
[1. 分类](#1. 分类)
[2. 备份方法一:Mysqldump 工具](#2. 备份方法一:Mysqldump 工具)
[3. Mysqldump 备份完整过程](#3. Mysqldump 备份完整过程)
[1. 备份之前,需收集信息,确保备份内容完整:](#1. 备份之前,需收集信息,确保备份内容完整:)
[2. 创建备份用户及授权:](#2. 创建备份用户及授权:)
[3. 创建备份目录](#3. 创建备份目录)
[4. 生产环境单库备份](#4. 生产环境单库备份)
[5. 完整实例备份](#5. 完整实例备份)
[6. 单表多表备份](#6. 单表多表备份)
[7. 按条件备份](#7. 按条件备份)
[8. 导出表结构](#8. 导出表结构)
[9. 只备份数据](#9. 只备份数据)
[10. 数据导入](#10. 数据导入)
[11. 监控恢复进度](#11. 监控恢复进度)
[4. 备份方法二:SQL 语句导出导入](#4. 备份方法二:SQL 语句导出导入)
[1. 查看允许导出的目录:](#1. 查看允许导出的目录:)
[2. sql 语句导入导出](#2. sql 语句导入导出)
[3. mysqlimport 导入](#3. mysqlimport 导入)
[5. 备份方法三:物理备份工具-Xtrabackup](#5. 备份方法三:物理备份工具-Xtrabackup)
[1. 软件安装](#1. 软件安装)
[2. 全量备份](#2. 全量备份)
[3. 增量备份](#3. 增量备份)
前言
本文系统介绍了MySQL日志系统与备份策略。主要内容包括:1) MySQL各类日志(二进制日志、错误日志等)的功能与配置;2) 二进制日志的格式、刷盘策略及恢复方法;3) 三种备份方法:mysqldump逻辑备份、SQL语句导出导入、XtraBackup物理备份;4) 详细说明全量/增量备份操作流程及恢复步骤。重点阐述了生产环境下的最佳实践,如推荐使用ROW格式二进制日志、sync_binlog=1刷盘策略等。文章为数据库管理员提供了全面的日志管理与备份恢复方案。
一、MySQL 日志
MySQL Server 有一下几种日志:
重做日志(Redo log):用于事务的提交和崩溃时恢复数据;事务中的数据落盘时,如果系统发生奔溃,会记录再重做日志中,服务器重启时,会检查重做日志,重新完成落盘;
回滚日志(Undo log):用于事务回滚;
错误日志(Error log):mysqld 在启动,运行或停止时遇到的问题,都会记录在错误日志中;
一般查询日志(General query log):已建立的客户端连接和冲客户收到的语句;
慢查询日志(slow query log):执行时间超过 long_query_time 指定秒数的查询;
二进制日志(Binary log):更改数据的语句(也用于主从复制);
中继日志(Relay log):从源服务器收到的数据更改;
二、二进制日志
1. 介绍
二进制日志是 mysql 中最重要的日志,日志以事件的形式记录了所有 DDL 和 DML 语句对数据的更改;
DDL:代表数据定义语言1,主要用于定义、修改或删除数据库的结构对象,如创建表、修改列或删除数据库3。典型命令包括 create,alter 和 drop;
DML:代表数据操作语言12,专门负责数据的增删改查操作,如插入记录、更新值或删除行3。常用命令有 insert,update,delete 和 select;
二进制日志还包括每个语句更新时花费的时间信息,启动二进制,对服务器性能稍微有些影响;
二进制日志不会记录 show 和 select 操作;
2. 作用
主从节点数据复制:从节点服务器读取主节点服务器上的二进制日志文件,并根据二进制日志中记录的事件在从节点上执行相同的操作,保证主从节点服务器上的数据一致,实现数据的复制功能;
数据恢复:重新执行记录在二进制日志中的事件,可以完成任一事务之前的数据恢复;
3. 配置
查看 binlog 相关的系统变量:
sql
-- 查看包含 log_bin 的系统配置
show variables like '%log_bin%';

log_bin:是否开启二进制日志;
log_bin_basename:二进制日志的基本文件名;
log_bin_index:二进制日志的索引文件名;
sql_log_bin:会话级别是否开启二进制日志;
在 linux 系统中,bin_log 相关的配置保存在 /etc/mysql/my.cnf 中:

bash
# mysql 的系统配置
[mysqld]
# 配置 mysql 自定义的二进制日志的基本文件名,可以是绝对路径(生产环境),也可以是相对路径(数据目录下)
log_bin = /var/lib/mysql/binlog
# 禁用二进制日志
skip-log-bin
# 或者
disable-log-bin
# 指定⼆进制⽇志的过期时间
binlog_expire_logs_seconds = 2592000
# 指定⼆进制⽇志格式为 ROW
binlog_format = ROW
# 二进制日志刷盘策略
sync_binlog = 1
# 修改 mysql 为允许远程连接
bind-address = 0.0.0.0
4. 磁盘文件
二进制日志文件名是由基本名+数字扩展名组成的,服务器每次创建一个新的日志文件时,数字扩展名都会增加,从而保证有序的文件序列;
发生以下事件时,服务器都会再创建一个新的日志文件:
- 服务器已启动或者重新启动;
- 服务器刷新日志;
- 当前日志文件的大小达到 max_binlog_size (单个日志文件的最大字节数,最小值 4096 字节,最大值和默认值 1 GB);
二进制日志记录事务,会完整的记录事务;
如果事务比较大,二进制日志也会完整记录,即使超过日志大小限制(1 GB),也会保证事务的完整性;
删除二进制日志文件:
sql
-- 删除指定日志文件之前的所有日志文件并更新索引
PURGE BINARY LOGS TO 'binlog.000010';
-- 删除指定时间之前的所有⽇志⽂件并更新索引
PURGE BINARY LOGS BEFORE '2024-10-02 22:56:26';
-- 重置⼆进⾏⽇志⽂件和索引⽂件为初始状态
reset master;
5. 日志格式
statement:基于 sql 语句记录日志;
row:基于表中受影响的行记录日志;
mixed:基于语句格式与行格式的混合模式记录日志;
生产环境中使用 row 格式,原因是一些函数比如 now(),uuid() 等函数产生的数据无法使用 statement 格式进行恢复;
6. 刷盘策略
二进制日志的刷盘策略可以通过 sync_binlog 系统变量设置:
sync_binlog = 0:mysql 不控制 binlog 的刷新,由系统控制刷新时机,性能最好,但是风险最大,如果系统发生奔溃,未来得及落盘的二进制日志就会丢失;
sync_binlog = 1:每次提交事务,mysql 刷新 binlog 完成落盘,最安全但性能损耗最高;实际的生产环境推荐使用这种策略;
sync_binlog = N:每提交 N 个事务刷新一次 binlog;
7. mysqlbinlog 工具
常用选项:
--base64-output:把 binlog 中的事件用 base-64 进行编码;
--database:之查看指定数据库的日志;
--no-defaults:不读取选项文件;由于 mysqld 中指定的字符编码集是 utf8mb4 格式,binlog 是二进制格式,因此需要使用这个选项,跳过选项文件的配置;
--offset, -o:跳过日志中的前 N 条记录;
--server-id:显示指定服务器 ID 创建的事件;
--start-datetime:从等于或者晚于 datatime 的第一个事件开始读取日志;
--stop-datatime:从等于或者晚于 datatime 的第一个事件结束;
--start-position:开始读取日志的位置;
--stop-position:停止解码的位置;
语法:
bash
# 查看日志
mysqlbinlog --no-defaults --database=testdb --base64-output=decode-rows -v binlog.000001 | less
mysqlbinlog --no-defaults --database=testdb --base64-output=decode-rows --start-position=1234 --stop-position=5678 -v binlog.000001 | less
通过二进制日志恢复数据:
bash
# 数据库恢复
# 方法一:找到恢复的起始位置,直接通过二进制日志进行恢复
mysqlbinlog --no-defaults --skip-gtids=true --start-position=721 --stop-position=5426 binlog.000001 | mysql -uroot -p -h127.0.0.1 -P3306
# 方法二:导出二进制日志到 sql 文件
mysqlbinlog --no-defaults --skip-gtids=true --start-position=721 --stop-position=5426 binlog.000001 > testdb.sql
# 在 mysql 客户端导入 .sql 文件
source /var/lib/mysql/testdb.sql
8. 远程备份 binlog 日志
在主服务器上创建账号:
sql
-- 远程备份 binlog 日志
-- 创建一个用于复制日志的用户
create user 'binloggrep'@'%' identified with mysql_native_password by '123456';
-- 为用户赋予复制权限
grant replication slave on *.* to 'binloggrep'@'%';
-- 刷新权限
flush privileges;
-- 测试登录
mysql -ubinloggrep -p123456
从服务器运行备份:
bash
# 从服务器运行备份
mysqlbinlog --read-from-remote-server --raw --host=49.233.162.74 --port=3306 --user=binloggrep --password=123456 --stop-never binlog.000001 --result-file=D:/BitCourse/code/mysql/logs/bak-
三、备份
1. 分类
逻辑备份:备份数据库的逻辑结构和数据,通常是导出数据库中的数据和对象来实现的,生成的是数据库可以识别的格式,如 sql 语句;
物理备份:直接复制数据库文件,包括数据文件和日志文件等;
冷备份:数据库完全关闭的情况下进行的备份;
热备份:在数据库运行正常的情况下备份,备份过程中数据库服务仍然可用;
温备份:数据库在运行过程中处于只读模式,可以查询数据,不能修改数据;
全量备份:备份数据库或文件系统的所有数据;
增量备份:备份自上次备份发生变化的数据;
差异备份:备份自上次全量备份以来所有变化的数据;
2. 备份方法一:Mysqldump 工具
mysqldump 客户端程序可以执行逻辑备份并生成一组 sql 语句;
应用场景:
- 数据库版本升级;
- 备份表结构或者小于 10GB 以下的数据库;
- 跨数据库类型迁移;
- 云平台之间的迁移;
常用选项:
--all-databases, -A:转储所有数据库中的所有表;
--databases, -B:转储指定数据库(可以写多个数据库),并转储所有表;
--events, -E:转出数据库中的事件;
--flush-logs, -F:在开始转储前刷新日志;
--no-data, -d:不转储表内容;
--routines:转储数据库的存储过程和函数;
--tables:转储指定表(可以多个表);
--trigger:转储每个表中的触发器;
bash
# 导出本地数据库中所有数据到磁盘
mysqldump -uroot -p -h127.0.0.1 -P3306 -B testdb > /backup/mysql/dump.sql
# 在命令行通过 mysql 客户工具直接恢复
mysql -uroot -p < /backup/mysql/dump.sql
# 也可以在数据库中恢复
source /backup/mysql/dump.sql
存在的问题:
在备份之前会对是所有表进行加锁,意味着在备份之前,正常产生的相关插入,删除,truncate 操作都处于锁等待状态,会对业务造成严重影响,不建议在生产环境中使用;
同时在备份过程中会产生数据不一致的问题:
- 数据已经发生改变,但是这些改变尚未提交,因此备份中可能包含未提交事务中的数据更改;
- 如果在备份期间发生了事务回滚,备份中可能已经包含了已经删除或者修改了的数据;
- 如果在备份期间有新的数据插入,那么这些数据可能不会被备份;
解决方法:
解决备份过程是数据不一致的方法是使用 --single-transaction 选项,确保在备份在事务内运行,保证备份期间的数据一致性;
事务的级别设置为可重复度,确定备份内的事务任何时候读取的数据都相同;
3. Mysqldump 备份完整过程
1. 备份之前,需收集信息,确保备份内容完整:
sql
-- 查看数据库的表信息
select
table_schema,
table_name,
table_collation,
ENGINE,
table_rows
FROM
information_schema.TABLES
WHERE
table_schema NOT IN ( 'information_schema', 'sys', 'mysql', 'performance_schema' );
-- 查看是否存在存储过程
select count(*) from information_schema.routines;
-- 查看是否存在触发器
select count(*) from information_schema.triggers;
-- 查看是否存在调度事件
select count(*) from information_schema.events;
-- 查看字符集
show variables like 'character%';
-- 查看数据库连接超时时间
show variables like 'wait_timeout%';
-- 查看交互式连接超时时间
show variables like 'interactive_timeout';
-- 查看数据包⼤⼩限制,,建议128M或256M,防⽌包过⼤⽽失败,默认64MB,最⼤1GB
show variables like 'max_allowed_packet';
-- 查看事务是否⾃动提交
show variables like 'autocommit';
2. 创建备份用户及授权:
sql
-- mysql 8.0
-- 创建备份用户
create user 'backup_user'@'localhost' identified with mysql_native_password by '123456';
-- 授权
grant BACKUP_ADMIN,PROCESS,SELECT,RELOAD, LOCK TABLES, REPLICATION CLIENT, EVENT on *.* to 'backup_user'@'localhost';
-- mysql 5.7
-- 创建备份用户
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY '123456';
-- 授权
grant reload,lock tables,replication client,create tablespace,process,super,select,event,trigger,show view on *.* to 'backup_user'@'localhost';
3. 创建备份目录
bash
mkdir -p /backup/mysql
4. 生产环境单库备份
bash
# 生产环境单库备份
mysqldump -ubackup_user -p -h127.0.0.1 -P3306 \
-B testdb --default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines \
--set-gtid-purged=off > /backup/mysql/`date +%Y%m%d`_0.sql
5. 完整实例备份
bash
sqldump -ubackup_user -p -h127.0.0.1 -P3306 \
--all-databases --default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines \
--set-gtid-purged=off --flush-logs > /backup/mysql/`date +%Y%m%d`_1.sql
--all-databases:备份所有数据库;
--flush-logs:备份完刷新日志,以便后面做增量备份;
不推荐使用备份所有数据库,有的版本存在 bug,可能会导致某些系统表无法使用;
6. 单表多表备份
bash
# 单表多表备份
mysqldump -ubackup_user -p -h127.0.0.1 -P3306 \
-B testdb --tables class student \
--default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines \
--set-gtid-purged=off > /backup/mysql/dump2.sql
7. 按条件备份
bash
# 按条件备份
mysqldump -ubackup_user -p -h127.0.0.1 -P3306 \
-B testdb --tables class student --default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines --set-gtid-purged=off \
--where='id<3' > /backup/mysql/dump3.sql
8. 导出表结构
bash
# 导出表结构
mysqldump -ubackup_user -p -h127.0.0.1 -P3306 \
-B testdb -d --default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines \
--set-gtid-purged=off > /backup/mysql/dump4.sql
--no-data, -d:不转储表内容;
9. 只备份数据
bash
# 导出数据
mysqldump -ubackup_user -p -h127.0.0.1 -P3306 \
--databases testdb --hex-blob --no-create-db --no-create-info \
--default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines \
--set-gtid-purged=off --flush-logs > /backup/mysql/dump5.sql
10. 数据导入
命令行导入:
bash
# 命令行导入
mysql -uroot -p < /backup/mysql/dump6.sql
交互式导入:
bash
登录 mysql 客户端导入 sql 文件
mysql -uroot -p
password:
mysql> source /backup/mysql/dump.sql
流式导入:
bash
# 流式导入
mysqldump -ubackup_user -p123456@BitBit -h127.0.0.1 -P3306 \
-B testdb --default-character-set=utf8mb4 \
--single-transaction --source-data=2 \
--triggers --events --routines \
--set-gtid-purged=off | mysql -uroot -p123456 -h192.168.100.237 -P3306
11. 监控恢复进度
bash
# 监控恢复进度
# Debian/Ubuntu 系统
sudo apt-get install pv
# Red Hat/CentOS 系统
sudo yum install pv
# 导⼊并查看进度
pv -L1000 /backup/mysql/dump6.sql | mysql -uroot -p123456 -h127.0.0.1 -P3306
4. 备份方法二:SQL 语句导出导入
MySQL 中可以通过 SQL 语句把查询出来的数据导出到服务器文件中,也可以从导出文件加载数据到指定的数据库和表,同时提供了一个导入工具,方便在命令行中完成导入操作;
1. 查看允许导出的目录:
sql
-- 查看全局只读参数 secure_file_priv 的值(允许导出的⽬录)
show variables like 'secure_file_priv';
应用场景:
- 简单的数据备份和数据迁移;
- 将数据导出到外部应用程序进一步处理;
2. sql 语句导入导出
sql
-- sql 语句备份
-- 导出
select * from db_name.tbl_name into outfile 'filename';
-- 导入
load data infile 'filename' into table tbl_name;
-- 导入导出时设置字段顺序
-- 导出
select 列名1, 列名2, ... from db_name.tbl_name into outfile 'filename';
-- 导入
load data infile 'filename' into table tbl_name(列名1, 列名2, ...);
3. mysqlimport 导入
bash
mysqlimport -uroot -p testdb /var/lib/mysql-files/student1.txt
注意:表名是跟导出的文件是通过名字匹配的;mysqlimport 会根据导入的文件名去匹配数据库中的表名;
5. 备份方法三:物理备份工具-Xtrabackup
Percona XtraBackup for MySQL - Top MySQL Backup Solution
应用场景:
- 大型数据库备份:可以节省存储空间和备份时间;
- 高可用环境:可以在不影响数据库服务的情况下进行在线热备份,适用于高可用环境的备份需求;
- 全量和增量备份:可以定期进行增量备份以节省存储空间和备份时间的场景;
- 全量和增量恢复:可以进行全量和增量恢复,甚至可以进行部分恢复和时间点恢复;
需根据 mysql 和 linux 版本确定 Xtrabackup 的版本;
1. 软件安装
bash
# 数据库物理备份工具
# 安装软件源
dpkg -i percona-xtrabackup-80_8.0.35-31-1.jammy_amd64.deb
# 更新源
apt update
# 如果提⽰缺少依赖运⾏以下命令安装
apt-get install -f
# 安装 xtrabackup
apt install percona-xtrabackup-80
# 更新源
apt update
# 安装 xtrabackup
apt install percona-xtrabackup-80
# 验证是否成功
xtrabackup --version
2. 全量备份
确保 /etc/msyql/my.cnf 已配置好:

bash
# 全量备份
xtrabackup --defaults-file=/etc/mysql/my.cnf \
--host=localhost --port=3306 --user=backup_user --password=123456 \
--use-memory=1G --parallel=2 \
--backup --target-dir=/backup/mysql/full
xtrabackup_binlog_info:记录备份时binlog⽇志和POS信息;
xtrabackup_checkpoints:备份类型和备份LSN信息,增量备份时依赖⽂件中的LSN;
xtrabackup_info:备份信息;
恢复:
bash
# 停止 mysql 服务
systemctl stop mysql
# 查看 mysql 服务是否停止
systemctl status mysql
# 数据目录改名
mv /var/lib/mysql /var/lib/mysql-old
# 创建空目录
mkdir -p /var/lib/mysql
# 准备
xtrabackup --prepare --target-dir=/backup/mysql/full
# 恢复数据
xtrabackup --defaults-file=/etc/mysql/my.cnf --copy-back --parallel=2 --target-dir=/backup/mysql/full
# 为恢复⽬录授权
chown -R mysql:mysql /var/lib/mysql
# 启动 MySQL 服务
systemctl start mysql
# 查看 MySQL 服务
systemctl status mysql
3. 增量备份
增量备份之前,需要进行一次全量备份,全量备份的过程同上;
bash
# 增量备份
# 为当前增量备份指定保存备份的⽬录,以及全量备份的⽬录
xtrabackup --host=localhost --port=3306 --user=backup_user --password=123456 --backup --target-dir=/backup/mysql/inc1 --incremental-basedir=/backup/mysql/full
# 为当前增量备份指定保存备份的⽬录,以及上⼀次增备的⽬录
xtrabackup --host=localhost --port=3306 --user=backup_user --password=123456 --backup --target-dir=/backup/mysql/inc2 --incremental-basedir=/backup/mysql/inc1
# 增量恢复
# 准备全量恢复
xtrabackup --prepare --apply-log-only --target-dir=/backup/mysql/full
# 准备第一次增量恢复
xtrabackup --prepare --apply-log-only --target-dir=/backup/mysql/full --incremental-dir=/backup/mysql/inc1
# 准备第二次增量恢复
xtrabackup --prepare --target-dir=/backup/mysql/full --incremental-dir=/backup/mysql/inc2
# 恢复数据
xtrabackup --copy-back --parallel=2 --target-dir=/backup/mysql/full
# 为恢复⽬录授权
chown -R mysql:mysql /var/lib/mysql
# 启动 MySQL 服务
systemctl start mysql
# 查看 MySQL 服务
systemctl status mysql