(1)案例背景:
当时有人删除了千万级的数据,结果导致了频繁的查询,当时从线上收到大量的慢查询告警开始的,当收到大量的慢查询告警后,就去检查慢查询的SQL,结果发现不是特别的SQL,这些SQL语句主要都是针对一个表的,同时比较简单,而且基本都是单行查询,看起来似乎不应该会慢查询,所以这个时候感觉极为奇怪,因为SQL本身完全不应该有慢查询,按说那种SQL语句,基本上都是直接索引查找出来的,性能应该是极高的。
那么有没有另外一种可能,慢查询不是SQL的问题,而是MySQL生产服务器的问题呢?这里给大家解释下,实际上个别特殊情况,MySQL慢查询并不是SQL语句问题,而是自己生产服务器的负载太高了,导致SQL语句执行很慢。举个例子,比如现在MySQL服务器的磁盘IO负载特别高,也就是每秒执行大量的高负载的随机IO,但是磁盘本身每秒执行的随机IO是有限的。
结果,就导致正常的SQL语句去磁盘上执行的时候,如果要跑一些随机IO,磁盘太繁忙导致本来一个很快的SQL,要等很久才能执行完毕,这个时候就可能导致正常SQL语句变成慢查询。所以同理,除了磁盘之外,还有一个例子就是网络,也许网络负载很高,就可能导致一个SQL语句要发送到MySQL上去,光是等待获取一个跟MySQL的连接都很难,或者说MySQL自己网络负载太高,带宽打满后一个SQL也许执行很快,但是他查出来的数据返回给你,网络都送不出去,此时也会变成慢查询。
另外一个关键的点就是CPU负载,如果说CPU负载过高的话,也会导致CPU过于频繁去执行别的任何,没时间执行这个SQL语句,此时也可能导致SQL语句出现问题,所以慢查询本身不一定是SQL导致的,如果觉得SQL不应该慢,结果那个时间段跑这个SQL就是慢,此时应该排查下当时MySQL服务器的负载,尤其是看看磁盘,网络以及CPU负载,是否正常。
如果发现那个时间段MySQL生产服务器的磁盘,网路或CPU负载特别高,那么可能是服务器负载导致的问题。
(2)例子:
举个例子,之前解决过一个典型的问题,就是当某个离线作业瞬间大批量把数据往MySQL里灌入的时候,他一瞬间服务器磁盘,网络以及CPU的负载会超高。此时一个正常的SQL执行下去,短时间内
一定会慢查询,针对类似的问题,优化手段更多的是控制导致MySQL负载过高的那些行为,比如大量灌入数据,最好在凌晨低峰期灌入,别影响线上系统运行。
结果奇怪的是,当时我们看了MySQL服务器
的磁盘,网路,cpu负载,一切正常,似乎也不是这个问题导致的。案例的排查过程是极为漫长的,涉及到MySQL大量的调优知识,最终解决这个问题,甚至要深入之前讲过的,MySQL内核级原理,才能
分析清楚以及解决问题。
(3)总结:
今天我们站在当时的角度,头两步的排查手段,一个是检查SQL是否有问题,主要是看他的执行计划,另一个是检查MySQL服务器的负载,那么在这两种方法都不奏效的情况下,就用到了
排查问题的第三步,就是用 MySQL profiling工具去细致的分析SQL语句的执行过程和耗时。 profiling: 剖析
知识点:开始mysql慢查询配置,
知识点:RR下快照读通过MVCC机制不会存在幻读,在当前读时通过间隙锁来锁住查询的区间防止其他事务插入数据或者删除区间的数据。
知识点:
快照读解决幻读原理是 你插入我也不读,但是某些场景下需要当前读,这时候就不能用快照了,也就是说不能用mvcc解决幻读了,就会加间隙锁,
直接锁住不让你插入,既然不会插入
就不会有幻读了。