暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

MySQL中如何查看正在执行的SQL语句?

一森咖记 2020-02-03
12205


【此为"一森咖记"公众号——第126篇文章】

读完需要

10
分钟

速读仅需5分钟

【引言】

如何在MySQL中查看正在执行的SQL语句有哪些,今天念叨下这件事。

 

大家都知道,linux环境中很容易通过操作系统top看到执行时间长的进程pid号,根据pid号,再通过oracle的视图v$sessionv$processv$sqltext追到到执行sid,从而查到具体的sql语句。

 

示例如下:

SQL语句

    SELECT /*+ ORDERED */
    Sid,
    event,
    p1,
    p2,
    p3
    FROM v$session_wait a
    WHERE a.sid IN (SELECT b.sid
    FROM v$session b
    WHERE b.paddr = (SELECT addr
    FROM v$process c
    WHERE c.spid = '3128'));

    SQL语句2

      SELECT /*+ ORDERED */
      sql_id, sql_text
      FROM v$sqltext a
      WHERE sql_id IN (SELECT NVL (SQL_ID, PREV_SQL_ID)
      FROM v$session b
      WHERE b.sid = '151')
      ORDER BY piece ASC;

      其中SQL语句1中标红部分为top命令查到pid号,SQL语句2中的标红部分为根据SQL语句1查到的SQL语句的SID

       

      那在如何在MySQL中查看正在执行的SQL语句?

       

      有2个方法:

      方法1:

      使用show processlist,但该方法有个弊端,只能查看正在执行的sql语句,对应历史记录,查看不到,好处是简单便捷。

      1.mysql的bin目录下使用 mysqladmin processlist;

      2.mysql> show processlist;

      如果SUPER权限,可看到全部的线程;否则,只可看到自己发起的线程(当前对应的MySQL帐户运行的线程)。

      示例:

        mysql> show processlist;
        +---------+-------------+----------------------+-----------------------+-------------+----------+---------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
        | Id | User | Host | db | Command | Time | State | Info |
        +---------+-------------+----------------------+-----------------------+-------------+----------+---------------------------------------------------------------+------------------------------------------------------------------------------------------------------+
        | 7568614 | ethan_app | 192.168.10.69:51420 | ethan_geo_yl | Sleep | 3 | | NULL |
        | 7568681 | root | 192.168.10.57:57520 | ethan_opt_yl | Sleep | 5 | | NULL |
        | 7569751 | ethan_app | 192.168.10.56:49702 | ethan_geo_yl | Query | 14 | Searching rows for update | update message_info set VAL_STATUS = '1' where TXT_DEVICETOKEN = '5ea335368ea17428a1cf1bd96d9f19aff1 |
        | 7569759 | ethan_app | 192.168.10.56:49741 | ethan_geo_yl | Sleep | 30 | | NULL


        从上述语句可以看出,info中能显示执行的SQL的类型,但看不到具体的执行SQL

        如何查看具体的SQL,怎么破?


        方式2通过查看information_schema.`PROCESSLIST`

        可以用具体的SQL语句进行查看,通过where条件过滤把不相关的信息过滤掉。

        具体语句如下:

          mysql> select * from information_schema.`PROCESSLIST` where info is not null ORDER BY time desc;

          这里有必要介绍下processlist各列的含义和用途:

          1id列:用户登录mysql时,系统分配的"connection_id",可以使用函数connection_id()查看kill一个语句时会用到,语句为:kill idMySQLid相当于OraclesidSERIAL#

          2user列:显示当前用户。如果不是root命令就只显示用户权限范围的sql语句

          3host列:显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户4db列:显示这个进程目前连接的是哪个数据库

          5command列:显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等

          6time列:显示这个状态持续的时间,单位是秒

          7state列:显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个sql语句,已查询为例,可能需要经过copying to tmp tableSorting resultSending data等状态才可以完成

          8info列:显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。

           

          上述两种方式,刚才也提到过只能查看正在执行的sql语句,对应历史记录,查看不到

          怎么办?


          答:开启日志模式


          设置开启

          SET GLOBAL log_output = 'TABLE';  

          SET GLOBAL general_log = 'ON';

           

          设置关闭

          SET GLOBAL log_output = 'TABLE';  

          SET GLOBAL general_log = 'OFF';

           

          查询具体sql

          SELECT * from mysql.general_log ORDER BY   event_time DESC

           

          清空表

          不允许使用delete删除mysql.general_log ,只能用truncate

          truncate table mysql.general_log;

          但,如果想查看执行时间长的sql,可开启慢日志查询。

          首先查询慢日志是否开启:

            mysql> show variables like 'slow_query_log';
            +----------------+-------+
            | Variable_name | Value |
            +----------------+-------+
            |slow_query_log | OFF | 
            +----------------+-------+
            1 row in set (0.00 sec)

             

            慢日志查询没有开启开启如下,找到my.cnf,添加如下内容

             

            # 添加慢查询日志

            log_output=file

            slow_query_log=on

            slow_query_log_file = tmp/mysql-slow.log

            log_queries_not_using_indexes=on

            long_query_time = 1

             

            重启mysql。

              mysql> show variables like 'slow_query_log';
              +----------------+-------+
              | Variable_name | Value |
              +----------------+-------+
              | slow_query_log | ON |
              +----------------+-------+
              1 row in set (0.00 sec)


              注意:

              如果更改日志目录位置

              如更改为/home/msyql/log/mysql-slow.log至少需要将log目录所有者设置为mysql:mysql。重启mysql时,才能自动生成mysql-slow.log文件;否则将无法生成日志文件,mysql用户无权写入数据。


              【参考】

              http://dev.mysql.com/doc/refman/5.0/en/general-thread-states.html

               


              以下为个人公众号“一森咖记”,欢迎关注。

                                     

                 

              近期热文

              你可能也会对以下话题感兴趣。点击链接便可查看。




              最后修改时间:2020-02-03 10:07:25
              文章转载自一森咖记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论