内存缓存 Buffer Pool
Buffer Pool 是在 MySQL 启动的时候,向操作系统申请的一片连续的内存空间,默认为 128MB,强烈建议任何一台 MySQL 服务器都根据自己的机器资源情况,增大配置的内存值,这玩意儿能把 MySQL 的性能提升多个数量级。
缓存池的大小
缓存池的大小由innodb_buffer_pool_size
参数来管理,一般建议大家设置成系统可用内存的 75%,但是根据我的经验,对于普通的“冷热均衡”的数据库这样是合理的,因为热数据较少,但是如果你需要在短时间内(如几天)普遍地读写几乎所有表的所有数据,那这个比例最好设置在 50% 附近,否则在运行一段时间后将会爆内存(OOM 错误),MySQL 进程会被杀掉。
缓存池的基本结构
缓存池和磁盘数据一样,分为一个又一个 16KB 的页来进行管理。除了缓存“索引页”和“数据页”,缓存池里面还有 undo 页,插入缓存、自适应哈希索引、锁信息等。
虽然缓存池已经在内存中了,但是既然缓存池是一组 16KB 的页,那它就需要一个额外的内存索引来保存每一页的表空间、页号、缓存页地址、链表节点信息,这个结构叫控制块。N 个控制块和 N 个 16KB 数据页连在一起就是 Buffer Pool 占据那一段连续内存。
引入缓存池后,数据如何读写
缓存池中的 16KB 页是和磁盘上的页一一对应的,这就带来了读写两个方向的改变:
- 读数据时,如果该页已经在内存中了,则无需再浪费一次磁盘 IO。
- 写数据时,会直接将数据写入缓存中的页(不影响之后的读取),并在成功写入 redo log 之后返回成功。同时会将该页设置为脏页,等待后台进程将数据真正写入磁盘。