长事务导致规格变更或小版本升级失败
场景描述
长事务导致实例规格变更失败或小版本升级失败。
原因分析
- 规格变更过程或者小版本升级由于采用滚动执行的方式,最大程度减小对客户业务的影响,因此需要做主备切换。
- 主备切换时,为了保证数据一致性,需要先把主机设置readonly后,让主备的执行事务完全一致,才进行切换。
- 当主机上有长事务时,会导致主机设置readonly超时或失败,从而导致规格变更或小版本升级失败。
解决方案
- 执行show processlist,查看正在执行的事务,使用如下命令,找到长事务。
select t.*,to_seconds(now())-to_seconds(t.trx_started) idle_time from INFORMATION_SCHEMA.INNODB_TRX t \G;
示例输出:
上述结果中idle_time是计算产生的,也是事务的持续时间。trx_mysql_thread_id是该事务的thread_id,和show processlist中的线程ID对应。
事务的trx_query是NULL,但不表示未执行事务,一个事务可能包含多个SQL,如果SQL执行完毕就不再显示。如果事务正在执行,InnoDB也无法得知该事务后续还有没有SQL以及提交时间。此时,trx_query不能提供有意义的信息,因此为NULL。
- kill长事务,再进行规格变更或小版本升级。
- 建议客户在进行规格变更或小版本升级时,避免长事务执行。