在做数据库的异常诊断的时候,之前在SQL
Server上的时候,最主要的参考信息之一就是去看当前的活动Session有哪些,
这些活动Session分别在执行什么语句,用的什么执行方式(计划),运行了多久,等待资源是什么
然后利用类似这些信息对问题的诊断提供依据。
在mysql中,虽然换了数据库平台,虽然有些东西不一样,个人认为无非也就是类似这些指标
查看活动Session最常用的命令之一就是show processlist;
其结果中有一个time字段,但这个字段在某些情况下帮助不大,它并不是一个Session运行的时间,而是当前语句的运行时间
如果想到知道某个活动Session执行了多久,用show processlist是不够的。
通过一个简单的实例来说明类似请,如下是一个简单的存储过程
CREATE DEFINER=`root`@`%` PROCEDURE`test_long_run_sql`()BEGIN
--用 select sleep(10)来模拟长时间运行的过程或者SQL语句
select sleep(10);select count(1) froma;select sleep(15);delete fromtest01;END
当调用这个存储过程的时候,从另外一个Session中执行show processlist
怎么理解time字段的含义,比如在存储过程中有多个sql语句,每个语句运行的时候,都会重置show
processlist中的time。
比如这个存储过程一共会执行25秒秒,在执行select
sleep(15);的时候,至少运行了10s,为什么这里的Time是3秒?
答案是,这个3秒是第三个sql语句的执行时间,而不是整个Session(存储过程)的执行时间。
笔者之所以纠结这个问题,是刚接触MySQL(比较老的5.6)的时候,就被这个问题上猜到过坑
测试环境中,因为一个bug导致一个存储过程出现死循环,死循环的存储过程跑了两天,知道服务器很忙,
但是用show processlist的时候,根本发现不了运行了很久的Session
因为循环的原因,执行的sql语句不一样,Time不停地被重置,而且语句的源头也无从发现(call
存储过程的名称),无法得知长时间的Session。
在mysql5.7之后,新的sys库中有一个session的系统视图(前提是要打开performance_schema),
这个视图中就记录了的信息就比较完整,不但记录了当前语句的执行时间,而且还有Session级别的执行时间,
参考如下:一个statement_latency是Session级别的,一个statement_latency是语句级别的