比较操作系统和MySQL的InnoDB引擎
首先介绍一下操作系统里面CPU、CPU缓存、内存和磁盘的关系,这里以图书馆举例(小林coding中操作系统里面的例子)。
当你在图书馆里面学习的时候:
缓存相当于你的大脑,大脑里面的知识你可以很快的接收到;
内存相当于桌面上面的知识,你也可以较快的得到;
磁盘相当于图书馆书架上面的知识,取的时候会更慢一点;
一、都使用了分页
操作系统:操作系统内存分页,每页4KB,依据计算机组成原理的局部性原理,认为下一次访问的数据在目前访问数据的附近,所以每一次操作的单位都是一页。
InnoDB引擎:每页16KB,依据计算机原理里面的局部性原理,认为下一次访问的数据在目前访问数据的附近,每次从磁盘里面存取数据都是以页为单位。
二、都使用了缓存来提高效率
操作系统中的CPU:有缓存,对于CPU来说,有CPU独立的一级缓存和二级缓存,还有多个CPU共享的三级缓存,使用缓存来增大数据的访问效率。
程序执行的时候,会将内存中的数据加载到共享的三级缓存里面,然后依次加载到二级缓存和一级缓存里面,最后才会被CPU读取。
InnoDB引擎:并且在内存里面有缓存空间,维护了free链表、flush链表以及LRU链表,为了方便用户的操作。
三、数据一致性
操作系统中CPU:保证CPU缓存和内存中数据的一致性
- 写直达:每一次修改数据的时候,去判断当前数据是否存在于缓存里面,如果存在就要对缓存里面的数据进行修改,然后更新到内存里面;如果不存在与缓存里面,直接更新内存里面的数据。
- 写回:发生写操作的时候,新的数据只写到缓存里面,只有当修改过的缓存块被替换时才需要写到内存中。
InnoDB引擎:保证缓存和磁盘里面的数据一致性
在缓存中维护三个链表:
- free链表:维护当前没有存储数据的数据块
- flush链表:维护已经被修改的数据块,但是还没有写回到磁盘里面
- LRU链表:为了可以更快的访问数据,存储热点数据,包括冷热区域,防止全表扫描的时候把不是热点的数据存储在LRU链表里面
MySQL中会有一个线程,以一定的间隔时间去把flush链表里面的数据写回到磁盘里面,来保证数据一致性。
四、操作系统中的缓存一致性
因为现在的操作系统都有多个CPU,对于不同的CPU来说,会有独有的一级缓存和二级缓存,只有三级缓存是多个CPU共享的,所以要保证各个CPU独有的缓存里面数据的一致性,也就是缓存一致性。
方法:
-
当一个CPU核心里的缓存数据更新的时候,要传播到其他的CPU的缓存里面,称为写传播。
实现方式:总线嗅探。每个核心都会监听总线上面的广播,如果发现当前修改的数据也存在于自己的缓存里面,就进行修改。
缺点:CPU需要一致监听总线上面的变化,并且不管其他的CPU是否缓存了我当当前修改的数据,都需要在总线上面进行广播,增加了总线的负载。
解决方法:MESI协议,Cache Line有四种状态:modified、exclusive、shared、invalidated
-
事务串行化:某个CPU对数据的操作,必须和其他核心看起来顺序是一样的。如果两个数据都要设置i,A核心设置为100,B核心设置为200,同时进行操作,这个时候两个核心看到的i的值必须是一致的,比如:i都是先变成100,再变成200。
Last but not least:以上都是学习中我自己的理解,如果有错误欢迎批评指正~