1.redo log 和 bin log的流程及区别
1、更新内存,然后写redo日志。后续的流程是生成此操作的binlog,然后写到磁盘。
2、redo日志是存储引擎实现的,记录的在某个数据页做了什么修改,固定大小,默认为4GB,可以循环写,解决了每次更新操作写磁盘、查找记录、然后更新整个过程效率低下的问题,redo日志将磁盘的查找写变成了顺序写,这个机制是WAL,先写日志再刷磁盘。一句话,redo日志保证了事务ACID的特性
3、binglog日志Server层实现的,记录的是语句的原始逻辑,比如给ID=1的行的状态设置成1,追加写,上个文件写完回切换成下一个文件,类似滚动日志
4、两阶段提交,是为了解决redo log和binlog不一致问题的,这里的不一致是指redo log写成功binlog写失败了,由于恢复是根据binlog恢复的,这样恢复的时候就会少一条更新操作,导致和线上库的数据不一致。具体而言,两阶段是指prepare阶段和commit阶段,写完redo log进入prepare阶段,写完binlog进入commit阶段。
然后说下由redo log联想到之前遇到的一个问题:一个普通的select查询超过30ms,经过和DBA的联合排查,确认是由于MySQL“刷脏”导致的。
所谓刷脏就是由于内存页和磁盘数据不一致导致了该内存页是“脏页”,将内存页数据刷到磁盘的操作称为“刷脏”。刷脏是为了避免产生“脏页”,主要是因为MySQL更新先写redo log再定期批量刷到磁盘的,这就导致内存页的数据和磁盘数据不一致,为了搞清楚为什么“刷脏”会导致慢查,我们先分析下redo log再哪些场景会刷到磁盘。
场景1:redo log写满了,此时MySQL会停止所有更新操作,把脏页刷到磁盘
场景2:系统内存不足,需要将脏页淘汰,此时会把脏页刷到磁盘
场景3:系统空闲时,MySQL定期将脏页刷到磁盘
可以想到,在场景1和2都会导致慢查的产生,根据文章提到的,redo log是可以循环写的,那么即使写满了应该也不会停止所有更新操作吧,其实是会的,文中有句话“粉板写满了,掌柜只能停下手中的活,把粉板的一部分赊账记录更新到账本中,把这些记录从粉板删除,为粉板腾出新的空间”,这就意味着写满后是会阻塞一段时间的。
那么问题来了,innodb存储引擎的刷脏策略是怎么样的呢?通常而言会有两种策略:全量(sharp checkpoint)和部分(fuzzy checkpoint)。全量刷脏发生在关闭数据库时,部分刷脏发生在运行时。部分刷脏又分为定期刷脏、最近最少使用刷脏、异步/同步刷脏、脏页过多刷脏。暂时先写到这,后面打算写文详细介绍。
后续正在更新。。。。。。