[MySQL 5.6] Innodb并发控制改进

从5.6开始,如果使用了GCC Build-in的原子操作,在进入Innodb层的线程并发控制走与之前不同的逻辑,5.5也可以调用通过原子操作进行并发控制的逻辑,但需要打开只读选项innodb_thread_concurrency_timer_based来控制.


quoted code in 5.6:
function srv_conc_enter_innodb:

ifdef HAVE_ATOMIC_BUILTINS
    srv_conc_enter_innodb_with_atomics(trx);
#else
    srv_conc_enter_innodb_without_atomics(trx);
#endif /* HAVE_ATOMIC_BUILTINS */
srv_conc_enter_innodb_without_atomics是MySQL5.5的调用逻辑,在5.6中开始默认编译情况下,调用srv_conc_enter_innodb_with_atomics逻辑,其不同之处在于使用GCC Build-in的原子操作,来避免热点锁srv_conc_mutex的频繁加锁/释放。

与5.5不同的是,在5.6中采用了一种称为adaptive sleep的方法,来替代5.5使用的直接sleep固定时间的方式。这样Innodb可以根据系统的负载做一些自适应调整。新增一个参数innodb_adaptive_max_sleep_delay(文档见http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_adaptive_max_sleep_delay ),文档的表述有误,已report bug list(http://bugs.mysql.com/bug.php?id=68594)

原先的做法是在进入Innodb层前,先查看当前在Innodb中活跃的线程数是否超过innodb_thread_concurrency; 如果超过了,则sleep一段时间,再重试,如果还是超过并发限制时,就给其分配一个slot,让其进入信号量等待。

在5.6中,当使用原子操作进行并发控制时,如果innodb_adaptive_max_sleep_delay大于0, 会对另外一个参数innodb_thread_sleep_delay的值做自适应调整.它的逻辑也很简单。
我们这里假定innodb_adaptive_max_sleep_delay的值大于0 

当线程能够进入Innodb层时:
a.如果当前线程之前sleep过一次,并且当前innodb_thread_sleep_delay>20,将innodb_thread_sleep_delay减1
b.如果当前没有等待的线程,将innodb_thread_sleep_delay除以2

如果线程目前因并发控制无法进入Innodb层:
a.如果当前innodb_thread_sleep_delay>innodb_adaptive_max_sleep_delay
,将innodb_thread_sleep_delay的值设置为innodb_adaptive_max_sleep_delay
b.sleep  innodb_thread_sleep_delay毫秒

c.如果该线程已经sleep了超过1次,将innodb_thread_sleep_delay++

可以看到innodb_thread_sleep_delay降低比增加的更快。这样在并发线程数很高时,当限制并发数早就达到,其他线程的每次sleep时间会缓慢拉长。而当Innodb层很空闲时,sleep时间又会快速降到非常低

调整sleep到一个优化值的目的是,过小的sleep值可能会产生太多的线程切换,但过长的sleep时间,在并发比较空闲的时候又会影响性能。新的并发控制策略有利于随着负载的变化而做自适应调整。

另外注意,在使用原子操作进行并发控制后,就再也没有使用信号量让线程进行等待了。

这种自适应调整策略的效率依然有待于评估,也不确定其对某些工作负载是否存在不利影响。合适的参数配置应当由性能测试来给出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值