mysql的日志模块

一条sql执行的过程:     

连接器-------->分析器------->优化器--------->执行器-------->存储引擎    #如下图

mysql的日志模块

 不建议使用查询缓存的原因: 如果表有数据更新的话,这张表的缓存都会被清空

redo log日志(重做日志):

特性:  innodb的引擎层日志,redo log日志大小时固定的(可通过参数设置),可配置日志个数,可重复写,存储的是脏页,写满后会读入到磁盘(读入的过程称之为刷脏)

一家商店有一个记账板,当赊账顾客多的时候,会临时记录在记账板上,避免频繁去记账本上查找更新对应顾客的信息。等到生意不忙的时候,再将记账板上的信息同步到账本上 。避免高峰期拥堵,提高了工作的效率。

同样,mysql也有这个问题,为了避免更新数据的时候IO成本和查询成本过高,通过WAL技术来避免。WAL技术关键点就是先写日志,后写磁盘,也就是先写记账板,后写账本。

流程:

1.不繁忙情况:  有一条语句需要更新,innodb引擎先记录到redo log中,更新内存,这个时候就算更新完成了。在不繁忙的时候再读入磁盘

2.繁忙情况下:记账板写满,把数据更新到记账本,擦掉记账板。

mysql的日志模块

redo log有个好处,可以再数据库发生异常重启保证之前提交的数据不丢失,这个能力成为crash-safe

binlog日志:

特性:server层日志,归档日志,记录数据库执行的查询、DML、DDL语句,记录内容是追加写,可以生成多个文件。

redo log   和  binlog 不同:

1、redo log 是innodb引擎特有的,基于innodb引擎层面的日志。 而binlog是server层日志,所有引擎都可以使用。

2、redo log 是物理日志,记录了做了什么操作。而binlog日志是逻辑日志,具体记录了操作语句。

3、redo log 循环写,空间固定会用完。而binlog是可以追加写入生成多个文件的,不会覆盖以前日志。

执行器和innodb引擎执行update语句流程:    update  t  set c=c+1

1、执行器先找引擎拿到ID=2这一行数据。数据在内存直接返回,不在的话先从磁盘读入内存然后返回。

2、执行器拿到引擎给的数据,将c值+1,得到新数据后调用引擎接口写入这条新数据

3、引擎将这条新数据更新到内存中(change buffer),同时将这条更新操作记录到redo log 里边,此时redo log处于prepare状态。然后通知执行器执行完成了,随时可以提交

4、执行器生成这个操作记录的binlog,并把binlog写入磁盘。

5、执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log状态改成commit状态,更新完成。

图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的:

mysql的日志模块

相关推荐