今天开发反馈在做应用双活测试时,对其中一个中心的应用节点做了kill -19
让压力流量都走另一个中心,这个过程引起了并发处理非常慢。
正常A、B两中心彼此业务应该是互不干扰的,这样在数据库才不会引起锁争用/冲突。开发反馈会有少许干扰,当A/B同时工作时只会有少量锁冲突的现象。
当对其中A中心的APP1执行了kill -19
时,流量都跑到了B中心,但交易越来越慢,现象也是TPS越来越小,从切流到B后抓取了数据库AWR,发现数据库DB TIME 90%以上都在处理enq: TX-row lock contention
,基本上都锁在了两条select for update和一条update语句上。
从这种现象可推测:
- 交易隔离没有做好
- 交易在故障时压力切换方式有问题
通过kill -19
是会让应用程序暂停,但应用下发的语句还是会一直停留在数据库中执行,且不会释放,其实数据库在处理完成后,是会一直等待将结果反馈给客户端(应用端),直到kill -18
才会释放。
暂停app1时,压力机a会选择继续往app2发压,这就会导致同样的业务交易出现在了app1和app2中,出现了大量的锁等待就不足为奇了。
这种情况下,相当于压力机a的下发交易能力直线下降,总tps下降明显也属于正常了。如果再叠加压力机a和压力机b的交易隔离不好,这种情况下会被放大,将引起进一步tps下降。
有什么方法可以解决这个问题呢?
在不改变业务逻辑的情况下,最好的办法不是暂停app服务,而是从压力机处主动切流。两个中心的交易隔离一定要做好,不然一旦出现资源锁/繁忙的情况,这种交叉一定会被放大。