MGR多主环境的故障简单分析

这是学习笔记的第 1911 篇文章


  今天晚上的时候,突然发现我们的运维系统不可访问了,最开始以为是网络的问题,查看后端没有报错,依然有业务输出日志。怀疑是网络的访问导致,重启了应用服务,依然访问失败,接着查看数据库端,让人担心的事情还是发生了,数据库里面有大量的线程,还是大多数都处于阻塞状态。

640?wx_fmt=png

这是一套基于MGR的多主环境,目前存在两个节点,都是可写的。初步分析这个问题,是由于事务的阻塞导致的,而且应该属于连锁反应。

那么看起来只要kill掉阻塞线程即可,但是查看已有的线程都是清一色的commit,所以为了尽快恢复业务,我们选择先kill掉这些线程,先选择kill了一小部分,没想到马上得到了应用的回复,连接数直线上升,原来还是400多个,现在成了600多个,马上数据库就无法连接了,应用端完全阻塞,而另外一个节点却没有丝毫的变化,线程数都正常。

情况类似下图所示:

640?wx_fmt=png

显然问题升级了,这个时候查看当前的锁情况,通过sys schema得到了一些线索。

>select *from innodb_lock_waits \G

*************************** 1. row ***************************

                wait_started: 2019-03-07 20:12:22

                    wait_age: 00:00:20

               wait_age_secs: 20

                locked_table: `devopsdb`.`xxxx_backup_rs`

                locked_index: PRIMARY

                 locked_type: RECORD

              waiting_trx_id: 2295941

         waiting_trx_started: 2019-03-07 20:12:22

             waiting_trx_age: 00:00:20

     waiting_trx_rows_locked: 1

   waiting_trx_rows_modified: 0

                 waiting_pid: 113071

  waiting_query: insert into `xxxx_backup_ ... name`=values(`physeevicename`)

             waiting_lock_id: 2295941:587:59498:85

           waiting_lock_mode: X

             blocking_trx_id: 2295230

                blocking_pid: 111437

              blocking_query: commit

            blocking_lock_id: 2295230:587:59498:85

          blocking_lock_mode: X

        blocking_trx_started: 2019-03-07 19:06:29

            blocking_trx_age: 01:06:13

    blocking_trx_rows_locked: 3

  blocking_trx_rows_modified: 3

     sql_kill_blocking_query: KILL QUERY 111437

sql_kill_blocking_connection: KILL 111437

1 row in set, 3 warnings (0.01 sec)

可以看到是在2019-03-07 19:06:29的一个事务,相关SQL是insert语句,在commit的时候突然阻塞了,这个阻塞导致了后续的操作都产生了堆积。

那么111437是哪个线程呢,我们简单定位发现是另外一个服务器发起的数据请求。

| 111437 | dev_trans_rwl        | xxxx:63077 | devopsdb | Query   |   2837 | starting                                               | commit      

简单来看insert是无辜的,因为它的逻辑很简单,但是一定是碰到了其他的因素,而经过一番排查发下,这个原因就是delete,这个操作的瓶颈就在于delete语句,其中表数据有500万,但是delete的逻辑是没有指定索引,也就意味着是全表扫描了,所以这种情况下在事务中是很可能导致阻塞的。

kill了线程之后也没有奏效,那些线程都标识为KILLED的,但是没有释放。

这种情况下,flush相关的操作也会hang住,所以果断对当前数据库做重启恢复。

       整个过程持续了几分钟,最后数据库启动后,发现一个奇怪的问题,那就是IDC2-MGR 的节点也退出了集群。也就意味着没有了高可用保护。

最后我们重新在IDC1-MGR启动集群然后加入IDC2-MGR节点。        

        对于这个问题我们通过日志的初步分析是IDC1-MGR节点存在大事无阻塞,没有提交导致数据变更没有同步到IDC2-MGR,这样超过一定阈值之后,IDC1-MGR节点停止推出集群后,IDC2-MGR为了保证集群的稳定,也停止了GR复制,听起来好像不是很顺。主要还是基于数据的完整性保护,我们后续做了测试,对运行平稳,写入正常的环境重启IDC2-MGR,多主环境是正常的,可以提供持续性访问。

对于2个MGR节点如此,其实从分布式的角度来说,对于3个节点也是类似的。如下图所示:

640?wx_fmt=png

如果数据变更的压力都是IDC1-MGR,如果数据变化都难以同步到IDC2-MGR,IDC3-MGR,那么这个过程中从分布式协议的算法来说,这是属于异常情况,而为了保持集群的稳定,是需要剔除IDC1-MGR的。



相关链接:

MGR从单主模式向多主模式的迭代演进



640?


猜你喜欢

转载自blog.csdn.net/weixin_36250635/article/details/88325016
MGR