BinLog的基本原理与RedoLog的区别
BinLog基本概念
BinLog记录模式
总体上binlog有三种记录模式:
1.Row模式:binlog中记录每一行数据被修改的情况,在mysql中对相同数据做同样的修改。能够完全实现主从数据库的同步和恢复操作。缺点是大批量操作会产生大批量的操作日志 如:alter操作。二进制越来越多就会影响数据库的同步性能。
2.statement模式:binlog会记录修改语句的sql语句,mysql从库在复制sql语句的时候,会通过sql进程将binlog中的sql语句解析成和mysql主库上执行过的sql语句相同的sql语句,然后上从库上执行。优点在于产生少量的二进制文件,减少磁盘的io操作,提升数据存储和恢复的效率。缺点在于某些情况下导致主从数据库数据不一致,比如mysql主库中使用了last_insert_id()和now()这样的函数就会导致不一致。
3.mixed模式:row模式和statement模式混合,正常语句使用statement保存,last_insert_id()和now()使用raw。
Bin Log的文件结构
mysql的binlog文件中保存的是对数据库、数据表和数据表中数据的各项更新操作,用来表示修改操作的叫log event,不同的操作对应不同的log event,比较常用的log event有query event、row event、xid event,里面就是各种event的集合。
Bin Log的写入时机
Bin Log提交的时候,会记录事务日志和二进制日志。也就是redo log 和binlog,这里就存在一个问题,事务日志和二进制日志,MySQL先记录的是二进制日志。
Bin Log的写入规则:
1.触发event事件生成Log Event:主要是根据记录的模式,比如row、statement、mixed以及操作比如create、drop、alter、insert、update等触发event事件生成log event。也就是事件触发执行机制。
2.将事务执行过程中产生的日志事件(Log Event)写入相应的缓冲区:每个事务都有一个缓冲区,Log Event 保存在一个binlog_cache_mngr的数据结构中,这个数据结构有两个缓冲区,一个是stmt_cache用于不支持事务的信息,另一个是trx_cache用于存放支持事务的信息。
3.事务在提交阶段会将产生的日志事件(Log Event)写入磁盘的BinLog文件中:事务在提交阶段会将产生的日志事件写入磁盘的binlog文件中,不同的事务以穿行的方式将日志事件写入binlog文件中,所以一个事务中包含的log event信息在binlog文件中是连续的,中间不会插入其他事务的log event事件,一个事务的binlog是完整。
Bin Log组提交机制:
1.BinLog组提交机制:为了提高MySQL中日志刷盘效率,MySQL提供了组提交,group commit会调用fsync()函数将多个事务日志刷新到磁盘的日志文件中,而不是每次将每个事务的日志单独刷新到磁盘的日志文件。
在innodb存储引擎中,提交事务会进行两个阶段的操作:1.修改内存中事务对应的信息,并且会将日志写入相应的redo log buffer。2.调用fsync()函数将redo log buffer中的日志信息刷新到磁盘的redo log文件中。其中步骤2存在磁盘操作比较耗时,所以事务提交后,先将日志信息写入redo log buffer,最后调用fsync()函数将多个事务日志信息从内存的redo log buffer刷新到磁盘的redo log文件。为了保证binlog 和 事务日志的一致性,会在步骤1的prepare阶段会启用一个prepare_commit_mutex锁,这个时候会导致开启二进制后的group commit功能失效(5.6后,BLGC解决这个问题)。
BLGC
1.flush:将每个事务的binlog写入对应的内存缓冲区
2.sync:将内存缓冲区的binlog写入磁盘的binlog文件,如果存在多个事务,只执行一次刷盘
3.commit:leader事务根据队列中的事务顺序调用存储引擎层事务的提交,由于innodb存储引擎本身就支持group commit,所以解决了 prepare_commit_mutex锁导致的group commit失效的问题。
在flush阶段写入binlog到内存缓冲区时,不是写完就立即进入sync阶段,而是等待一定时间,多积累几个事务的binlog一起进入sync阶段,这个时间由binlog_max_flush_queue_time变量决定,默认值为0,除非由大量的事务不断写入和更新操作,否则不建议修改,不然会导致事务的响应速度变慢。当进入到sync阶段时,会将内存缓冲区多个事务的BinLog刷新到磁盘的BinLog文件中,和刷新一个事务的BinLog一样,都是由sync_binlog变量控制。如果一组事务正在执行commit阶段的操作时,其他新产生事务可以执行flush操作,commit阶段和flush阶段不会互相阻塞。这个时候group commit就会不断生效。group commit的性能与队列中的事务数量有关,如果队列只存在一个事务的话和单独提交一个事务差不多,甚至性能更差,提交的事务越多,group commit的性能就更明显。
1.BinLog是MySQL本身拥有的,与存储引擎无关。Redo Log是InnoDB存储引擎特有的,只有InnoDB才会输出BinLog
2.BinLog是逻辑日志记录的是对数据库的修改操作。Redo Log是物理格式的日志,记录的是每个数据页的修改。
3.Redo Log具有幂等性,多次操作的前后状态是一致的。BinLog不具有幂等性,记录的是所有影响数据库的操作。
4.BinLog开启事务时,会将每次提交的事务一次性写入内存缓冲区,如果未开启事务则每次成功执行语句时,就会写入到内存缓冲区,而RedoLog是在数据准备修改之前将数据写入缓冲区的Redo Log中,然后在缓冲区中修改数据,而且Redo Log是在提交事务时,先将Redo Log写入缓冲区,写完完成再提交事务。
5.BinLog只会在事务提交时,一次性写入BinLog,其日志的记录方式与事务的提交顺序有关,并且一个事务的BinLog中间不会插入其他事务的BinLog;而RedoLog记录的是物理页的修改,最后一个提交的事务记录会覆盖之前所有未提交的事务记录。并且一个事务的RedoLog中间会插入其他事务的RedoLog
6.BinLog是追加写入,写完一个日志文件就写下一个。Redo Log是循环写入。
7.BinLog主要作为主从复制和数据恢复,不具备自动崩溃和恢复的能力。RedoLog主要用于服务器发生故障后,事务已提交但未写入数据表的数据的自动恢复操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧