大查询对mha切换的影响

先说结论:

     如果在线MHA切换,为了减少对系统的影响,应该先让实例只读,等待大查询结束之后,才开始切换,而更好的做法的,自动kill掉大查询,确保切换影响时间最少。

    (1)正常的MHA切换程序中,mha会调用FLUSH  NO_WRITE_TO_BINLOG TABLES这个语句;

    (2)这个时候,如果有大的查询在执行,mha就会需要等待。同事前天做了一次mha在线切换,切换的时候,当时有如下的语句正在执行:

select gpl.ID, gpl.GAME, gpl.LOGIN_ACCOUNT, gpl.PRODUCT_ID, gpl.PURCHASE_TOKEN, gpl.ORDER_ID, gpl.CO_ORDER_ID, gpl.REFUND_STATUS, p.GPID, p.TWD_MONEY, p.ORDER_TIME, gpl.DATETIME,gpl.CHARGE_TIME, p.PACKAGE_NAME, p.PAY_IP from google_play_logs gpl left join payment p on p.LOGIN_ACCOUNT = gpl.LOGIN_ACCOUNT and p.ORDER_ID = gpl.ORDER_ID where gpl.DATETIME >= '2017-09-19 00:30:02' and gpl.REFUND_STATUS = 1 order by gpl.ID desc

    (3)这个语句正常的时候,执行只需要4秒钟不到,就算没有缓存,也只需要1分多钟,而这里执行了480秒,是因为系统资源被占用,备份导致了IO忙,IO忙导致SQL语句执行效率低,从而放大了flush table的影响,导致问题的出现。

    (4)测试中能发现,flush table,只需要等待比它早开始的查询结束,flush table就能完成,并不需要等到全部查询完成。

       如下图,id 9394执行了flush table,它和time是121秒,说明它已经执行了121秒,但id 9394被阻塞了,它被id 21751线程所阻塞,进程21751在flush table之前已经开始执行,它已经执行了137秒。

       进程6333也是一个查询语句,它的状态也是waiting for table flush,但它的开始时间晚,time才87秒。

下面这个图,只有6333存在,说明21751执行完成之后,9394随之执行完成,9394不会被6333所阻塞。

      (5)再解释一下,为什么同事在ctrl+c终止了mha的切换之后,故障并没有马上恢复,那是因为ctrl+c虽然终止mha程序,但flush table其实并不能被终止,测试如下。

在这里id6333执行insert into t1(b) values ('ccc');它被阻塞了,但我们执行kill 21751,kill掉flush table,之后再通过show processlist,能看到insert into t1(b) values ('ccc')的state并没有变化,它仍然处于:Waiting for table flush 状态,

需要等到select *,sleep(30) from t1 limit 5 执行完毕,insert into t1(b) values ('ccc');才会成功执行。

原文地址:https://www.cnblogs.com/tonnyChen/p/7575376.html