ps
真实的流程没有我说的那么简单,下面的是最基本的情况。
预备知识redolog
binlog
WAL机制
redolog简介
redolog是个循环日志,其大小固定为4g,存在2个指针来定位其是否已经满了。一个指针是当前写,一个指针是当前checkpoint,其2个指针的顺时针空间就是可写的空间。
这个redolog就是完成mysql突然宕机后,如何无损恢复数据的。
binlog简介
这个是mysql自身的日志,叫做归档日志。和redolog大致3个不同点。其为mysql自带的,redolog是innodb里面的。
redolog是物理日志,binlog是逻辑日志。
redolog是循环日志,binlog是增量日志。
这里不对其过多介绍,下一篇文章关于主从的详细介绍,主从就是通过binlog完成的。
WAL机制简介
MySQL里经常说到的 WAL 技术,意思就是数据入库前先写进去日志,再写磁盘里面。
这里采用的是数据安全性最高的双1策略。
其数据更新顺序也保持着其顺序。
下面我来简单介绍下。
1.当要更新id=2这一行数据时,先通过这个表的索引,查询到这行记录所在的数据页。然后判断这个数据页是否在buffer pool(这个是内存)。
2.如果不在内存则需要读到内存(其实也可以不用读入内存,当要更新的这行数据没有唯一索引时,mysql为了提高效率,采用了change buffer(别看有个buffer,但是人家也是持久化到磁盘的)这个东西,将对这行修改的动作记录到change buffer里面,就不用读到内存了)。
3.在buffer pool 内存上修改这行数据(仅仅只是在内存上修改了这行数据,并没有持久化到磁盘里面)。
4.将上面的操作,写入到redolog里面,且将这个操作状态设置为prepare状态,首先写到redologbuffer里面(为了提高效率,mysql做了组提交这个优化,这里不扩展),等到这个事务提交后,redologbuffer然后再写入到文件系统的page cache里面,然后立马调用fsync,将其刷到磁盘。
5.然后写入到binlog里面,先写到binlog cache里面,然后写入page cache,然后调用fsync,写入磁盘。
6.redolog继续写一次,将其状态设置为commit状态。
如此就算完成了一个更新操作。
mysql 如何做到crash后,数据不丢失的
前面说了数据更新操作。
当前buffer pool里面存在大量脏页(就是一些数据页,只在内存里面修改了,没有刷新到磁盘),当系统宕机了,内存里面的数据全部丢失了怎么办?
方法如下:我们需要redolog来完成灾难备份,check point到writ pos这块空间记录的所有的操作步骤派上用场了,根据这些redolog记录从磁盘里面读取所有相关的数据页。然后按照redolog上的操作恢复数据即可,那么我们发现存再内存的数据全部恢复了。