1.mysql执行sql大致流程
web容器中发起sql语句执行的请求
->从数据库连接池中拿到连接
->连接请求mysql中的sql接口
->sql解析器进行sql语句的步骤解析
->sql查询优化器进行sql语句的执行计划调优
->sql执行器按照执行计划执行sql语句
->sql执行器将执行任务交给存储引擎(InnoDb)
->存储引擎拿到执行任务后 先从磁盘中加载被执行数据的缓存页数据到Buffer pool
->然后生成一条undo日志 将旧数据写入(需要操作的数据先备份起来)
->在buffer pool中更新数据内存
->写入一条redo log日志(存储引擎级别的日志),存储的是逻辑日志.方便之后意外down机时可以再度更新内存中的数据
->准备将redo log刷入磁盘 redo log也是需要持久化的(准备提交事务阶段)
->sql server会针对此次存储引擎修改做一个binlog日志(准备提交事务阶段)
->redo log和bin log都刷盘之后 会写入binlog的文件位置 然后写入commit标志位(标志事务提交已完成)
->此时还在buffer pool中的脏页会被io线程随机的刷入磁盘,如果刷盘的过程中,mysqldown机了.脏页还未来得及刷盘(此时buffer pool全都会被清空),会判断redo log中的commit标志位 如果有生成,那么就加载磁盘中的redo log 执行数据内存的更新然后再继续交给io线程刷入磁盘
如果未生成commit标志位 那么认定此次执行无效(事务未成功提交)
2.redolog和binlog刷盘策略
2.1.redolog刷盘策略 配置值为indodb_flush_log_at_trx_commit
配置为0时 提交事务时不把redo log刷入磁盘
配置为1时,提交事务时把redo log刷入磁盘
配置为2时,redo log会先刷入OS cache中,1秒后才会把OS cache中的数据刷入磁盘
由此他们的执行速度是 0>2>1 综合考虑下通常会选择1
2.2.binlog刷盘策略 配置值为 sysnc_binlog
配置值为0时 首先刷入到OS cache,1么秒后刷入磁盘
配置值为1时,直接刷到磁盘
3.为啥会有redolog和binlog以及commit标志位
redolog是用来控制事务提交的,防止提交过程中mysqldown机导致的buffer pool中内存丢失
binlog是mysql server级别的日志,主要职责是mysql集群时用来同步从库的
redolog和binlog之间会有一致性的问题,为了避免这个问题所以才会有commit标志位