Buffer Pool的本质
Buffer Pool其实本质就是一大块内存数据结构,由一大堆的缓存页和描述数据块组成的,然后加上了各种链表(free、flush、lru)来辅助他的运行
Buffer Pool在访问的时候需要加锁吗
多线程并发访问一个Buffer Pool,必然是要加锁的,然后让一个线程先完成一系列的操作,比如说加载数据页到
缓存页,更新free链表,更新lru链表,然后释放锁,接着下一个线程再执行一系列的操作
多线程并发访问加锁,数据库的性能还能好吗
每个线程都是查询或者更新缓存页里的数据,这个操作是发生在内存里的,基本都是微秒级的,
很快很快,包括更新free、flush、lru这些链表,他因为都是基于链表进行一些指针操作,性能也是极高的
所以即使每个线程排队加锁,然后执行一系列操作,数据库的性能倒也是还可以的
MySQL的生产优化经验:多个Buffer Pool优化并发能力
MySQL默认的规则是,如果你给Buffer Pool分配的内存小于1GB,那么最多就只会给你一个Buffer Pool
一旦你有了多个buffer pool之后(每个都独立的一套机制free、flush、lru),你的多线程并发访问的性能就会得到成倍的提升,因为多个线程可以在不同的buffer pool中加锁和执行自己的操作,大家可以并发来执行了
所以这个在实际生产环境中,设置多个buffer pool来优化高并发访问性能,是mysql一个很重要的优化技巧。
如何通过chunk来支持数据库运行期间的Buffer Pool动态调整
buffer pool这种大块头,能在运行期间动态调整大小吗
不能,
如果实现的话,需要这个时候向操作系统申请一块新的16GB的连续内存,然后把现在的buffer pool中的所有缓存页、描述数据块、各种链表,都拷贝到新的16GB的内存中去。这个过程是极为耗时的,性能很低下,是不可以接受的
如何基于chunk机制把buffer pool给拆小呢
MySQL自然会想办法去做一些优化的,他实际上设计了一个chunk机制,也就是说buffer pool是由很多chunk组
成的,他的大小是innodb_buffer_pool_chunk_size参数控制的,默认值就是128MB
然后每个buffer pool里的每个chunk里就是一系列的描述数据块和缓存页,每个buffer pool里的多个chunk共享一套free、flush、lru这些链表
基于chunk机制是如何支持运行期间,动态调整buffer pool大小的
比如我们buffer pool现在总大小是8GB,现在要动态加到16GB,那么此时只要申请一系列的128MB大小的chunk就可以了,只要每个chunk是连续的128MB内存就行了。然后把这些申请到的chunk内存分配给buffer pool就行了
