DDL期间TDSQL异常会话查询造成数据库主备切换
问题描述:
7*24联机交易系统,傍晚时分,从客户端后台对3千万行的大表执行缩短varchar类型字段长度的ddl语句,执行期间,为了查看ddl进度,从TDSQL-MySQL赤兔前端页面点击异常会话查询,之后数据库卡住,发生主备切换,主备切换后的几分钟内数据库交易耗时上升。
问题分析:
查看tdsql记录的processlist的日志,发现ddl语句之后,就是对performance_schema.data_locks试图的查询语句,其余sql语句都阻塞在该data_locks查询sql后面。点击查看主备切换原因,是因为心跳检测中断时间超过20s,数据库误以为主库挂掉,发起主备切换。
原因总结:
从客户端后台执行ddl语句时,会对全表加行锁,由于该实例为分布式实例,每一个set行数为500万行左右。在TDSQL-MySQL赤兔前端页面点击异常会话查询,会使用到performance_schema.data_locks视图,查询data_locks视图时,首先需要获取trx_sys->mutex这个信号量,获取到trx_sys->mutex后扫描trx_sys结构下面trx_lock_list和mysql_lock_list两个记录锁信息的双向链表,当扫描到执行ddl语句的表的锁信息时,要等把这个表的所有行锁信息扫描完后才会释放trx_sys->mutex互斥量,扫描时间过长造成trx_sys->mutex长时间未释放。其他dml语句在执行时,也需要申请trx_sys->mutex互斥量,向trx_sys结构中的事务链表注册一个事务。但data_locks视图异常会话持有的trx_sys->mutex长时间未释放,使得其余dml语句获取不到trx_sys->mutex被阻塞,这其中就包括心跳检测的dml语句,心跳检测sql中断超过20s,TDSQL数据库认为主库挂掉,发起主备切换。
解决方案:
1、执行ddl时,避开业务高峰期。
2、从赤兔前端执行ddl操作,使用到pt工具执行online ddl。
3、执行ddl语句时,谨慎使用异常会话查询功能。