1 访问Buffer Pool时需要加锁吗?
对MySQL执行CRUD的第一步,就是利用BP里的缓存来更新或查询。
假设MySQL同时接收到了多个请求,他自然会用多线程处理,那这多线程就可能会同时访问BP,即同时操作里面的缓存页,同时操作一个free链表、flush链表、lru链表。现在多线程来并发的访问这个BP,此时他们都是在访问内存里的一些共享数据结构,如缓存页、各种链表,必要加锁,然后让一个线程先完成一系列操作,比如说加载数据页到缓存页,更新free、lru链表,然后释放锁,接着下个线程再执行操作。
2 多线程并发访问加锁,DB性能还能好?
即使就一个BP,多个线程会加锁串行执行,性能也差不到哪。因为大部分情况下,每个线程都是查询或更新缓存页数据,基本都是微秒级,包括更新free、flush、lru这些链表都是基于链表的指针操作,性能也极高。
所以即使每个线程排队加锁,然后执行一系列操作,数据库性也还可以。
但毕竟也是每个线程加锁,然后排队一个个操作,有时你的线程拿到锁后,他可能要从磁盘里读取数据页加载到缓存页,这还发生了一次磁盘I/O!所以他要是进行磁盘IO的话,耗时就会多些,后面排队等的线程就得多等会了!
3 多BP实例设置
可以给MySQL设置多个BP来优化其并发能力。MySQL默认规则,若你给BP分配的内存小于1G,那最多就只能给你一个BP。
但若你的机器内存很大,那你必然会给BP分配大内存,比如8G,那此时你可设置多个BP:
[server]
innodb_buffer_pool_size = 8589934592
innodb_buffer_pool_instances = 4
给BP设置8G总内存,有4个BP,即每个BP 2G。这时,MySQL运行时就有4个BP了!
多线程并发访问时,压力就分散了,这就是分段锁的思想。