mysql wal_MySQL · 引擎特性 · WAL那些事儿

前言

日志先行的技术广泛应用于现代数据库中,其保证了数据库在数据不丢的情况下,进一步提高了数据库的性能。本文主要分析了WAL模块在MySQL各个版本中的演进以及在阿里云新一代数据库POLARDB中的改进。

基础知识

用户如果对数据库中的数据就行了修改,必须保证日志先于数据落盘。当日志落盘后,就可以给用户返回操作成功,并不需要保证当时对数据的修改也落盘。如果数据库在日志落盘前crash,那么相应的数据修改会回滚。在日志落盘后crash,会保证相应的修改不丢失。有一点要注意,虽然日志落盘后,就可以给用户返回操作成功,但是由于落盘和返回成功包之间有一个微小的时间差,所以即使用户没有收到成功消息,修改也可能已经成功了,这个时候就需要用户在数据库恢复后,通过再次查询来确定当前的状态。 在日志先行技术之前,数据库只需要把修改的数据刷回磁盘即可,用了这项技术,除了修改的数据,还需要多写一份日志,也就是磁盘写入量反而增大,但是由于日志是顺序的且往往先存在内存里然后批量往磁盘刷新,相比数据的离散写入,日志的写入开销比较小。 日志先行技术有两个问题需要工程上解决:

日志刷盘问题。由于所有对数据的修改都需要写日志,当并发量很大的时候,必然会导致日志的写入量也很大,为了性能考虑,往往需要先写到一个日志缓冲区,然后在按照一定规则刷入磁盘,此外日志缓冲区大小有限,用户会源源不断的生产日志,数据库还需要不断的把缓存区中的日志刷入磁盘,缓存区才可以复用,因此,这里就构成了一个典型的生产者和消费者模型。现代数据库必须直面这个问题,在高并发的情况下,这一定是个性能瓶颈,也一定是个锁冲突的热点。

数据刷盘问题。在用户收到操作成功的时候,用户的数据不一定已经被持久化了,很有可能修改还没有落盘,这就需要数据库有一套刷数据的机制,专业术语叫做刷脏页算法。脏页(内存中被修改的但是还没落盘的数据页)在源源不断的产生,然后要持续的刷入磁盘,这里又凑成一个生产者消费者模型,影响数据库的性能。如果在脏页没被刷入磁盘,但是数据库异常crash了,这个就需要做奔溃恢复,具体的流程是,在接受用户请求之前,从checkpoint点(这个点之前的日志对应的数据页一定已经持久化到磁盘了)开始扫描日志,然后应用日志,从而把在内存中丢失的更新找回来,最后重新刷入磁盘。这里有一个很重要的点:在数据库正常启动的期间,checkpoint怎么确定,如果checkpoint做的慢了,就会导致奔溃恢复时间过长,从而影响数据库可用性,如果做的快了,会导致刷脏压力过大,甚至数据丢失。

MySQL中为了解决上述两个问题,采用了以下机制:

当用户线程产生日志的时候,首先缓存在一个线程私有的变量(mtr)里面,只有完成某些原子操作(例如完成索引分裂或者合并等)的时候,才把日志提交到全局的日志缓存区中。全局缓存区的大小(innodb_log_file_size)可以动态配置。当线程的事务执行完后,会按照当前的配置(inn

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值