1.2.3 MyISAM是如何存储表数据的和InnoDB不同,MyISAM没有表空间的概念,表的数据和索引全都直接存放在对应的数据库子目录下,可以看到t_user_myisam对应了三个文件
- t_user_myisam.MYD
- t_user_myisam.MYI
- t_user_myisam.frm
1.2.4 MEMORY是如何存储表数据的MEMORY存储引擎对应的数据表只有一个描述表结构的文件t_user_memory.frm 。
2. 缓冲池Buffer Pool为了更好的利用局部性原理带给我们的优势,InnoDB在处理客户端请求时,如果需要访问某个页的数据,会把该数据所在的页的全部数据加载到内存中 。哪怕是只需要访问一个页中的一条数据,也需要加载整个页 。
从磁盘中加载数据到内存中的操作太昂贵了!有什么办法可以提高数据操作的效率呢?缓存!
为了缓存磁盘的页,InnoDB在MySQL服务器启动时会向操作系统申请一片连续的内存区域,这片内存区域就是Buffer Pool 。
很容易理解,为了更好地缓存页数据,Buffer Pool对应的一片连续内存空间也被划分为若干个页,而且默认情况下,Buffer Pool页的大小和InnoDB页大小一样,都是16KB 。为了区分两种不同的页,我们将Buffer Pool中的页面称为缓冲页 。

文章插图
读取数据的时候,InnoDB先判断数据是否在Buffer Pool中,如果是,则直接读取数据进行操作,不用再次从磁盘加载;如果不是,则从磁盘加载到Buffer Pool中,然后读取数据进行操作 。
修改数据的时候,也是将数据先写到Buffer Pool缓冲页中,而不是每次更新操作都直接写入磁盘 。当缓冲页中的数据和磁盘文件不一致的时候,缓冲页被称为脏页 。
那么脏页是什么时候被同步到磁盘呢?
InnoDB中有专门的后台线程每隔一段时间会把脏页的多个修改刷新到磁盘上,这个动作叫做「刷脏」 。
3. redo日志3.1 为什么需要redo日志不定时刷脏又带来一个问题 。如果脏页的数据还没有刷新到磁盘上,此时数据库突然宕机或重启,这些数据就会丢失 。
首先想到的最简单粗暴的解决方案就是在事务提交之前,把该事务修改的所有页面都刷新到磁盘 。但是上文说过,页是内存和磁盘交互的最小单位,如果只修改了1个字节,却要刷新16KB的数据到磁盘上,不得不说太浪费了,此路不通!
所以,必须要有一个持久化的措施 。
为了解决这个问题,InnoDB把对所有页的更新操作(再强调一遍,包含INSERT、UPDATE、DELETE)专门写入一个日志文件 。
当有未同步到磁盘中的数据时,数据库在启动的时候,会根据这个日志文件进行数据恢复 。我们常说的关系型数据库的ACID特性中的D(持久性),就是通过这个日志来实现的 。
这个日志文件就是大名鼎鼎的redo日志 。
「re」在英文中的词根含义是“重新”,redo就是「重新做」的意思,顾名思义就是MySQL根据这个日志文件重新进行操作

文章插图
这就出现了一个有意思的问题,刷新磁盘和写redo日志都是进行磁盘操作,为什么不直接把数据刷新到磁盘中呢?
3.2 磁道寻址我们需要稍微了解一下磁道寻址的过程 。磁盘的构造如下图所示 。

文章插图
每个硬盘都有若干个盘片,上图的硬盘有4个盘片 。
每个盘片的盘面上有一圈圈的同心圆,叫做「磁道」 。
从圆心向外画直线,可以将磁道划分为若干个弧段,每个磁道上一个弧段被称之为一个「扇区」(右上图白色部分) 。数据是保存在扇区当中的,扇区是硬盘读写的最小单元,如果要读写数据,必须找到对应的扇区,这个过程叫做「寻址」 。
3.2.1 随机I/O如果我们需要的数据是随机分散在磁盘上不同盘片的不同扇区中,那么找到相应的数据需要等到磁臂旋转到指定的盘片然后继续寻找对应的扇区,才能找到我们所需要的一块数据,持续进行此过程直到找完所有数据,这个就是随机I/O,读取数据速度非常慢 。
3.2.2 顺序I/O假设我们已经找到了第一块数据,并且其他所需的数据就在这一块数据之后,那么就不需要重新寻址,可以依次拿到我们所需的数据,这个就叫顺序 I/O 。
推荐阅读
- 腾讯QQ macOS版6.8.8.6517测试版更新:表情面板新增GIF表情Tab
- 天下长河|《天下长河》更新慢不够看?别慌,6部重磅大剧将播,总有你的菜
- lazada|“卖爆”东南亚的国货美妆,趟出了一条出海路
- flink sqlserver flinksql语法
- 功能齐全的 MySQL 数据库管理工具
- 于魁智|“京剧界最好的一条嗓子”于魁智:我没有离婚,妻子还是原配
- 剑网3|LML就一个职业,Mlxg脾气太差,直言就像一条狗,北枫还挺厉害
- 许敏|相亲相爱一家人!姚策堂嫂更新言宝旧照,一家人忙碌打包很温馨
- 世界排名更新了 羽毛球 世界排名
- SQLSERVER如何分离和附加数据库
