前言
MySQL中执行一条SQL语句,相应表数据的读写都是由存储引擎去做(更新数据、查询数据)。
在这个过程,存储引擎需要决策一些事情
- 数据是从内存查还是从硬盘查
- 数据是更新在内存,还是硬盘
- 内存的数据什么时候同步到硬盘
所以存储引擎会按照内部逻辑与内存、硬盘交互。
![]()
我们可以按需选择存储引擎,比如常见的 InnoDB、MyISAM、Memory 等等。
![]()
众多存储引擎中,InnoDB是最为常用的,从 MySQL5.5.8 版本开始,InnoDB是默认的存储引擎。
InnoDB简介
InnoDB存储引擎支持事务,其设计目标主要面向在线事务处理(OLTP)的应用。
特点是行锁设计、支持MVCC、外键,提供一致性非锁定读,同时本身设计能够最有效的利用内存和CPU,是 MySQL 最常用的存储引擎。
InnoDB的重要内存结构
![]()
InnoDB存储引擎在内存中有两个非常重要的组件,分别是缓冲池(Buffer Pool)和重做日志缓存(redo log buffer)。
Buffer Pool简介
缓冲池(Buffer Pool)里面会缓存很多的数据,比如数据页、索引页、锁信息等等。
MySQL表数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 Buffer Pool 中。
后续的查询先从 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。
更新表数据的时,如果 Buffer Pool 里命中数据,就直接在 Buffer Pool 里更新。
![]()
总之 Buffer Pool 会缓存很多的数据,以便后续的查询与更新。
小贴士:这里只是用数据页举例帮助大家理解,大家千万不要认为 Buffer Pool 里面只有数据页,它只是占 Buffer Pool 大部分空间,关于 Buffer Pool 更多细节,后续会有专门的文章讲解。
redo log buffer简介
接着思考一个问题,假设我们把 Buffer Pool 中某个数据页的某条数据修改了,但是硬盘的数据还未同步,此时数据是不一致的,如果 MySQL 宕机了,数据就丢失了。
![]()
这可怎么办呢。
为了保证数据的持久性,InnoDB存储引擎加入了 redo 日志功能,也叫重做日志。
每当我们对表数据进行更新时,会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里。
当事务提交时,会把 redo log buffer 清空,刷盘到 redo 日志文件。
![]()
这样 MySQL 宕机了也没关系,因为重启后会根据 redo 日志去恢复数据。
![]()
小贴士:redo日志细节也很多,本文只做个介绍,后续会有专门的文章讲解。
小结
其实不难发现,缓冲池(Buffer Pool)和重做日志缓存(redo log buffer),它们都是为了减少硬盘 IO 开销。
因为 Buffer Pool 与 redo 日志涉及内容较多,后面会出两篇文章单独讲。
今天讲的这些内容全是在给后面的文章做铺垫,大家先知道它们是干嘛的,留个印象就行了。
站在巨人的肩膀上:
- 《MySQL实战45讲》
- 《从零开始带你成为MySQL实战优化高手》
- 《MySQL是怎样运行的:从根儿上理解MySQL》
- 《MySQL技术Innodb存储引擎》
白嫖福利
给粉丝的高质量福利,低调领取哈~
点击领取,零基础到Java就业全套教程、架构师全套教程
MySQL好文推荐