认真学习数据库缓冲池(buffer pool)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 认真学习数据库缓冲池(buffer pool)

InnoDB存储引擎是以页为单位来管理存储空间的,我们进行的增删改查操作其实本质上都是在访问页面(包括读页面、写页面、创建新页面等操作)。而磁盘IO需要消耗的时间很多,而在内存中进行操作效率则会高很多。为了能让数据表或索引中的数据随时被我们所用,DBMS会申请占用内存来作为数据缓冲池,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。


这样做的好处是可以让磁盘活动最小化,从而减少与磁盘直接进行IO的时间。要知道,这种策略对提升SQL语句的查询性能来说至关重要。如果索引的数据在缓冲池里,那么访问的成本就会降低很多。

【1】缓冲池

首先说明一点缓冲池和查询缓存二者不是同一个东西。

① 基础介绍

在InnoDB存储引擎中有一部分数据会放到内存中,缓冲池则占了这部分内存的大部分,它用来存储各种数据的缓存,如下图所示:


83e6a5470daa4640a83f43546924a787.png


对于使用InnoDB作为存储引擎的表来说,不管是用于存储用户数据的索引(包括聚簇索引和二级索引),还是各种系统数据,都是以页的形式存放在表空间中的。而所谓的表空间只不过是InnoDB对文件系统上一个或几个实际文件的抽象,也就是说我们的数据说到底还是存储在磁盘上的。


但是磁盘的速度很慢的,缓冲池就可以帮助我们消除CPU和磁盘之间的鸿沟。所以InnoDB存储引擎在处理客户端的请求时,当需要访问某个页的数据时,就会把完整的页的数据全部加载到内存中。也就是说即使我们只需要访问一个页的一条记录,那也需要先把整个页的数据加载到内存中。将整个页加载到内存中后就可以进行读写访问了,在进行完读写访问之后并不着急把该页对应的内存空间释放掉,而是将其缓存起来,这样将来有请求再次访问该页面时,就可以省去磁盘IO的开销了。


② 缓存原则

"位置*频次"这个原则,可以帮我们对IO访问效率进行转化。


首先位置决定效率,提供缓冲池就是为了在内存中可以直接访问数据。


其次,频次决定优先级顺序。因为缓冲池的大小是有限的,比如磁盘有200G,但是内存只有16G,缓冲池大小只有1G,就无法将所有数据都加载到缓冲池里,这时就涉及到优先级顺序,会优先对使用频次高的热数据进行加载。

缓冲池的预读特性

缓冲池的作用就是提升IO效率,而我们进行读取数据的时候存在一个“局部性原理”,也就是说我们使用了一些数据,大概率还会使用它周围的一些数据。因此采用“预读”机制提前加载,可以减少未来可能的磁盘IO操作。

【2】查询缓存

查询缓存是提前把查询结果缓存起来,这样下次不需要执行就可以直接拿到结果。需要说明的是,在MySQL中的查询缓存,不是缓存查询计划,而是查询对应的结果。因为命中条件苛刻,而且只要数据表发生变化,查询缓存就会失效,因此命中率低。

缓冲池服务于数据库整体的IO操作,它们的共同点都是通过缓存的机制来提升效率。

【3】缓冲池如何读取数据?

缓冲池管理器会尽量将经常使用的数据保存起来。在数据库进行页面读操作的时候,首先会判断该页面是否在缓冲池中,如果存在就直接读取。如果不存在,就会通过内存或磁盘将页面存放到缓冲池中再进行读取。

缓存再数据库中的结构和作用如下图所示:

如果我们执行SQL语句的时候更新了缓存池中的数据,那么这些数据会马上同步到磁盘上吗?


实际上,当我们对数据库中的记录进行修改的时候。首先会修改缓冲池中页里面的记录信息,然后数据库会以一定的频率刷新到磁盘上。


注意并不是每次发生更新操作,都会立刻进行磁盘回写。缓冲池会采用一种叫做 checkpoint的机制 将数据回写到磁盘上,这样做的好处就是提升了数据库的整体性能。


比如,当缓冲池不够用时,需要释放掉一些不常用的页,此时就可以强行采用checkpoint的方式,将不常用的脏页回写到磁盘上,然后再从缓冲池中将这些页释放掉。这里脏页(dirty page)指的是缓冲池中被修改过的页,与磁盘上的数据页不一致。

【4】查看/设置缓冲池大小

如果你使用的是MySQL MyISAM存储引擎,它只缓存索引,不缓存数据,对应的键缓存参数为 key_buffer_size,你可以用它进行查看。


如果你使用的是InnoDB存储引擎,可以通过查看 innodb_buffer_pool_size 变量来查看缓冲池的大小。命令如下:

show variables like 'innodb_buffer_pool_size'

8178e3734e5b40b19e27934691fad0ff.png

你能看到此时InnoDB的缓冲池大小只有134217728/1024/1024=128MB 。我们可以修改缓冲池大小,比如改为256MB,方法如下:

# 这种方式,重启mysql将失效,最好配置在my.cnf中
set global innodb_buffer_pool_size=268435456;

配置文件比如:

[server]
innodb_buffer_pool_size=268435456

【5】多个Buffer Pool实例

Buffer Pool本质是InnoDB向操作系统申请的一块连续的内存空间,在多线程环境下,访问Buffer Pool中的数据都需要加锁处理。在Buffer Pool特别大而且多线程并发访问特别高的情况下,单一的Buffer Pool可能会影响请求的处理速度。


所以在Buffer Pool特别大的时候,我们可以把它们拆分成若干个小的Buffer Pool,每个Buffer Pool都称为一个实例,它们都是独立的。将会独立的去申请内存空间,独立的管理各种链表。从而在多线程并发访问时并不会相互影响,提高并发处理能力。


我们可以在服务器启动的时候通过设置 innodb_buffer_pool_instances 的值来修改Buffer Pool实例的个数。

# 查看当前实例个数
show variables like 'innodb_buffer_pool_instances'
# my.cnf
[server]
innodb_buffer_pool_instances=2

每个Buffer Pool实例实际占用内存可以用如下公式计算:

innodb_buffer_pool_size/innodb_buffer_pool_instances

不是说Buffer Pool实例创建的越多越好,分别管理各个Buffer Pool也是需要性能开销的,InnoDB规定:当innodb_buffer_pool_size的值小于1G的时候设置多个实例是无效的,InnoDB会默认把innodb_buffer_pool_instances的值修改为1。鼓励在Buffer Pool大于或等于1G的时候设置多个Buffer Pool实例。

【6】更新数据流程

当我们查询数据的时候,会先去Buffer Pool中查询,如果Buffer Pool中不存在,存储引擎会先将数据从磁盘加载到Buffer Pool中,然后将数据返回给客户端。


同理,当我们更新某个数据的时候,如果这个数据不存在于Buffer Pool,同样会先将数据加载进来,然后修改内存的数据。被修改过的数据会在之后统一回刷入磁盘。



2a3f09f8be3346d98b91d9ab314a08bf.png

个过程实际是有问题的。比如我们修改Buffer Pool中的数据成功但是还没有来得及将数据刷入 磁盘MySQL就挂了怎么办?按照上图的逻辑,此时更新之后的数据只存在于Buffer Pool中,如果此时MySQL宕机了,这部分数据将会永久地丢失。


或者,更新到一半突然发生错误了,想要回滚到更新之前的版本怎么办?如果数据持久化、事务回滚都做不到,那么更遑论崩溃恢复了。

.

这里就要涉及到Redo Log和Undo Log了。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1天前
|
SQL 存储 关系型数据库
【MySQL 数据库】11、学习 MySQL 中的【锁】
【MySQL 数据库】11、学习 MySQL 中的【锁】
86 0
|
1天前
|
存储 人工智能 Cloud Native
阿里云瑶池数据库训练营权益:《玩转Lindorm》学习资料开放下载!
阿里云瑶池数据库训练营权益:《玩转Lindorm》学习资料开放下载!
|
1天前
|
存储 关系型数据库 MySQL
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
189 0
|
1天前
|
SQL 关系型数据库 MySQL
【MySQL 数据库】4、MySQL 事务学习
【MySQL 数据库】4、MySQL 事务学习
50 0
|
1天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:深入学习数据库表管理,创建、修改、约束、建议与性能优化(3)
轻松入门MySQL:深入学习数据库表管理,创建、修改、约束、建议与性能优化(3)
|
1天前
|
数据库
sqlserver数据库学习感悟(1)----关于group by
sqlserver数据库学习感悟(1)----关于group by
5 0
|
1天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
ava从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
|
1天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
1天前
|
SQL 关系型数据库 数据库
数据库学习
数据库学习涵盖基础概念、类型(如关系型与NoSQL)、设计、安全和应用。理解数据组织、DBMS功能,掌握SQL语言至关重要。实践中,探索不同数据库系统,确保数据安全,参与实际项目,利用教程资源,能提升数据库管理和应用能力。
18 7
|
1天前
|
SQL 存储 NoSQL
数据库基础学习思路
数据库设计是根据用户的需求,在某一具体的数据库管理系统上,设计数据库的结构和建立数据库的过程。设计过程中需要遵循一些原则,如一对一设计、独特命名、双向使用等,以减少数据冗杂,维护数据一致性。
29 2
http://www.vxiaotou.com