数据库日志管理、备份恢复与主从同步
01 数据库服务日志管理
1)数据库服务中有什么日志(4种)
-
第一种日志:通用日志
- 记录登录数据库的用户信息,登录用户操作行为会被记录
-
第二种日志:错误日志
- 记录数据库运行或启动过程的错误信息,便于排查数据库问题
-
第三种日志:二进制日志
- 记录数据库中的事务操作信息,可以用于恢复数据/可以用于主从同步
-
第四种日志:慢查询日志
- 记录在操作数据库过程中的慢查询语句
2)数据库日志信息如何管理
通用日志(默认不存在)
ini
# 配置文件设置
general_log=ON
general_log_file=/var/log/mysql/general.log
错误日志(默认存在-数据库数据目录-db-01.err)
ini
# 配置文件设置
log_error=0/off # 禁用错误日志
log_error=./xiaoQ-01.edu.err # 指定生成错误日志保存在哪
二进制日志(默认存在)
ini
# 配置文件设置
log_bin # 此配置项可以定义binlog日志是否开启
sql
-- 查看binlog是否开启
mysql> select @@log_bin;
ini
# 配置文件设置
sql_log_bin=1 # 此配置项可以定义binlog日志是否做事务记录
注意:做binlog日志数据恢复时,会临时将sql_log_bin功能关闭
二进制日志管理
1)如何查看二进制日志
方式一:在数据库中查看
sql
-- 获取数据库中所有binlog日志信息
show binary logs;
-- 获取数据库中正在使用的binlog日志信息
show master status;
输出示例:
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000023 | 157 | | | |
+---------------+----------+--------------+------------------+-------------------+
- Position:事务信息的位置点,便于过滤需要恢复的数据信息
- Binlog_Do_DB:指定哪些数据库的事务操作会被记录到binlog(二进制日志记录信息白名单)
- Binlog_Ignore_DB:指定哪些数据库的事务操作不会记录到binlog(二进制日志记录信息黑名单)
sql
-- 直接查看binlog日志内容
show binlog events in 'binlog日志名称';
知识补充:如何实现事务自动提交
- 利用autocommit配置项,可以实现事务信息自动提交
- 当完成事务过程中,出现了DDL或DCL语句,也会自动触发提交功能
方式二:在命令行查看二进制日志文件
bash
# 基本查看
mysqlbinlog binlog.000024
# 带参数查看
mysqlbinlog binlog.000024 \
--start-position=# \ # 从binlog日志中,根据位置点过滤指定事务信息(从哪过滤)
--stop-position=# \ # 从binlog日志中,根据位置点过滤指定事务信息(到哪结束)
--base64-output=decode-rows -vvv # 从binlog日志中,将DML编码语句进行解码,以明文方式显示DML语句
DML语句解码示例:
INSERT INTO `xiaoD`.`student` SET @1=1 @2='xiaoA';
INSERT INTO `xiaoD`.`student` value (1,'xiaoA');
注意:可以指定开始和结束的日志信息然后写入到一个文件中,然后导入mysql中,进行备份的恢复。
2)二进制日志记录格式(面试题)
二进制日志记录信息有三种格式:
-
SBR(语句格式记录)
- 会将DML操作事务信息,以语句明文方式记录
inibinlog_format=statement # 语句格式记录应用场景:对表操作过程中,没有函数信息应用,并且需要更直观查看DML事务信息
-
RBR(行格式记录)
- 会将DML操作事务信息,以具体数据行的信息记录
inibinlog_format=row # 行格式记录应用场景 :对表操作过程中,需要函数信息应用,并且有主从同步架构,为了保证数据一致性
示例:比如说时间函数now(),这种函数信息必须要用行格式记录。 -
MBR(混合方式记录)
- 会将DML操作事务信息,进行自动识别,根据识别后内容自动选择记录方式
3)二进制日志切割
方式一:手动执行命令进行切割
sql
-- 在数据库中执行
mysql> flush logs;
bash
# 在命令行执行
mysqladmin -uroot -p123456 flush-logs
方式二:根据文件大小进行切割(设置在配置文件当中)
ini
max_binlog_size = 字节量切割(默认1G)
4) 二进制日志清理
方式一:进行日志信息手工清理
sql
-- 清理到指定日志文件
mysql> purge binary logs to 'binlog.000027'
-- 清理指定时间之前的日志
mysql> PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
方式二:进行日志信息自动清理(根据时间)(都设置在配置文件当中)
ini
binlog_expire_logs_seconds = 3600 # 根据二进制日志存在了多少秒进行清理
expire_logs_days = 0 # 根据二进制日志存在了多少天进行清理
5) 二进制日志远程备份(实现日志信息统一管理)(kylin的机器)
说明:实现高可用会应用binlog日志远程备份功能
场景:主机数据库(10.0.0.51),别的数据库上进行备份
bash
# 创建备份目录
mkdir -p /binlog_backup/10.0.0.{51..55}
cd /binlog_backup/10.0.0.51
# 开始远程备份
mysqlbinlog -R \
--host=10.0.0.51 \
--user=root \
--password=123456 \
--raw \
--stop-never \
binlog.000008 &
参数说明:
-R:远程拉取目标主机日志信息--host:指定拉取日志主机地址--user:指定登录目标数据库服务器用户--password:指定登录目标数据库服务器用户密码--raw:实时拉取日志信息--stop-never:以守护进程方式一直拉取日志信息binlog.000008:从哪个日志开始拉取日志信息
注意:在带有mysql的客户端进行操作可以发现备份成功
知识扩展:利用binlog日志实现误操作数据的闪回功能
数据损坏类型:
- 物理损坏:硬件出现异常,数据库服务异常(主从架构,高可用架构)
- 逻辑损坏:出现数据信息误操作(DML)(数据闪回修复)
闪回工具使用步骤:
步骤一:下载数据闪回工具
- 访问:www.github.com
- 搜索:binlog2sql
- 下载:binlog2sql-master.zip,requirements.txt
步骤二:安装软件程序包
bash
# 查看文件
ll /opt/binlog2sql-master
# 安装Python3(可选)
yum install -y python3
# 安装依赖
pip3 install -r requirements.txt
步骤三:测试应用数据闪回工具
sql
-- 准备测试数据
use xiaoD;
create table t1 (id int, name char(10), age int);
insert into t1 values (1,'xiaoA',18),(2,'xiaoB',19),(3,'xiaoC',20);
步骤四:模拟误操作(在服务端db进行)
sql
-- 误插入数据
insert into t1 values (4,'xiaoD',18);
-- 误修改数据
update t1 set name='oldboy' where id=2;
-- 误删除数据
delete from t1 where id=3;
步骤五:进行数据闪回恢复(在客户端db进行查看)
bash
# 恢复误插入的数据
python3 binlog2sql.py \
-h10.0.0.117 \
-P3306 \
-uroot \
-p1 \
-d xiaoD \
-t t1 \
--sql-type=insert \
--start-file='binlog.000005' \
-B
输出结果:
DELETE FROM `xiaoD`.`t1` WHERE `id`=4 AND `name`='xiaoD' AND `age`=18;
说明 :insert into t1 values (4,'xiaoD',18); 的逆向操作信息是 delete from t1 where id=4 and name=xiaoD and age=18;

步骤六:执行逆向SQL恢复数据
sql
-- 在数据库中执行逆向SQL
DELETE FROM `xiaoD`.`t1` WHERE `id`=4 AND `name`='xiaoD' AND `age`=18;
同理恢复其他误操作:
bash
# 恢复误修改的数据
python3 binlog2sql.py \
-h10.0.0.51 \
-P3306 \
-uroot \
-p123456 \
-d xiaoD \
-t t1 \
--sql-type=update \
--start-file='binlog.000003' \
-B
# 输出:
# UPDATE `xiaoD`.`t1` SET `id`=2, `name`='xiaoB', `age`=19 WHERE `id`=2 AND `name`='oldbo' AND `age`=19;
# 恢复误删除的数据
python3 binlog2sql.py \
-h10.0.0.51 \
-P3306 \
-uroot \
-p123456 \
-d xiaoD \
-t t1 \
--sql-type=delete \
--start-file='binlog.000003' \
-B
# 输出:
# INSERT INTO `xiaoD`.`t1`(`id`, `name`, `age`) VALUES (3, 'xiaoC', 20);
总结:找出逆向操作的信息然后回数据库执行,即可返回误删除之前的数据
02 数据库服务备份恢复
方式一:逻辑备份与恢复
备份和恢复原理:
-
备份原理:读取数据库中数据对象以及表中数据信息,将数据对象创建过程和表中数据插入过程SQL语句导出
show databases→show create database 库名→ 创库语句use 库名→show tables→show create table 表名→ 创表语句- 识别表中数据信息 →
insert xxx
-
恢复原理:重新加载备份文件中SQL语句
应用场景:
- 只是适合于少量数据进行备份与恢复(50G)
- 可以将备份后的数据进行灵活恢复
备份实践过程:
bash
# mysqldump (-A -B)
备份方式一:实现数据库信息全备
bash
# 本地备份
mysqldump -u用户 -p密码 -S socket_file -A >/backup/all.sql
# 远程备份(异地备份)
mysqldump -u用户 -p密码 -h数据库服务器IP地址 -P数据库服务端口 -A >/backup/all.sql
注意:!!!别忘记了mysql服务端要创建相应的用户密码和配置权限
备份方式二:实现数据库分库备份
bash
mysqldump -uroot -p1 -B xiaoD > /backup/xiaoD.sql
参考:https://blog.csdn.net/weixin_64334766/article/details/145671441 -- 脚本实现
备份方式三:实现数据库分表备份
bash
mysqldump -uroot -p123456 xiaoD t1 >/backup/xiaoD_t1.sql
恢复数据过程:
恢复方式一:实现全备恢复数据
bash
mysql -uroot -pxxx </backup/all.sql
sql
-- 在数据库中执行
mysql> source /backup/all.sql
恢复方式二:实现恢复分库备份数据
bash
mysql -uroot -p123456 </backup/world.sql
恢复方式三:实现恢复分表备份数据
bash
mysql -uroot -pxxx 库名 </backup/xiaoD_t1.sql
sql
-- 在数据库中执行
mysql> use xiaoD
mysql> source /backup/xiaoD_t1.sql
方式二:物理备份与恢复
备份和恢复原理:
- 备份原理:将数据库数据目录中的所有信息做备份
- 恢复原理:将备份后的数据目录重新迁移到原有数据库数据目录中,重新启动数据库服务加载
备份实践过程:
bash
# 停止数据库服务
/etc/init.d/mysqld stop
# 备份数据目录
cp -a /data/3306/data/ /backup/data_2025_08_21
恢复实践过程:
bash
# 停止数据库服务
/etc/init.d/mysqld stop
# 清理数据目录
rm -rf /data/3306/data/*
# 恢复数据目录
cp -a /backup/data_2025_08_21/* /data/3306/data/
实现物理方式热备(xbk)(Centos 7.9 的一台机器下进行备份操作)
步骤一:安装下载备份工具
bash
# 访问下载地址
https://www.percona.com/downloads/
# 安装工具
yum localinstall -y percona-xtrabackup-80-8.0.32-26.1.el7.x86_64.rpm
步骤二:实现物理备份与恢复
方式一:物理全备与恢复(成功)
物理全备:
bash
# 创建保存物理数据的空目录
mkdir /data/backup/full -p
# 执行全备
xtrabackup \
--defaults-file=/etc/my.cnf \
--host=10.0.0.119 \
--user=root \
--password=1 \
--port=3306 \
--backup \
--no-server-version-check \
--target-dir=/data/backup/full
注意 :--target-dir=/data/backup/full指的是备份放在的目录
全备恢复:
bash
# 停止数据库服务
/etc/init.d/mysqld stop
# 清理数据目录
rm -rf /data/3306/data/*
# 恢复备份过程中的内存数据
xtrabackup --prepare --target-dir=/data/backup/full
# 恢复备份过程前的磁盘数据
xtrabackup --copy-back --target-dir=/data/backup/full
# 修改权限
chown -R mysql.mysql /data/3306/data
# 启动数据库服务
/etc/init.d/mysqld start
方式二:物理增量备份与恢复
增量备份过程:
bash
# 创建备份目录
mkdir /data/backup/week01 -p # 作为第一周全备数据存储目录
mkdir /data/backup/week02 -p # 作为第二周增量数据存储目录
mkdir /data/backup/week03 -p # 作为第三周增量数据存储目录
第一周全备:
bash
xtrabackup \
--defaults-file=/etc/my.cnf \
--host=10.0.0.119 \
--user=root \
--password=1 \
--port=3306 \
--backup \
--no-server-version-check \
--parallel=4 \
--target-dir=/data/backup/week01
第二周增量备份:
sql
-- 在数据库中创建测试数据
create database week02;
use week02;
create table t1(id int);
insert into t1 values(1),(2),(3);
commit;
bash
# 执行第二周增量备份
xtrabackup \
--defaults-file=/etc/my.cnf \
--host=10.0.0.119 \
--user=root \
--password=1 \
--port=3306 \
--backup \
--no-server-version-check \
--parallel=4 \
--target-dir=/data/backup/week02 \
--incremental-basedir=/data/backup/week01
注意 :--incremental-basedir 指定了本次增量备份所基于的上一个备份目录
第三周增量备份:
sql
-- 在数据库中创建测试数据
create database week03;
use week03;
create table t1(id int);
insert into t1 values(1),(2),(3);
commit;
bash
# 执行第三周增量备份
xtrabackup \
--defaults-file=/etc/my.cnf \
--host=10.0.0.119 \
--user=root \
--password=1 \
--port=3306 \
--backup \
--no-server-version-check \
--parallel=4 \
--target-dir=/data/backup/week03 \
--incremental-basedir=/data/backup/week02
增量恢复数据:
bash
# 模拟数据库数据损坏
/etc/init.d/mysqld stop
rm -rf /data/3306/data/*
# 全量数据目录中数据信息恢复到内存中的(不做恢复)
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/week01
# 第一次增量备份过程中需要恢复到内存中的数据也做加载
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/week01 --incremental-dir=/data/backup/week02
# 第二次增量备份过程中需要恢复到内存中的数据也做加载
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/week01 --incremental-dir=/data/backup/week03
# 将全量和增量备份过程中,需要恢复到内存的数据统一恢复到内存中
xtrabackup --prepare --target-dir=/data/backup/week01
注意 :--apply-log-only 取消undo日志文件加载过程。以上信息表示将内存信息做整合恢复。
bash
# 将磁盘信息做整合恢复
xtrabackup --datadir=/data/3306/data --copy-back --target-dir=/data/backup/week01
# 修改权限
chown -R mysql.mysql /data/3306/data
# 启动数据库服务
/etc/init.d/mysqld start
03 数据库服务主从同步(基础方式)
主从同步作用:
- 可以实现数据信息实时保存
- 可以实现数据库高可用架构
- 可以实现数据库读写分离功能(负载功能)
1)数据库主从同步原理
详细复述(画图说明/按照步骤解释说明)
- 需要在从库上进行主从功能配置(
change master to) - 当从库配置信息配置完毕后,会需要将配置信息进行保存,将内存保存到master_info文件中(
mysql.slave_master_info表) - 激活主从同步功能(
start slave) - 在从库中会出现两个线程(IO线程、SQL线程)
- IO线程 的出现会完成三个工作任务:
a. 读取master_info文件信息,根据文件内容向主库发起连接请求
b. 和主库建立连接会话,接收主库发送的binlog日志信息,并进行保存,保存到从库中继日志文件中(relay log)
c. 会随着不断接收binlog日志信息,去修改master_info文件位置点信息
- IO线程 的出现会完成三个工作任务:
- 主库接收从库IO线程连接请求,会在主库中创建binlog dump线程
- dump线程 的出现会完成两个工作任务:
a. 和从库建立维护会话
b. 监控binlog日志信息变化,并将变化binlog日志中事务信息进行发送给从库IO线程
- dump线程 的出现会完成两个工作任务:
- 在从库中应用SQL线程,完成主库数据信息同步
- SQL线程 的出现会完成两个工作任务:
a. 读取relay log文件中的事务信息,并将事务信息在从库中执行
b. 会将relay log中同步数据的位置点,记录到relay log info文件
- SQL线程 的出现会完成两个工作任务:
简述过程(主从同步过程中的3个线程和四个文件解释清楚)
3个线程:
- IO线程(出现在从库):可以实现和主库建立会话,可以保存binlog日志信息
- dump线程(出现在主库):可以实现和从库建立会话,可以将主库binlog日志信息发送给从库
- SQL线程(出现在从库):可以读取从库中继日志信息,将日志中的事务信息做回放
4个文件 :
主库中:
- binlog:记录主库事务操作信息(DDL DML DCL)
从库中:
- master info:记录主从配置信息
- relay log:同步保存主库发送过来的事务操作信息
- relay log info:记录relay log日志的回放位置点
2)主从同步实践过程(centos7.9环境,两台机器,一台主库,一台从库)
步骤一:准备两个数据库实例环境(省略)
步骤二:在主库中进行数据备份
sql
-- 创建复制用户
create user repl@'10.0.0.%' identified with mysql_native_password by '1';
grant replication slave on *.* to repl@'10.0.0.%';
-- 备份数据
mysqldump -uroot -p1 -A --single-transaction --source-data >/backup/all.sql
参数说明:
--single-transaction:在备份期间可以不影响数据库业务--source-data:在备份文件中记录备份后的binlog日志和位置点信息,便于主从同步
bash
# 传输备份文件到从库
scp -rp /backup/all.sql 10.0.0.203:/tmp/all.sql
步骤三:在从库中进行数据恢复
sql
-- 进入mysql执行恢复
mysql> source /tmp/all.sql;
步骤四:在从库中进行主从配置
sql
CHANGE MASTER TO
MASTER_HOST='10.0.0.119',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='1',
MASTER_LOG_FILE='binlog.000011', -- 查看 /tmp/all.sql 前几行就有
MASTER_LOG_POS=674, -- 查看 /tmp/all.sql 前几行就有
MASTER_CONNECT_RETRY=10;
步骤五:激活主从同步功能
sql
start slave;
补充:主从同步异常如何排查问题:
sql
-- 查看从库状态
show slave status\G
输出示例:
Slave_IO_Running: no
Slave_SQL_Running: Yes
问题:此时发现报错显示server_id和主库相同
解决方案:
sql
-- 停止复制
STOP SLAVE;
-- 修改 server_id(选择一个与主库不同的值)
SET GLOBAL server_id = 2; -- 确保与主库的 server_id 不同
-- 重新启动复制
START SLAVE;
bash
# 编辑从库的 MySQL 配置文件
vi /etc/my.cnf
# 在 [mysqld] section 中添加或修改
[mysqld]
server_id = 2 # 确保与主库不同
# 重启从库 MySQL
/etc/init.d/mysqld restart
sql
-- 重新配置复制
STOP SLAVE;
START SLAVE;
-- 检查复制状态
SHOW SLAVE STATUS\G
课程作业:
- 练习数据库备份操作(逻辑备份、物理备份)
- 练习数据库主从搭建
- 复述主从同步原理
- 练习主从备份分库分表备份脚本编写