mysql怎么保证一致性 mysql保证数据一致性

汗颜!工作10年去面试 , 被“MySQL怎么保证事物一致性”难倒了阿牛去一家中意的公司面试,本以为凭借以往丰富的经验,肯定手到擒来 , 结果第一个问题,我就“出门右拐”了 。
问题就是:MySQL是怎么保证事务一致性的?
回到家阿牛翻阅资料,终于搞懂了,在这里分享给大家 。
定义
在搞清楚问题答案之前,先搞清楚以下几个名词以及大致的用处
redo log:
通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)、Innodb特有的,他在存储引擎层 。循环写的,空间固定会用完 。作用是crash-safe能力
binlog:
是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ” 是 MySQL 的 Server 层实现的 , 所有引擎都可以使用 。是可以追加写入的,“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志 。作用是数据归档
undo log:
有两个作用:提供回滚和多个行版本控制(MVCC) 。
在数据修改的时候 , 不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚 。
SQL执行的过程
了解了以上名词之后 , 让我们看一下“一条更新SQL语句执行的过程是什么?”
如图1有几个关键步骤:
1、先查找记录所在的Innodb页在不在内存里;如果不在内存里则将记录所在的页加载在内存里;根据SQL语句在内存中将记录更新
2、将更新前的记录写入undolog
3、根据记录的更新值将变更写入redolog(buffer)中,并将状态变更为prepare
4、将变更记录到逻辑日志
5、redolog日志中的状态修改为commit,返回结束
至此:一条更新语句的过程结束
上面的步骤中有些同学可能会有一些疑问:为什么更新一条记录要把一整页数据加载到内存里答:因为Innodb引擎中 , 最小的存储单位是页为什么一定要加载到内存里?答:因为所有的计算操作都是在内存里,操作完成后最终才写回磁盘为什么要写入redolog , 直接写入磁盘,然后写入binlog就好了?。看穑赫饨谙旅婊崽岬剑胪罂?
为了加深理解,准备了下面2张图辅助理解
以图3为例,让我们看看在每个步骤出现异常的时候,到底怎么保证事物一致性的吧!1、步骤123,所有的操作最多还只是内存里,如果出现宕机、断电等异常,记录不会有任何变动 , 事物是一致的2、步骤4刚执行完,断电了,因为redolog还处在prepare状态,这时候事物也是一致的3、步骤5记录binlog的过程中断电了,这时候要保证主从一致性,事物也是不生效的,最终也是一致的4、步骤6、7如果中间任何一个时刻断电了 , 这时候情况就不一样了,事物是生效的,因为redolog、binlog的数据都是完整的,服务器重启后可以按照xid来去查看binlog、redolog中是否都存在 , 都存在该事物就是生效的 。上面就是怎么保证事务一致性的根本原因
为什么要使用redolog?
回答这个问题之前,我们先看看redolog用图形表示的
图4是redolog的形象一点的表现,并不是说redolog 长这个样子,只是为了更形象;一般情况下redolog一组4个文件,每个文件1个G,其中write pos是指redolog当前写到什么位置了,check point是指上次刷脏结束的位置 , 当write log和check point重合时,所有的进程停止,开始新一轮的刷脏操作 。刷完后redolog清空开始下一轮的写入,往返重复 。

推荐阅读