数据库学习案例20240426/一文读懂MySQL的BinLog写入机制

1 概述信息

binlog 写入机制

binlog 的写入逻辑并不复杂:事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中。

binlog cache

  binlog cache 在事务的运行期间暂存着binlog的数据,binlog cache 是在每个线程内空间独立的如果启用了bin log日志,MySQL 会为每个客户端分配一个二进制日志缓存。如果您经常使用大型事务,则可以增加此缓存大小以获得更好的性能,可通过  binlog_cache_size 配置其大小,默认 32768 bytes。

   如果binlog cache空间足够,在事务提交的时候,cache中的内容会被清空,同时这些数据会被写入到 binlog files 中;因为 bin log内容无论多大在事务提交时都需要一次性写入,所以当 bin log cache放不下的时候,就需要暂存到磁盘,然后提交被写入到 binlog files。

参数 binlog_cache_size:控制单个线程内 binlog cache 所占内存的大小

上面说的 写入到 bin log 中其实又拆为两部分:

write:首先会写入 page cache 中的 binlog files 中,page cache 就是一块内存。(不占用磁盘IOPS)

fsync:然后操作系统执行 fsync 时 bin log 才会从 page cache 中真正持久化到磁盘。(占用磁盘IOPS)

write 和 fsync 时机


关于write和fsync 的时机,是通过参数 sync_binlog 控制:

sync_binlog=0:表示每次提交事务只是 write,不执行 fsync,也就是binlog不做持久化。(不建议)

sync_binlog=1:表示每次提交事务都要发生 fsync。

sync_binlog=N:表示每次事务都会write,但是N次事务提交会执行fsync进行持久化。

通常来说,为了提高IOPS,会将这个参数设为100-1000。缺点是如果还没有执行fsync就宕机,最多会丢失最近N个事务的binlog日志。如果为了保证数据安全,就设为1。

官方文档描述如下:

如果 binlog 内容缺失怎么办


对于通过 redo log 可以恢复数据,我们都已经知道了,但是如果 binlog 内容缺失呢?

根据 sync_binlog 参数描述,如果设置为大于一,就代表N次事务才会将log持久化到磁盘中。而与此同时,redo log 的 innodb_flush_log_at_trx_commit 参数设置为1,表示每次事务提交都会执行 fsync。

如果对于Redo log有什么不懂,请移步前一篇文章。

这就产生了一种可能,如果发生mysql服务器了crash,此时redolog已经做持久化,但是binlog还有事务仍保存在page cache中,没有来得及执行fsync。宕机后重启服务,依赖redolog恢复数据,就会出现binlog 长度比真实数据所应该需要的长度短的情况。

面对数据完整但是binlog缺失,这种情况下会出现什么异样呢?开始我苦思不得其解,最终在MySQL5.7的官方文档中找到了答案。

官方文档描述如下:

If the MySQL server discovers at crash recovery that the binary log is shorter than it should have been, it lacks at least one successfully committed InnoDB transaction. This should not happen if sync_binlog=1 and the disk/file system do an actual sync when they are requested to (some do not), so the server prints an error message The binary log *file_name* is shorter than its expected size. In this case, this binary log is not correct and replication should be restarted from a fresh snapshot of the source's data.

如果 MySQL 服务器在崩溃恢复时发现二进制日志比应有的短,则它至少缺少一个成功提交的 InnoDB 事务。如果 sync_binlog=1 并且磁盘/文件系统在请求时进行实际同步(有些则没有),则不会发生这种情况,所以服务器打印一条错误消息日志。在这种情况下,此二进制日志不正确,应从源数据的新快照重新启动复制。

按照官方描述,如果将 sync_binlog设为1不会出现这种情况,如果出现了binlog比预期少,则会在服务器打印一条binlog日志的异常log:The binary log xxx is shorter than its expected size.

所以这种情况需要去人为干预处理,从最新的快照数据源重新复制。
 

如何使用Bin Log 恢复历史数据


binlog 会记录所有的逻辑操作,并且是采用“追加写”的形式,不会像redo log一样去覆盖日志文件。bin log 里面的数据是可靠的,一定是事务提交后的数据,这就全靠 redo log 两阶段提交来保证。

众所周知,我们可以通过 bin log 恢复任意时间点的数据,如何做到呢?

其实这是有前提的,我们必须要有定期备份全量数据的机制,比如半个月、每周、或者每天。

假定场景:比如今天中午12点有一次误删表数据,需要找回数据,如何做?

首先,找到最近的一次全量备份,比如昨天凌晨1点,那就从这个备份恢复到临时库;

然后,从备份的时间昨天凌晨1点开始,将备份的 binlog 依次取出来重放,直到今天中午12点的数据。

这样临时库就到达了误删数据之前的状态,然后可以把表数据从临时库取出来,按需求恢复到线上正式数据库。

应用从库的binlog到主库,用于恢复在备库执行的事务同步到主库。

mysqlbinlog binlog.000002|mysql -uroot -p -hlocalhost -P3306
———————————————          
原文链接:https://blog.csdn.net/sinat_32873711/article/details/129943145

                 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值