查询sql的流程,更新sql同样会走一遍。执行的sql首先连接数据库,通过连接器,清该表相关的缓存,接下来分析器通过词法分析和语法解析知道这是一个更新sql。优化器决定使用使用所有,执行器负责具体执行,找到这条sql,然后更新。与查询不一样的是,更新设计两个日志模块redolog(重做日志)和binlog(归档日志)
一、redolog日志
redolog是物理日志,是Innodb存储引擎特有的日志,是在存储层实现的。记录了哪个数据页,做哪些操作,哪些偏移量等。当一条数据更新的时候,执行器不会将数据直接写入磁盘,而是先写入redolog,再写入到内存中。也就是所谓的wal技术(write ahead logging),先写日志再写磁盘
write pos代表当前写的位置,一边写一般往后移动,当写到最后一个文件结尾时,会从新回到第一个文件开头继续写。
check point是擦除的位置,也是向后移动的,擦除前要把记录写入到数据文件。
二、binlog日志
从整体看,binlog日志是在server层实现的,binlog日志也被称为归档日志。binlog日志是逻辑日志,记录的是执行的sql日志,会有多个日志文件,一个文件写满了,会再写一个文件。
三、执行器执行一条sql的过程
执行过程如下:
1、执行器首先通过id查找改行数据,如果id是索引,则通过索引引擎查找。如果当前数据页在内存中,则返回给执行器,否则从磁盘中将该数据页读到内存里。
2、执行器拿到这行数据,执行c+1操作,得到新的一行,写入内存,并写入redolog,此时redolog状态是prepare,之后通知执行器,可以提交事务了。
3、执行器生成binlog,并写入磁盘
4、执行器提交事务,并把刚刚的redolog的prepare改为commit。
redolog和binlog分为两阶段提交时为了保证数据的一致性。
四、两个参数
innodb_flush_log_at_trx_commit
1、设置为0:速度最快,不安全崩溃的时候,上一秒的所有数据会丢失
2、设置为1:最安全,也是最慢,崩溃时可能会丢失个别事务
3、设置为2:比0安全,只有在断电的情况下,才会丢失上一秒的所有数据或事务
sync_binlog:
sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。
如果sync_binlog>0,表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去。最安全的就是sync_binlog=1了,表示每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据。但是binlog虽然是顺序IO,但是设置sync_binlog=1,多个事务同时提交,同样很大的影响MySQL和IO性能。虽然可以通过group commit的补丁缓解,但是刷新的频率过高对IO的影响也非常大。对于高并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。
所以很多MySQL DBA设置的sync_binlog并不是最安全的1,而是100或者是0。这样牺牲一定的一致性,可以获得更高的并发和性能