加锁:
Mysql线程池接受到多个网络请求之后,给每个请求分配一个线程去执行,那么多个线程就会同时去操作Buffer Pool,Buffer Pool中有很多共享的数据结构,比如缓存页、各种链表之类的,所以需要要进行加锁。
让一个线程加锁,先完成一系列的操作,比如说加载数据页到缓存页,更新free链表,更新lru链表,然后释放锁,接着下一个线程再执行一系列的操作。
加锁后的性能情况:
即使一个Buffer Pool,即使多个线程会加锁串行着排队执行,性能也差不到哪儿去,因为大部分情况下,每个线程都是查询或者更新缓存页里的数据,这个操作发生在内存里,微秒级的,包括更新free、flush、lru这些链表,也都是指针操作,性能也是很高的。但是有可能要从磁盘里读取数据页加载到缓存页里去,发生了一次磁盘IO,就会耗时多一些。
使用多Buffer Pool可以优化并发能力:
如果给Buffer Pool分配的内存小于1GB,那么最多只会给你一个Buffer Pool,但是如果给Buffer Pool分配了8GB,那么可以通过配置innodb_buffer_pool_instatnces=4,设置4个Buffer Pool,每个Buffer Pool就是2GB。
每个Buffer Pool负责管理一部分的缓存页和描述数据块,有自己独立的free、flush、lru等链表。
可以做到分散请求压力,有的线程访问这个buffer pool,有的线程访问那个buffer pool。多并发访问性能就会得到成倍的提升!(思想是和分段锁的思想一样的)
chunk机制:
buffer pool是由很多chunk组成的,chunk的大小由innodb_buffer_pool_chunk_size参数控制,默认值为128M。Chunk存储的是缓存页、描述数据块。一个buffer pool中的所有chunk共享一套free、flush、lru等链表。
Chunk机制如何支持运行期间调整buffer pool大小:
申请一系列的128M的chunk,每个chunk的内存需要是连续的,然后把申请到的chunk分配给buffer pool。
有了这个chunk机制,此时并不需要去额外申请整个buffer pool需要的连续内存空间,然后还要把已有的数据进行拷贝。
思考:正是因为有了chunk机制,buffer pool的内存大小调整更为灵活了,而且可以做到运行期间动态调整。
如何避免你执行crud的时候,频繁的发现缓存页用完了,此时还得先把一个缓存页刷入磁盘腾出一个空闲缓存页,然后才能从磁盘读取一个自己需要的数据页到缓存页,需要两次磁盘IO,影响性能,降低并发。
本质上缓存页一边被你使用,一边会被后台IO线程定时释放掉一批,刷入磁盘。
如果并发比较高,缓存页使用得很快,后台IO线程释放缓存页得速度很慢,那么必然导致你频繁地发现缓存页已用完。
如果根据系统并发,加快后台IO线程释放缓存页的速度的话,磁盘IO过于频繁,也会影响数据库的性能。
所以关键点就在于Buffer Pool有多大:如果你的数据库要抗高并发的访问,需要给Buffer Pool设置很大的内存空间,通过增加Buffer Pool的空间,增大缓存页的数量,降低crud的时候发现没有缓存页的频率;而且一旦数据库访问高峰过去,后台IO线程在不断地释放缓存页,那么空闲地缓存页的数量又会在数据库访问低谷期的时候慢慢地增加了。
如何基于机器配置合理设置Buffer Pool
首先看机器内存,因为操作系统本身、其他应用需要占用内存,一般将Buffer Pool大小设置为机器内存地50%~60%。
buffer pool总大小 = (chunk大小 * buffer pool数量)的倍数
为什么会有这样的规定呢?你想啊,为了避免内存碎片,你的buffer pool总大小应该是chunk大小的倍数吧,然后buffer pool总大小又是每个个buffer pool的倍数。所以应该是他们两个的公倍数。
比如默认的chunk大小是128M,此时你的机器内存是32GB,你打算给buffer pool分配总内存20GB,假设你设置32个buffer pool,那么此时,buffer pool总大小(20GB)= chunk大小(128MB)*32)的5倍。
那么此时每个buffer pool的大小是640MB,每个buffer pool包含5个128M的chunk。
思考:那为什么要每个buffer pool要一样大呢?
当数据库启动之后,可以通过上诉命令,去查看当前innodb里的一些具体情况,可以看到buffer pool相关的东西。
Mysql内部架构_jerry_dyy的博客-CSDN博客
Mysql存储模型_jerry_dyy的博客-CSDN博客
InnoDB内部架构_jerry_dyy的博客-CSDN博客
Buffer Pool 核心原理_jerry_dyy的博客-CSDN博客
Buffer Pool生产实践_jerry_dyy的博客-CSDN博客
Mysql事务隔离机制_jerry_dyy的博客-CSDN博客
Mysql的锁机制_jerry_dyy的博客-CSDN博客
Mysql的索引深度讲解_jerry_dyy的博客-CSDN博客
Mysql索引的使用_jerry_dyy的博客-CSDN博客
SQL语句的执行计划_jerry_dyy的博客-CSDN博客_sql语句的执行计划