mysql的日志模块

Posted 天宇星空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql的日志模块相关的知识,希望对你有一定的参考价值。

一条sql执行的过程:     

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

 

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

 

redo log日志(重做日志):

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

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

记账板可以看做 redo log  账本可以看做为数据文件,老板的记忆可以看做是内存。

 

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

流程:

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

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

redo log有个好处,可以再数据库发生异常重启保证之前提交的数据不丢失,这个能力成为crash-safe。还有就是将mysql随机写入磁盘转换为了顺序写入磁盘,提升了磁盘的IO性能。

 

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、引擎将这条新数据更新到内存中,同时将这条更新操作记录到redo log 里边,此时redo log处于prepare状态。然后通知执行器执行完成了,随时可以提交

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

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

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

 最后三步:  写入redo log,并将其 状态置为:prepare    ----->写binlog------->提交事务,将redo log状态置为:commit   ;这个过程是为了保证redo log 和binlog俩个日志逻辑上数据的一致性,过程称为:俩阶段提交。

如果先写redo log ,在binlog写入之前发生故障重启。恢复后,redo log日志数据写入磁盘,而binlog日志却少了数据,会导致 新做的从库数据缺少。

如果先写binlog   ,在redo log 写入之前发生故障重启,恢复后,拿binlog做了新的从库,会导致从库的数据比主库多数据。

 

这里涉及到俩个参数:

innodb_flush_log_at_trx_commit    #默认为1  表示每次事务的 redo log 都直接持久化到磁盘    

sync_binlog   #默认为0   表示每次事务的 binlog 都持久化到磁盘

在服务器性能  还有  数据的安全性(crash后保证数据都落盘,不丢失)  俩方面 权衡,根据业务需求自行设置。

 

以上是关于mysql的日志模块的主要内容,如果未能解决你的问题,请参考以下文章

拆解大数据总线平台DBus的系统架构

mysql日志

MySQL的两个日志系统

2 (mysql实战) 日志系统

Python日志模块介绍

python-日志模块