从之前的Mysql架构可以了解到,Mysql 客户端不是直接和磁盘打交道,我们在客户端输入的sql语句会被发送给服务端,服务端对sql语句进行解析、缓存等操作,然后再交由存储引擎去读写磁盘。这其实是从 C/S 的角度去了解Mysql。
站在OS的角度,Mysql 的数据保存在磁盘,本质还是文件IO,Mysql是如何跟内核(OS)打交道的呢?
目录
1、Mysql 交互模型(站在OS的角度)
(1) Mysql 从磁盘读数据
(2) Mysql 向磁盘写数据
2、Mysql 交互的基本单位
(1) 交互的基本单位(每次IO的数据量)
(2) 为什么IO交互要以page为基本单位?
1、Mysql 交互模型(站在OS的角度)
核心理念说在最前面,Mysql 对数据所做的所有访问,无论是查询,还是增删改,都是在内存中进行的!
(1) Mysql 从磁盘读数据
早在Mysql 启动的时候,Mysql 就会向内存申请一块空间(下面统称“缓存池”)。
每次查询的时候,会预先从磁盘读取一部分相关数据到缓存池。(至于读取多少,详见“Mysql和磁盘交互的基本单位”)
每次增删改的时候,如果缓存池里存在对应的记录,那就直接在已有的记录上改;如果不存在,那就先从磁盘读取到缓存池,然后再改。
(2) Mysql 向磁盘写数据
所有的增删改查都在内存中进行,每次执行sql的时候都会在缓存池中先把数据调整好,然后再刷新到内核缓冲区。内核有自己刷新策略,会定期把数据从内核缓冲区刷新到磁盘。
从缓存池 ==》内核缓冲区的刷新策略有以下三种选择:
- 有脏数据就立马刷新(脏数据是内存操作完毕以后的数据)
- 定期刷新
- 达到一定的数据量再刷新
从内核缓冲区 ==》磁盘的刷新则是定期刷新。如果想要手动刷新内核缓冲区,可以参考系统调用接口 syncfs 。
2、Mysql 交互的基本单位
(1) 交互的基本单位(每次IO的数据量)
上面提到,查询时,Mysql 会读取一部分数据到缓存池,那么问题来了,每次到底读取多少呢?
Mysql和外设交互的基本单位是16KB,即一次IO的数据量就是16KB,站在Mysql的角度,这16KB就是一个page。读数据时,将以page为单位,把相关数据从磁盘读取到内存;写数据也是同理。
(2) 为什么IO交互要以page为基本单位?
假设每次查询都只读取一条记录,多次查询的时候,就要频繁跟数据库(简单理解为磁盘)交互。系统和磁盘的IO是比较费时的,为了提升效率,一般我们要尽量减少系统和磁盘IO的次数。
如果每次查询,我们以page(16KB)读取数据,那就相当于我们可以一次读取几百条记录到缓存池中,即便我们后续要频繁查询数据库,只要是在这个 page 里的内容,我们便无需和磁盘IO。