版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明。否则将追究法律责任。http://blog.csdn.net/mayongzhan - 马永占,myz,mayongzhan
原文地址:http://blog.thinkphp.de/archives/303-Observing-the-MySQL-Query-Log.html
调试现有的应用程序是很困难的。有时候,只是想要得到程序执行的数据库操作是否已经发送到数据库。可以使用MySQL查询日志,不幸的是, MySQL查询日志不直接告诉使用者查询到哪些数据库。
我要得到最近几条程序执行的查询。因为这个程序不是这个数据库唯一的程序,而且MySQL查询记录不支持过滤,我使用一个awk的脚本来自己进行过滤。我做了一些格式化,以便能更好的阅读。
MySQL查询记录格式如下:
080228 15:27:50 1170 Connect user@host on database_name
1170 Query SET NAMES "utf8"
1170 Query SELECT something FROM sometable WHERE some=thing
1170 Quit
我们需要过滤出Connect那行的含有我定义的数据库名称的那组结果。当然还要对SELECT进行一下格式化。
我的awk脚本:
BEGIN {
mydb = "default_database";
if (ARGC == 2 && substr(ARGV[1],0,3)=="db=") {
mydb = substr(ARGV[1],4);
printf("my db %s\n",mydb);
}
}
/[0-9]* Connect/ {
if(index($0,mydb)==0) {
#printf("not using %s\n",$0);
} else {
if($2 == "Connect") {
what=$1;
} else {
what=$3;
}
print;
conns[what]="true";
}
}
/[0-9]* Query/ {
if(conns[$1]=="true") {
printf("% 4s %s : ",$1,$2);
for(i=3; i<=NF; i++){
if ($i == "FROM") printf("\n\t\t");
else if ($i == "WHERE") printf("\n\t\t");
else if ($i == "GROUP") printf("\n\t\t");
else if ($i == "HAVING") printf("\n\t\t");
else if ($i == "ORDER") printf("\n\t\t");
else if ($i == "LIMIT") printf("\n\t\t");
else if ($i == "AND") printf("\n\t\t\t"); # AND clauses are indented one level deeper
gsub(",",",\n\t\t\t",$i); # selected fields are also indented deeper
printf("%s ",$i);
}
printf("\n");
}
}
/[0-9]* Quit/ {
delete conns[$1];
printf("deleting %s\n",$1);
}
对那些不熟悉awk的用户:了解awk的使用就可以了。使用BEGIN作为开始,然后执行内部语句,当遇到$0,$1,$2时,相应执行相关的正则匹配。
如下:
•BEGIN这块,得到一个参数为db=mydbname。
•Connect匹配,是否为我们所需要的部分,把需要的部分保存在数组中。
•Query匹配所有查询语句,然后在数组中查询判断是否为我们需要的。是的话,就格式化然后输出查询。
•Quit从数组中删除Connect,然后输出。
把上面的awk脚本保存为~/querylog.awk,然后在my.cnf中添加 log=/data/mysql-queries.log
tail -f /data/mysql-queries.log | awk -f ~/querylog.awk db=mydb_name
或许有人有类似的需求,会使用我的解决方案,当然也可能发现一些问题。欢迎提出改进意见。
Observing the MySQL Query Log - ThinkPHP /dev/blog - PHP
Debugging an existing application can be hard to bootstrap. Sometimes it just helps to observe the queries a web application is sending to the database. Unfortunately, the MySQL Query log does not directly tell the user which query goes to which database.
I wanted to have a tail on the queries that go from an existing web application to a particular database. Since that was not the only database, and the MySQL query log does not support filtering, I hacked up a short awk script to solve the task for me. On the way, I did some reformatting to be better able to read the queries.
The MySQL query log looks like this:
080228 15:27:50 1170 Connect user@host on database_name
1170 Query SET NAMES "utf8"
1170 Query SELECT something FROM sometable WHERE some=thing
1170 Quit
So we need to filter out the "Connect" line for all connections to the database in question and retrieve the connection id, then output all lines that reference that connection id. While we're at it, we also break up the SELECT line into multiple lines for readability.
This is my awk script:
BEGIN {
mydb = "default_database";
if (ARGC == 2 && substr(ARGV[1],0,3)=="db=") {
mydb = substr(ARGV[1],4);
printf("my db %s\n",mydb);
}
}
/[0-9]* Connect/ {
if(index($0,mydb)==0) {
#printf("not using %s\n",$0);
} else {
if($2 == "Connect") {
what=$1;
} else {
what=$3;
}
print;
conns[what]="true";
}
}
/[0-9]* Query/ {
if(conns[$1]=="true") {
printf("% 4s %s : ",$1,$2);
for(i=3; i<=NF; i++){
if ($i == "FROM") printf("\n\t\t");
else if ($i == "WHERE") printf("\n\t\t");
else if ($i == "GROUP") printf("\n\t\t");
else if ($i == "HAVING") printf("\n\t\t");
else if ($i == "ORDER") printf("\n\t\t");
else if ($i == "LIMIT") printf("\n\t\t");
else if ($i == "AND") printf("\n\t\t\t"); # AND clauses are indented one level deeper
gsub(",",",\n\t\t\t",$i); # selected fields are also indented deeper
printf("%s ",$i);
}
printf("\n");
}
}
/[0-9]* Quit/ {
delete conns[$1];
printf("deleting %s\n",$1);
}
For those not familiar with awk: The manpage tells you everything that is neccessary to understand how it works. Awk takes a couple of patterns (BEGIN, and /pattern/ here) and earch line that matches a pattern is then referenced as $0 and the following block is executed. Parts of the line are then put into $1, $2 and so forth.
What I do here:
•The BEGIN rule looks at the arguments, so that the user can provide a database name on the commandline as "db=mydbname"
•The Connect pattern grabs the connect lines and looks wether the correct line is referenced. It then looks whether the timestamp is omitted. After that it stores the connection id in an awk array
•The Query pattern grabs all queries, and if the connection id is already in our array, it prints the query, reformatting it with newlines and tabs
•The Quit pattern removes the connection ids from the array (Might not be neccessary since MySQL uses the ids in ascending order, but whatever :) )
I stored the above script as ~/querylog.awk and added log=/data/mysql-queries.log in my.cnf
tail -f /data/mysql-queries.log | awk -f ~/querylog.awk db=mydb_name
Perhaps someone with similar needs might find use in my solution. Suggestions for improvement are welcome!
分享到:
相关推荐
本文将深入探讨这两个文件:"mysql-connector-java-5.1.40.zip" 和 "mysql-connector-java-5.1.10.jar",以及它们在Java开发中的作用。 首先,`mysql-connector-java-5.1.40.zip` 是一个压缩文件,包含了MySQL ...
包含mysql-connector-java-8.0.22.jar包含mysql-connector-java-8.0.22.jar包含mysql-connector-java-8.0.22.jar包含mysql-connector-java-8.0.22.jar包含mysql-connector-java-8.0.22.jar包含mysql-connector-java-...
在实际使用中,开发人员需要将`mysql-connector-java-8.0.28.jar`添加到Java项目的类路径(classpath)中,或者在Hive中通过`ADD JAR`命令加载此驱动,以便在Hive查询中使用`CREATE EXTERNAL TABLE`语句连接MySQL...
MySQL是世界上最流行的开源关系型数据库管理系统之一,而`mysql-connector-java`是MySQL官方提供的用于Java应用程序连接到MySQL服务器的驱动程序。`mysql-connector-java-5.1.27.jar`是这个驱动的一个特定版本,它...
"mysql-connector-j-8.0.33.zip" 是MySQL Connector/J的一个特定版本,版本号为8.0.33。这个压缩包包含了驱动的所有必要文件,使得开发者能够在Java环境中建立与MySQL 8.x数据库的连接。解压后的主要文件通常包括...
MySQL-connector-java-8.0.28 是MySQL数据库与Java应用程序之间通信的重要组件,它是一个JDBC(Java Database Connectivity)驱动程序,使得Java开发者能够通过编写Java代码来访问和操作MySQL数据库。在这个版本中,...
`mysql-connector-java-5.1.47.jar`是这个驱动程序的特定版本,发布于MySQL的5.1系列,它提供了与MySQL 5.1数据库版本兼容的连接功能。 **JDBC(Java Database Connectivity)** JDBC是Java平台上的标准API,由Sun ...
总的来说,`mysql-connector-odbc-3.51.30`为开发者和数据分析师提供了一种标准化、跨平台的方式来访问MySQL数据库,极大地扩展了MySQL的适用范围和兼容性。通过ODBC接口,我们可以利用各种工具和语言,轻松实现与...
MySQL是世界上最流行的开源关系型数据库管理系统之一,而`mysql-connector-java-5.1.7.jar`是MySQL官方为了使得Java应用程序能够连接到MySQL数据库而提供的JDBC(Java Database Connectivity)驱动程序。JDBC是Java...
"mysql-connector-java-5.1.7-bin.jar" 文件就是这个桥梁,它是一个Java归档(JAR)文件,包含了MySQL JDBC驱动的所有必要组件。 MySQL JDBC驱动,也被称为MySQL Connector/J,允许Java应用程序通过遵循JDBC API来...
mysql-connector-java-5.1.7-bin.jar
- `mysql-connector-java-5.1.46-bin.jar` 和 `mysql-connector-java-5.1.27-bin.jar` 是Java的归档(Archive)文件,它们包含了MySQL Connector/J的所有类和资源,供Java虚拟机(JVM)加载和使用。`bin`通常表示这...
总的来说,`mysql-connector-java-5.1.27-bin.jar.zip`在Hive环境中用于建立与MySQL数据库的连接,允许在Hive SQL查询中操作和管理MySQL中的数据,是大数据生态中连接关系型数据库与分布式计算框架的重要组件。...
`mysql-udf-http` 包含一系列预编译的动态链接库,这些库可以被 MySQL 服务器加载,从而让你在 SQL 查询中直接执行 HTTP 请求。例如,你可以使用这个 UDF 来获取远程 API 的数据,或者将数据库中的信息 POST 到其他 ...
在给定的场景中,`mysql-connector-java-5.1.10-bin.jar`是这个桥接器的一个特定版本,用于配合Sqoop进行数据迁移。 Sqoop是一个用于在Hadoop和传统关系型数据库如MySQL之间传输数据的工具。它允许用户将大规模...
在这个"mysql-connector-java-8.0.11"压缩包中,包含的是MySQL官方发布的针对Java的最新版本连接器,版本号为8.0.11。 1. **JDBC接口**:JDBC是Java语言访问数据库的标准接口,由Java SE的java.sql包提供。它定义了...
MySQL是世界上最受欢迎的关系型数据库管理系统之一,而`mysql-connector-java-5.1.30`是MySQL官方为Java开发者提供的数据库连接驱动包。这个驱动包使得Java应用程序能够与MySQL数据库进行无缝通信,执行SQL查询,...
`mysql-connector-java-8.0.11.jar`适用于较新的MySQL环境,`mysql-connector-java-5.1.7-bin.jar`满足了对老版本MySQL的兼容需求,而`ojdbc14-10.2.0.1.0.jar`则服务于Oracle 10g数据库。在Java开发中,理解如何...
"mysql-connector-java-5.1.40.tar.gz" 是这个驱动程序的一个特定版本,版本号为5.1.40。这个压缩包包含了运行Java应用与MySQL数据库进行交互所需的类库和其他相关文件。 在Linux环境中处理这个压缩包,首先需要将...
这个"mysql-connector-java-5.1.45-bin.jar"文件是该驱动的一个特定版本,即5.1.45版。这个版本是纯净且正版的,适合于Java开发者在他们的项目中直接集成使用。 在Java编程中,为了连接到MySQL数据库,我们需要一个...