前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mysql日志redo log和binlog

Mysql日志redo log和binlog

作者头像
小土豆Yuki
发布2020-12-02 11:18:50
8370
发布2020-12-02 11:18:50
举报
文章被收录于专栏:洁癖是一只狗

binglog的写入机制

binglog的写入逻辑比较简单,事物执行过程中,先把日志写入到binglog cache,在事物提交的时候,再把binglog cache写到binlog文件中.

一个事物的binlog是不能拆开的,因为不论这个事务多大,也要确保一次性写入,这就涉及到了binLog cache的保存问题

系统会给binlog cache开辟一片内存,每一个线程一个,用binlog_cache_size控制内存的大小,如果超过这个参数的大小,就要暂存到磁盘

事务提交的时候,执行器要把完整的事物写入到binlog中,并清空binlog cache,状态如下

可以看到,每个线程有自己binlog cache,但是共用同一份binlog文件

  • 图中write就是把日志写入到文件系统的page cache,并没有把数据持久化到磁盘,所以速度比较快
  • 图中fsync就是把数据持久化到磁盘的操作,我们认为fsync才占磁盘的IOPS

write和fsysnc的实际有参数sync_binlog控制

  1. sync_binglog=0的时候,表示每次事物提交都只write,不fsync
  2. sync_binlog=1的时候,表示每次事物提交都会执行fsync
  3. sync_binlog=N的时候,表示每次提交事物都write,d但累计N个事物后才fsync

因此在出现IO瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提高性能,在实际业务场景中,并不建议设置这个值为0,比较常见设置为100-1000中一个值

但是如果主机发生异常重启,而sysn_binlog=N,会导致最近的N个事物丢失

redo log写入机制

事物执行过程中,生成的redo log会先写到redo log buffer,并且不会生成后直接持久化到磁盘,但是如果事物执行期间数据库重启,这份数据就会丢失,因为事物并没有提交,所以不会有什么损失,

事物在没有提交的时候,redo log buffer 中的部分日志也是会持久化到磁盘的

上面就是对应的redo log 的三种状态

  1. 红色部分就是mysql的进程内存,存在redo log buffer中
  2. 黄色部分就是写到磁盘但是没有持久化,是物理上是文件系统的page cache
  3. 绿色部分就是持久化到磁盘

日志写到redo log buffer是很快的,write到page cache也是差不多的,但是持久化磁盘就慢多了

redo log写入策略,是按照参数innodb_flush_log_at_trx_commit参数控制的,有三种可能性

  1. 等于0,表示每次事物提交时都只是把redo log留在redo log buffer中
  2. 等于1,表示每次事物提交时都将redo log直接持久化到磁盘
  3. 等于2,表示每次事物提交时只是把redo log写到page cache

在innodb后台线程每隔1秒,都会把redo log buffer中的日志,调用write写到文件系统的page cache,然后调用fsync持久化到磁盘.还有两种场景会把一个没有提交的事物持久化到磁盘

  1. 当redo log buffer占用空间即将达到innodb_log_size一半的时候,后台线程就会主动写盘,因为这个事物并没有提交,因此这个写盘只是write,并没有使用fsync,也就保留在page cache
  2. 并行的事物提交,顺带把这个事务的redo log buffer持久化磁盘,假设一个事物A执行到一半,已经写了一些redo log到buffer,另外一个事物提交,如果innodb_flush_at_trx_commit=1,则持久化redo log buffer里面的所有日志到磁盘,这个时候,事物A的redo log buffer里面的事务一起持久化到磁盘

如果把innodb_flush_log_at_trx_commit=1,那么redo log在prepare阶段就要持久化一次,因为有一个崩溃恢复逻辑是要依赖于prepare的redo log,在加上binlog来恢复的.

每秒一次后台轮询刷盘,加上崩溃恢复这个逻辑,innodb就会认为redo log在commit的时候就不需要fsync,只会write到文件系统的page cache中就够了.

组提交(group commit)

通常我们说的双1就是指sync_binlog和innodb_flushlog_at_trx_commit都设置成1,也就是说,一个事物的提交前,需要等待两次刷盘,一次redo log(prepare阶段),一次binlog

按照上面的原理,当mysql的TPS达到每秒两万的话,每秒就会写四万次磁盘,但是实际上磁盘也就两万左右,怎么实现两万TPS呢,其实就是使用到了组提交的机制了

首先我们说一个概念,LSN(日志逻辑序列号),LSN是对应redo log 的一个个写入点,每次写入长度为length的redo log,LSN的值就会加上length

下面是三个并发事物(trx1,trx2,trx3)在prepare阶段,都写完redo log buffer,持久化到磁盘的过程,对应的LSN分别是50,120,160

  1. 当trx1第一个到达,会被选为这组的leader
  2. 等trx1开始写的时候,这个组里面已经有三个事务,这个时候LSN也变成了160
  3. trx1去写磁盘的时候,就会写入LSN=160,因此等trx1返回的时候,小于160的redo log,都已经被持久化到磁盘
  4. 这时候trx2,trx3就可以直接返回了

所以一次组提交,组员越多,节约磁盘IOPS的效果越好,但如果只有单线程压测,那就只能老老实实的一个事物对应一次持久化操作了

在并发操作中,第一个事物写完buffer log buffer以后,接下来这个fsync越晚调用组员就越多,节约IOPS的效果就越好

binlog也是可以进行组提交的,我知道两阶段提交的时候如下图

其中binlog可以分成两个动作

  1. 先把binlog从binlo cache中写到磁盘的binlog文件
  2. 调用fsync持久化

mysql为了让组提交效果更好,把redo log 做fsync的时间拖到了上面额步骤1,也就是下图这样

而此时图中的第4步把binlog fsync到磁盘时候,如果有多个事物binlog已经写完了,也是可以一起持久化的,这样也就减少了IOPS的消耗

不过上面的步骤3执行的很快,因此binlog的write和fsync之间的间隔时间短,导致集中到一起持久化的binlog比较少,因此binlog组提交的效果不如redolog的效果好.

如果想要提升binLog组提交的效果,可以设置下面两个参数

  1. binlog_group_commit_sync_delay参数,表示延迟多少微妙后才调用fsync
  2. binlog_group_commit_sync_no_delay_count参数,表示累积多少次后调用fsync

这两个参数是或的关系,但是如果binLog_group_commit_sync_delay设置成0,binlog_group_commit_sync_no_delay_count也不会起作用

顺便说的是WAL的好处如下

  1. redo log和binlog都是顺序写,磁盘的顺序写比随机写速度要快
  2. 组提交机制,可以降低磁盘的IOPS消耗

最后,如果我们的mysql遇到了性能瓶颈,且在IO上,可以通过哪些方法来提升呢

  1. 设置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count的参数,减少binlog写盘的次数,这个方法是基于额外等待来实现的,因此可能会增加语句的响应时间,但是没有丢失数据的风险
  2. sync_binlog设置大于1的值,这样做的风险是,主机挂了会丢失binlog日志
  3. 设置innodb_flush_log_at_trx_commit=2,但是还是会丢失数据(不建议设置设置成0,因为容易丢失数据,风险太大,而redo log写入page caceh的速度也是很快的,所以设置成2和0的性能差不多,因此建议设置成2,可以保证数据不丢失)

如果对您有一丝丝帮助,麻烦点个关注,也欢迎转发,谢谢

扫码关注

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洁癖是一只狗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档