如何查看实时MySQL查询?


492

我如何在Linux服务器上跟踪MySQL查询?

例如,我希望设置某种侦听器,然后请求一个网页并查看引擎执行的所有查询,或者仅查看在生产服务器上运行的所有查询。我怎样才能做到这一点?


根据问题的严重程度,我强烈建议尝试使用MySql代理。B / c可以放置在应用服务器上,a)可伸缩,b)不必影响到数据库的所有流量。它处于“ alpha”状态,但是已经存在了很长时间。dev.mysql.com/downloads/mysql-proxy
Jeff Maass 2012年

14
为什么关闭?它询问如何做X,而不是建议。近200人认为此问题有用。国防部需要冷静下来。
塞林

1
我已将这个问题改写为省略对工具的任何引用。我认为这个问题在这里非常恰当,因为“我们是否应该运行查询?” 是调试与数据库相关的问题的重要第一步。
Jeffrey Bosboom,2016年

1
@MaasSql mysql代理对使用PDO作为查询和值仅在服务器上绑定的php开发人员没有帮助。
阿南达

Answers:


298

您可以运行MySQL命令SHOW FULL PROCESSLIST;以查看在任何给定时间正在处理哪些查询,但这可能无法实现您所希望的。

获取历史记录而不必使用服务器修改每个应用程序的最佳方法可能是通过触发器。您可以设置触发器,以便每次查询运行都将查询插入某种历史记录表中,然后创建一个单独的页面来访问此信息。

请注意,这可能会大大减慢服务器上的所有内容,并INSERT在每个查询之上添加一个额外功能。


编辑:另一个选择是General Query Log,但是将其写入平面文件将消除很多灵活性,尤其是实时显示。如果您只是想要一种简单,易于实现的方式来查看正在发生的情况,则启用GQL,然后tail -f在日志文件上使用运行即可解决问题。


5
这听起来可能很愚蠢,但是我究竟该如何启用GQL?我添加了log_output = file,general_log = 1和general_log_file = / pathtofile,并添加了日志文件,访问了站点,却一无所获。我究竟做错了什么?
barfoon

我不能确定什么,但是请确保您重新启动了服务器,并且还选择了mysql具有写权限的文件。
乍得伯奇

7
我已经弄清楚了-在my.cnf中我需要的只是log = / path / to / log然后我在上面做了尾巴,它显示了所有查询。
barfoon

1
据我所知,没有办法在SELECT语句上触发任何东西。触发器仅适用于INSERT,UPDATE,DELETE ...还是误导我?
gabe。

1
我之前在同一地点。当前,我正在使用Monyog,它以较少的开销来完成所有这些操作,因此不会减慢速度。

518

您可以非常轻松地将每个查询记录到日志文件中:

mysql> SHOW VARIABLES LIKE "general_log%";

+------------------+----------------------------+
| Variable_name    | Value                      |
+------------------+----------------------------+
| general_log      | OFF                        |
| general_log_file | /var/run/mysqld/mysqld.log |
+------------------+----------------------------+

mysql> SET GLOBAL general_log = 'ON';

进行查询(在任何数据库上)。Grep或其他检查/var/run/mysqld/mysqld.log

那别忘了

mysql> SET GLOBAL general_log = 'OFF';

否则性能将直线下降,您的磁盘将满!


37
好答案!您可以tail -f -n300 /var/run/mysqld/mysqld.log用来实时跟踪日志文件
Claudio Bredfeldt

4
请注意,这些变量需要MySQL 5.1.12或更高版本。在此之前,您必须重新启动MySQL才能更改这些设置。
jlh 2013年

有什么方法可以将参数化变量写入日志?我看到了,SELECT name FROM person where id=?但我不知道是什么id
杰夫

SHOW VARIABLES没有为我工作。但是SELECT @@GLOBAL.general_log_file;效果很好。(MariaDB 10.1.9)
phil pirozhkov

1
重要 -必须使用来检查日志记录输出SHOW VARIABLES LIKE "log_output%"。如果将其设置为table,则日志将保存到数据库本身(表mysql.general_log不在文件系统中)。你可以把它改成fileSET GLOBAL log_output = 'file';
阿尔尼斯Juraga

199

即使答案已经被接受,我还是想介绍一下可能是最简单的选择:

$ mysqladmin -u bob -p -i 1 processlist

这将每秒在屏幕上显示当前查询。

  • -u 您要执行命令的mysql用户
  • -p 提示您输入密码(因此您不必将其保存在文件中或将命令显示在命令历史记录中)
  • i 时间间隔(以秒为单位)。
  • 使用该--verbose标志显示完整的进程列表,并显示每个进程的整个查询。(谢谢,nmat

可能有一个缺点:如果快速查询在您设置的时间间隔之间运行,则可能不会显示。IE:我的间隔设置为一秒钟,如果有查询需要.02几秒钟来运行并且在间隔之间运行,您将看不到它。

当您想快速检查正在运行的查询而不必设置侦听器或其他任何内容时,最好使用此选项。


11
这是最好的解决方案!
user1398287 2015年

3
我认为这种更好的解决方案是因为不必每次都使用新的mysql连接发送命令,而是打开一个mysql连接并使用它发送show进程列表。
Jose Nobile 2015年

@JoseNobile如果您在适配器中保持mysql连接处于打开状态,那并不重要。我的解决方案不完全适合OP,因为我的解决方案尚未准备好在适配器中使用。但是,这是快速简便的。
halfpastfour.am,2015年

7
您可以添加--verbose以查看完整的查询
nmat

2
这是我一直在寻找的答案。应该接受它作为答案。这也是最容易实现的答案。
乍得

51

运行此便捷的SQL查询以查看正在运行的MySQL查询。它可以在任何您喜欢的环境中运行,而无需任何代码更改或开销。它可能需要一些MySQL权限配置,但对我来说,它无需任何特殊设置即可运行。

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep';

唯一的问题是您经常会错过执行速度非常快的查询,因此它对于长时间运行的查询或MySQL服务器具有正在备份的查询最有用-以我的经验,这正是我要查看“实时”查询。

您还可以添加条件以使其仅针对任何SQL查询都更加具体。

例如,显示所有查询运行5秒或更长时间:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME >= 5;

例如,显示所有正在运行的更新:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND INFO LIKE '%UPDATE %';

有关详细信息,请参见:http : //dev.mysql.com/doc/refman/5.1/en/processlist-table.html


17

我处于一种特殊的情况下,我没有打开日志记录的权限,也没有权限查看日志是否已打开。我无法添加触发器,但确实具有调用show processlist的权限。因此,我尽了最大努力并提出了以下建议:

创建一个名为“ showsqlprocesslist”的bash脚本:

#!/bin/bash

while [ 1 -le 1 ]
do
         mysql --port=**** --protocol=tcp --password=**** --user=**** --host=**** -e "show processlist\G" | grep Info | grep -v processlist | grep -v "Info: NULL";
done

执行脚本:

./showsqlprocesslist > showsqlprocesslist.out &

尾随输出:

tail -f showsqlprocesslist.out

宾果游戏邦戈 即使它没有节流,但在运行它的机器上它只占用了2-4%的CPU。我希望这可以帮助某人。


哈!美味的。爱它。
Darth Egregious

需要一些延迟以避免过多的详细输出。请参阅我的编辑。
Slyx 2014年

@Slyx感谢您提出在循环中入睡的建议。但是,如果您正在寻找寿命短于睡眠的短命查询,则可能会错过寻找的内容。如果您真的只是在及时寻找快照,则不应循环运行。还应注意,这仍然可能会错过很短的查询。
Michael Krauklis 2014年

17

strace

查看实时MySQL / MariaDB查询的最快方法是使用调试器。在Linux上,您可以使用strace,例如:

sudo strace -e trace=read,write -s 2000 -fp $(pgrep -nf mysql) 2>&1

由于有很多转义字符,因此您可以通过在上面的命令中用管道 (只需在这两个单线之间添加)来格式化strace的输出|

grep --line-buffered -o '".\+[^"]"' | grep --line-buffered -o '[^"]*[^"]' | while read -r line; do printf "%b" $line; done | tr "\r\n" "\275\276" | tr -d "[:cntrl:]" | tr "\275\276" "\r\n"

因此,您应该可以随时查看相当干净的SQL查询,而无需接触配置文件。

显然,这不会替代启用日志的标准方法,该方法将在下面进行描述(涉及重新加载SQL Server)。

dtrace

使用MySQL探针可以查看实时MySQL查询,而无需接触服务器。示例脚本:

#!/usr/sbin/dtrace -q
pid$target::*mysql_parse*:entry /* This probe is fired when the execution enters mysql_parse */
{
     printf("Query: %s\n", copyinstr(arg1));
}

将以上脚本保存到文件(如watch.d),然后运行:

pfexec dtrace -s watch.d -p $(pgrep -x mysqld)

了解更多:DTracing MySQL入门

Gibbs MySQL小望远镜

看到这个答案

日志

以下是对开发建议有用的步骤。

将这些行添加到您的~/.my.cnf或全局中my.cnf

[mysqld]
general_log=1
general_log_file=/tmp/mysqld.log

路径:/var/log/mysqld.log/usr/local/var/log/mysqld.log也可能有效,具体取决于您的文件权限。

然后通过以下方式重新启动您的MySQL / MariaDB sudo

killall -HUP mysqld

然后检查您的日志:

tail -f /tmp/mysqld.log

完成后,更改general_log0(以便将来可以使用),然后删除文件并再次重新启动SQL Server :killall -HUP mysqld


1
如果您general_log从MySQL查询中设置,则无需杀死服务器。它将开始写入指向的文件general_log_file
罗伯特·布里西塔

15

这是我遇到的Linux Ubuntu计算机上最简单的设置。疯狂地查看所有查询。

查找并打开您的MySQL配置文件,通常是Ubuntu上的/etc/mysql/my.cnf。查找显示“日志记录和复制”的部分

#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.

log = /var/log/mysql/mysql.log

只需取消注释“ log”变量即可打开日志记录。使用以下命令重新启动MySQL:

sudo /etc/init.d/mysql restart

现在,我们准备开始监视查询的出现。打开一个新终端,然后运行此命令滚动日志文件,并在必要时调整路径。

tail -f /var/log/mysql/mysql.log

现在运行您的应用程序。您会在终端窗口中看到数据库查询开始通过。(确保在终端上启用了滚动和历史记录)

http://www.howtogeek.com/howto/database/monitor-all-sql-queries-in-mysql/


13

从命令行可以运行:

watch --interval=[your-interval-in-seconds] "mysqladmin -u root -p[your-root-pw] processlist | grep [your-db-name]"

将值[x]替换为您的值。

甚至更好:

 mysqladmin -u root -p -i 1 processlist;

1
这实际上是一个非常好的片段,可能会派上用场..谢谢!
MGP

正是我想要的!手表需要单独安装。
提洛

12

mtop


1
是的,但是很幸运在Debian或Ubuntu上安装它:bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner 2011年

设法使它在debian上运行,但由于错过了很多查询,因此它毫无价值。我可以看到查询计数器不断增加,但是很少显示任何查询。看起来它只显示耗时约1秒以上的查询。
Cobra_Fast,2012年

@Cobra_Fast在mtop Sourceforge页面上明确指出:mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete. mtop.sourceforge.net有时非常有用。
伊恩·刘易斯

7

我一直想做同样的事情,并且从各种帖子中总结了一个解决方案,还创建了一个小型控制台应用程序以输出实时查询文本,并将其写入日志文件。就我而言,这很重要,因为我将Entity Framework与MySQL配合使用,并且我需要能够检查生成的SQL。

创建日志文件的步骤(为简单起见,在此处复制了其他帖子):

  1. 编辑位于以下位置的文件:

    C:\Program Files (x86)\MySQL\MySQL Server 5.5\my.ini

    在文件底部添加“ log = development.log”。(请注意,保存此文件需要我以管理员身份运行文本编辑器)。

  2. 使用MySql工作台打开命令行,输入密码。

    运行以下命令以打开将记录所有运行查询的常规日志记录:

    SET GLOBAL general_log = 'ON';
    
    To turn off:
    
    SET GLOBAL general_log = 'OFF';

    这将导致正在运行的查询被写入以下位置的文本文件。

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. 创建/运行控制台应用程序,该应用程序将实时输出日志信息:

    可从此处下载资源

    资源:

    using System;
    using System.Configuration;
    using System.IO;
    using System.Threading;
    
    namespace LiveLogs.ConsoleApp
    {
      class Program
      {
        static void Main(string[] args)
        {
            // Console sizing can cause exceptions if you are using a 
            // small monitor. Change as required.
    
            Console.SetWindowSize(152, 58);
            Console.BufferHeight = 1500;
    
            string filePath = ConfigurationManager.AppSettings["MonitoredTextFilePath"];
    
            Console.Title = string.Format("Live Logs {0}", filePath);
    
            var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
    
            // Move to the end of the stream so we do not read in existing
            // log text, only watch for new text.
    
            fileStream.Position = fileStream.Length;
    
            StreamReader streamReader;
    
            // Commented lines are for duplicating the log output as it's written to 
            // allow verification via a diff that the contents are the same and all 
            // is being output.
    
            // var fsWrite = new FileStream(@"C:\DuplicateFile.txt", FileMode.Create);
            // var sw = new StreamWriter(fsWrite);
    
            int rowNum = 0;
    
            while (true)
            {
                streamReader = new StreamReader(fileStream);
    
                string line;
                string rowStr;
    
                while (streamReader.Peek() != -1)
                {
                    rowNum++;
    
                    line = streamReader.ReadLine();
                    rowStr = rowNum.ToString();
    
                    string output = String.Format("{0} {1}:\t{2}", rowStr.PadLeft(6, '0'), DateTime.Now.ToLongTimeString(), line);
    
                    Console.WriteLine(output);
    
                    // sw.WriteLine(output);
                }
    
                // sw.Flush();
    
                Thread.Sleep(500);
            }
        }
      }
    }

1
这看起来真的很酷,我一定会对其进行研究,非常高兴将其作为OSS项目并创建分析工具!
Rippo 2012年

我认为这是个好主意。我在Google代码上放置了SVN存储库。可能是有史以来最小的OS项目,但是到目前为止,它非常有用。我可能会扩展它,有兴趣看看是否有人将它进一步推广。code.google.com/p/livelogs
gb2d 2012年

OP需要它在他的Linux机器上工作。您的答案似乎是针对Windows计算机的。尽管此答案反映了创造力,但可能对其他人没有帮助。
halfpastfour.am 2014年

1

除了先前的描述如何启用常规日志记录的答案之外,在将任何SQL写入日志之前,我还必须在香草MySql 5.6安装中修改一个附加变量:

SET GLOBAL log_output = 'FILE';

默认设置为“无”。


0

Gibbs MySQL小望远镜

AgilData最近启动了Gibbs MySQL Scalability Advisor(一种免费的自助服务工具),允许用户捕获实时查询流,并将其上传到Gibbs。望远镜(开放源代码)将监视MySQL服务器与客户端应用程序之间的交互。无需重新配置或重新启动MySQL数据库服务器(客户端或应用程序)。

的GitHub: AgilData / gibbs-mysql-spyglass

学到更多: 用Rust捕获MySQL的数据包

安装命令:

curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash

2
Spyglass似乎需要来自已关闭服务器的API密钥,并且最后一次提交是在3年前。不确定此产品是否仍受支持/正常工作。
Dan Tenenbaum
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.