面试必问 | 聊聊MySQL三大核心日志的实现原理?(二)

Pike_Chen
发布于 2022-5-30 17:35
浏览
0收藏

 

Binlog日志

什么是Binlog
Binlog记录所有MySQL数据库表结构变更以及表数据修改的二进制日志,不会记录select和show这类查询操作的日志。Binlog日志是以事件形式记录,还包含语句所执行的消耗时间。开启Binlog日志有以下两个最重要的使用场景。

  • 主从复制:在主库中开启Binlog功能,这样主库就可以把Binlog传递给从库,从库拿到Binlog后实现数据恢复达到主从数据一致性。
  • 数据恢复:通过mysqlbinlog等工具来恢复数据
    关于Binlog的使用场景可以参见冰河出版的《深入理解分布式事务:原理与实战》与《MySQL技术大全:开发、优化和运维实战》一书。

Binlog文件记录模式
Binlog文件记录模式有STATEMENT、ROW和MIXED三种,具体含义如下。

ROW模式

ROW(row-based replication, RBR):日志中会记录每一行数据被修改的情况,然后在slave端对相同的数据进行修改。

优点:能清楚记录每一个行数据的修改细节,能完全实现主从数据同步和数据的恢复。

缺点:批量操作,会产生大量的日志,尤其是alter table会让日志暴涨。

STATMENT模式

STATMENT(statement-based replication, SBR):每一条被修改数据的SQL都会记录到master的Binlog中,slave在复制的时候SQL进程会解析成和原来master端执行过的相同的SQL再次执行。简称SQL语句复制。

优点:日志量小,减少磁盘IO,提升存储和恢复速度

缺点:在某些情况下会导致主从数据不一致,比如last_insert_id()、now()等函数。

MIXED模式

MIXED(mixed-based replication, MBR):以上两种模式的混合使用,一般会使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择写入模式 。

Binlog文件结构
对于MySQL的Binlog文件结构有三种版本,见下图。

 面试必问 | 聊聊MySQL三大核心日志的实现原理?(二)-鸿蒙开发者社区面试必问 | 聊聊MySQL三大核心日志的实现原理?(二)-鸿蒙开发者社区面试必问 | 聊聊MySQL三大核心日志的实现原理?(二)-鸿蒙开发者社区
关于Binlog文件结构的具体信息,小伙伴们可以参考MySQL的官方文档,具体链接为:https://dev.mysql.com/doc/internals/en/event-header-fields.html

Binlog写机制
根据记录模式和操作触发event事件生成log event(事件触发执行机制)。

将事务执行过程中产生的日志时间(log event)写入缓冲区,每个事务线程都有一个缓冲区。Log Event保存在一个binlog_cache_mngr数据结构中,在该结构中有两个缓冲区,一个是stmt_cache,用于存放不支持事务的信息;另一个是trx_cache,用于存放支持事务的信息。

事务在提交阶段会将产生的log event写入到外部binlog文件中。不同事务以串行方式将log event写入Binlog文件中,所以一个事务包含的log event信息在binlog文件中是连续的,中间不会插入其他事务的log event。

Binlog文件操作
Binlog状态查看

show variables like 'log_bin';

开启Binlog功能,需要修改my.cnf或my.ini配置文件,在[mysqld]下面增加log_bin=mysql_bin_log,重启 MySQL服务。

binlog-format=ROW
log-bin=mysqlbinlog

使用show binlog events命令

show binary logs; //等价于show master logs;
show master status;
show binlog events;
show binlog events in 'mysqlbinlog.000001';

使用mysqlbinlog 命令

mysqlbinlog "文件名"
mysqlbinlog "文件名" > "test.sql"

使用 binlog 恢复数据

//按指定时间恢复
mysqlbinlog --start-datetime="2021-02-28 18:00:00" --stopdatetime="2021-03-01 00:00:00" mysqlbinlog.000001 | mysql -uroot -p123456
//按事件位置号恢复
mysqlbinlog --start-position=1789 --stop-position=2674 mysqlbinlog.000001
| mysql -uroot -p123456

删除Binlog文件

purge binary logs to 'mysqlbinlog.000001'; //删除指定文件
purge binary logs before '2021-03-01 00:00:00'; //删除指定时间之前的文件
reset master; //清除所有文件

可以通过设置expire_logs_days参数来启动自动清理功能。默认值为0表示没启用。设置为大于0的整数表示超出多少天binlog文件会自动清除。

更多有关于Binlog日志的信息,可以参考冰河出版的《深入理解分布式事务:原理与实战》与《MySQL技术大全:开发、优化与运维实战》一书。

好了,今天就到这儿吧,我是冰河,我们下期见~~

 

文章转自公众号:冰河技术

分类
标签
已于2022-5-30 17:35:44修改
收藏
回复
举报
回复
    相关推荐