MySQL 的数据都存放在磁盘文件里,表示逻辑概念,对应到物理概念是表空间,对应着一个 xxx.idb 文件。
磁盘文件的 是被拆分为一个个数据区分组,由256个数据区构成。而一个数据区由64个数据页构成,即1MB。
而每个数据页由 一行行的数据构成,16kb。当然其中肯定会有描述数据,而不是单纯的数据记录,在数据行,数据页,数据区都有很多附加的特殊信息。
各种特殊信息,让我们在磁盘文件里面实现B+树索引、事务等复杂的机制
如果我们要插入一条数据,那么是选择磁盘文件中的那个数据页加载到缓存文件中去呢?也就是说怎么找到数据行所在的数据页呢?
先找表空间 -> 磁盘文件 -> 数据组 -> 数据页 加载出来放入buffer Pool
一个数据页的大小其实是固定的,所以一个数据页固定就是可能在一个磁盘文件里占据了某个开始位置到结束位置的一段数据,此时你写回去也是一样的,选择好固定的一段位置的数据,直接把缓存页的数据写回去,就覆盖了原来的数据页了。
MySQL数据库 和 底层操作系统之间的交互原理,为啥生产数据库每隔一两个月就产生急剧抖动
MySQL在实际工作时的两种数据读写机制
表空间的磁盘文件里的数据页进行的磁盘随机读写
MySQL 在CRUD 的时候,会先从表空间的磁盘文件里读取数据页出来,典型的随机读写操作
因为读取的数据可能在磁盘的任意一个位置,所以在读取磁盘里的数据页的时候只能用随机读的方式。
因为随机读的性能是比较差的,所以不能每次更新数据都进行磁盘随机读,必须是读取一个数据页放到buffer pool 缓存里面去,下次要更新的时候直接更新Buffer pool 即可。
磁盘随机读来说,关注性能指标是 IOPS 和 响应延迟
- IOPS - 就是说底层的存储系统每秒可以执行多少次磁盘读写操作 , 就是说底层的存储系统每秒可以执行多少次磁盘读写操作
响应延迟, 假设你的底层磁盘支持你每秒 执行200个随机读写操作,但是每个操作是耗费10ms完成呢,还是耗费1ms完成呢,这个其实也是有很大的影响的, 决定了你对数据库执行的单个crud SQL语句的性能 比如你一个SQL语句发送过去,他磁盘要执行随机读操作加载多个数据页,此时每个磁盘随机读响应时间是50ms,那么此时可能你的SQL语句要执行几百ms,但是如果每个磁盘随机读仅仅耗费10ms,可能你的SQL就执行100ms就行 了。 所以其实一般对于核心业务的数据库的生产环境机器规划,我们都是推荐用SSD固态硬盘的,而不是机械硬盘,因为 SSD固态硬盘的随机读写并发能力和响应延迟要比机械硬盘好的多,可以大幅度提升数据库的QPS和性能。
redo log、bin log
在Buffer Pool,里面更新了数据之后,必须写一条redo log 日志,走的顺序写,就是在一个磁盘的日志文件里,一直在末尾追加日志。

磁盘顺序写的性能其实是很高的,某种程度上来说,几乎可以跟内存随机读写的性能差不多,尤其是在数据库里其实 也用了os cache机制,就是redo log顺序写入磁盘之前,先是进入os cache,就是操作系统管理的内存缓存里。
对于这个写磁盘日志文件而言,最核心关注的是磁盘每秒读写多少数据量的吞吐量指标 , 就是说每秒可以写入磁 盘100MB数据和每秒可以写入磁盘200MB数据,对数据库的并发能力影响也是极大的因为数据库的每一次更新SQL语句,都必然涉及到多个磁盘随机读取数据页的操作,也会涉及到一条redo log日志文 件顺序写的操作。所以磁盘读写的IOPS指标,就是每秒可以执行多少个随机读写操作,以及每秒可以读写磁盘的数据 量的吞吐量指标,就是每秒可以写入多少redo log日志,整体决定了数据库的并发能力和性能
包括你磁盘日志文件的顺序读写的响应延迟,也决定了数据库的性能,因为你写redo log日志文件越快,那么你的 SQL语句性能就越高。
