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的日志模块的主要内容,如果未能解决你的问题,请参考以下文章