汇总:Innodb
用一条从行到页、索引、表空间、Buffer Pool、事务的主线,概览 InnoDB 的存储设计。
Innodb是 以磁盘作为存储介质的MySQL引擎。既然存储在磁盘上,那么:
- 关机之后记录就还会存在;
- 使用的时候需要加载到内存;
- 内容有改动的时候要从内存写回磁盘才算真正的保存下来;
- 改动的内容没写回磁盘之前,如果程序崩溃、服务器宕机,修改就丢失了;
等等,听起来怎么这么耳熟?脏页?写回?LRU?学计算机组成原理的时候,虚拟内存不也是这么玩儿的?是的。大家都是从磁盘加载到主存Main Memory的东西,都涉及到回写磁盘,所以一些基本的理念也就差不多了。
有一样的地方,自然也有不一样的地方:如果宕机了,内存会消失,这很符合逻辑,所以虚拟内存不需要考虑宕机丢失的问题,根本就没有丢失一说。但Innodb就不行了,作为一个优秀的数据库系统,mysql自然要规避这种问题,后面再讨论。
flowchart TD
Row["行<br/>列值 + metadata + 隐藏列"] --> Page["页<br/>16KB,页内链表 + 页目录"]
Page --> Index["索引<br/>B+ 树把页组织起来"]
Index --> Table["表<br/>段 / 区 / 碎片区管理空间"]
Table --> BufferPool["Buffer Pool<br/>把磁盘页缓存到内存"]
BufferPool --> Tx["事务<br/>undo / redo / MVCC / 锁"]
style Row fill:#e3f2fd,stroke:#1976d2
style Page fill:#e8f5e9,stroke:#2e7d32
style Index fill:#fff3bf,stroke:#f59f00
style Table fill:#f3e5f5,stroke:#8e24aa
style BufferPool fill:#e0f7fa,stroke:#00838f
style Tx fill:#ffe3e3,stroke:#c62828
本来想根据我认为非常流弊的《MySQL是怎样运行的》写一篇总结,以问题引出innodb的主要设计逻辑。主要依据是书本内容,掺杂着我自己的理解。写着写着才发现即使是总结,依然需要写太多内容,所以还是拆吧。
大概由以下部分组成:
- innodb怎么存储行:Innodb - 行;
- innodb怎么存储页:Innodb - 页;
- B+树索引的构建和使用:Innodb - 索引;
- innodb怎么存储表:Innodb - 表;
- buffer pool,以及和它比较相像的虚拟内存、page cache:Innodb - Buffer Pool;
- 事务、undo、redo、mvcc、锁:Innodb - 有关事务的一切;
- 查询相关;
- 索引使用、limit使用:Innodb:索引的正确使用与拉胯的limit;
呦吼,之前还想总结成一篇,我到底是怎么想的。
本文由作者按照 CC BY 4.0 进行授权