如何查看实时MySQL查询?

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

例如,我想要设置某种侦听器,然后请求一个web页面并查看引擎执行的所有查询,或者只是查看在生产服务器上运行的所有查询。我该怎么做呢?

668229 次浏览

看看mtop

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

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

请注意,这可能会大大降低服务器上的一切,在每个查询之上添加额外的INSERT


编辑:另一个替代方案是常规查询日志,但将其写入平面文件将消除许多显示灵活性的可能性,特别是实时显示。如果您只是想要一种简单、易于实现的方法来查看发生了什么,那么启用GQL,然后在日志文件上运行tail -f就可以了。

我处于一种特殊的情况,我没有打开日志的权限,如果日志被打开,我也没有查看日志的权限。我不能添加触发器,但我确实有权限调用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在我运行它的盒子上。我希望这能帮助到一些人。

你可以很容易地将每个查询记录到日志文件中:

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';

执行查询(在任何db上)。Grep或其他方式检查/var/run/mysqld/mysqld.log

那就别忘了

mysql> SET GLOBAL general_log = 'OFF';

否则,性能将急剧下降,磁盘将被填满!

我一直想做同样的事情,并从各种帖子中拼凑出了一个解决方案,再加上创建了一个小的控制台应用程序来输出实时查询文本,因为它被写入日志文件。这在我的情况下是重要的,因为我使用实体框架与MySQL,我需要能够检查生成的SQL。

创建日志文件的步骤(一些其他帖子的复制,这里都是为了简单起见):

  1. 编辑位于:

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

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

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

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

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

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

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
    
  3. Create / Run a console app that will output the log information in real time:

    Source available to download here

    Source:

    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);
    }
    }
    }
    }
    

这是我所遇到的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

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

从# EYZ0

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

SET GLOBAL log_output = 'FILE';

默认设置为“NONE”。

尽管答案已经被接受,但我想提出一个可能是最简单的选择:

$ mysqladmin -u bob -p -i 1 processlist

这将每秒钟在屏幕上打印当前查询。

  • -u要执行命令的mysql用户
  • -p提示输入密码(这样你就不必保存在文件中或命令显示在你的命令历史中)
  • i间隔,以秒为单位。
  • 使用--verbose标志显示完整的进程列表,显示每个进程的整个查询。(谢谢,# EYZ1)

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

当您希望快速检查正在运行的查询而无需设置侦听器或其他任何东西时,最好使用此选项。

运行这个方便的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

你可以在命令行中运行:

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;

# EYZ0

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

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

因为有很多转义字符,你可以在上面的命令中使用格式化strace的输出 by 管道(只需在这两个一行程序之间添加|):

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服务器)。

# EYZ0

使用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 Spyglass

看看这个回答

日志

以下是对发展有用的步骤。

将这些行添加到~/.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_log更改为0(以便将来可以使用它),然后删除文件并重新启动SQL server: killall -HUP mysqld

Gibbs MySQL Spyglass

AgilData最近推出了Gibbs MySQL可伸缩性顾问(一个免费的自助服务工具),允许用户捕捉实时查询流并上传到Gibbs。小望远镜(这是开放源码)将监视您的MySQL服务器和客户端应用程序之间的交互。不需要重新配置或重新启动MySQL数据库服务器(无论是客户端还是应用程序)。

GitHub: # EYZ0

了解更多:包捕获MySQL与Rust

安装命令:

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

如果你想进行监控和统计,那么有一个很好的开源工具Percona监控和管理

但它是一个基于服务器的系统,并且它的启动不是很简单。

它还有现场演示系统用于测试。