LinuxサーバーでMySQLクエリが発生したときにそれらを追跡するにはどうすればよいですか?
たとえば、ある種のリスナーを設定してから、Webページを要求して、エンジンが実行したすべてのクエリを表示するか、運用サーバーで実行されているすべてのクエリを表示したいです。これどうやってするの?
LinuxサーバーでMySQLクエリが発生したときにそれらを追跡するにはどうすればよいですか?
たとえば、ある種のリスナーを設定してから、Webページを要求して、エンジンが実行したすべてのクエリを表示するか、運用サーバーで実行されているすべてのクエリを表示したいです。これどうやってするの?
回答:
MySQLコマンドSHOW FULL PROCESSLIST;
を実行して、任意の時点でどのクエリが処理されているかを確認できますが、それではおそらく期待どおりの結果は得られません。
サーバーを使用してすべてのアプリケーションを変更せずに履歴を取得する最良の方法は、おそらくトリガーを使用することです。すべてのクエリを実行するとクエリがなんらかの履歴テーブルに挿入されるようにトリガーを設定し、この情報にアクセスするための別のページを作成できます。
ただし、これにより、サーバー上のすべての速度が大幅に低下し、すべてのINSERT
クエリに追加で追加されるため、注意してください。
編集:もう1つの代替案はGeneral Query Logですが、それをフラットファイルに書き込むと、特にリアルタイムでの表示の柔軟性の多くの可能性がなくなります。何が起こっているかを確認するための単純で実装が簡単な方法が必要な場合は、GQLを有効にしてtail -f
から、ログファイルでの実行を使用するとうまくいきます。
すべてのクエリをログファイルに簡単に記録できます。
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';
またはパフォーマンスが急落し、ディスクがいっぱいになります!
tail -f -n300 /var/run/mysqld/mysqld.log
して、ログファイルのライブトラックを維持できます
SELECT name FROM person where id=?
いますが、何であるかわかりませんid
。
SHOW VARIABLES
うまくいきませんでした。ただし、SELECT @@GLOBAL.general_log_file;
正常に動作します。(MariaDB 10.1.9)
SHOW VARIABLES LIKE "log_output%"
。に設定されているtable
場合、ログはデータベース自体に保存され、テーブルmysql.general_log
はファイルシステムに保存されません。あなたはそれを変更することができますfile
とSET GLOBAL log_output = 'file';
答えはすでに受け入れられていますが、最も簡単なオプションでさえあるものを提示したいと思います。
$ mysqladmin -u bob -p -i 1 processlist
これにより、現在のクエリが毎秒画面に表示されます。
-u
コマンドを実行するmysqlユーザー-p
パスワードを要求する(ファイルに保存したり、コマンドをコマンド履歴に表示したりする必要がないため)i
秒単位の間隔。--verbose
フラグを使用して完全なプロセスリストを表示し、各プロセスのクエリ全体を表示します。(ありがとう、nmat)考えられる欠点があります。高速クエリは、設定した間隔で実行されると表示されない場合があります。IE:私の間隔は1秒に設定されており、実行に.02
数秒かかり、間隔の間に実行されるクエリがある場合、表示されません。
このオプションは、リスナーなどを設定せずに、実行中のクエリをすばやく確認する場合に使用してください。
--verbose
して完全なクエリを表示できます
この便利な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を参照してください。
ログをオンにする権限がなく、ログがオンになっているとログを表示する権限がない特定の状況にあります。トリガーを追加できませんでしたが、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
ビンゴバンゴ。スロットルされていませんが、実行したボックスでCPUを2〜4%しか消費していません。多分これが誰かを助けることを願っています。
strace
ライブMySQL / MariaDBクエリを確認する最も簡単な方法は、デバッガを使用することです。Linux strace
では、たとえばを使用できます。
sudo strace -e trace=read,write -s 2000 -fp $(pgrep -nf mysql) 2>&1
エスケープされた文字がたくさんあるので、上記のパイプライン (これらの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サーバーのリロードを含む)に取って代わるものではありません。
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の開始
この回答を参照してください。
ここでは、開発提案に役立つ手順を示します。
これらの行をyour ~/.my.cnf
またはglobalに追加します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サーバーを再起動しますkillall -HUP mysqld
。
general_log
MySQLクエリからを設定した場合、サーバーを強制終了する必要はありません。general_log_file
指しているファイルへの書き込みを開始します。
これは、私が遭遇した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
次に、アプリケーションを実行します。ターミナルウィンドウにデータベースクエリが表示されます。(ターミナルでスクロールと履歴が有効になっていることを確認してください)
FROM http://www.howtogeek.com/howto/database/monitor-all-sql-queries-in-mysql/
mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete.
mtop.sourceforge.netこれは非常に役立つことがあります。
私は同じことをしたいと考えており、さまざまな投稿からの解決策をまとめました。さらに、ログファイルに書き込まれるライブクエリテキストを出力する小さなコンソールアプリを作成しました。MySQLでEntity Frameworkを使用していて、生成されたSQLを検査できる必要があるため、これは私の場合には重要でした。
ログファイルを作成する手順(簡単にするために、他の投稿の一部を複製しています)。
次の場所にあるファイルを編集します。
C:\Program Files (x86)\MySQL\MySQL Server 5.5\my.ini
ファイルの最後に「log = development.log」を追加します。(このファイルを保存するには、テキストエディターを管理者として実行する必要がありました)。
MySqlワークベンチを使用してコマンドラインを開き、パスワードを入力します。
次のコマンドを実行して、実行されたすべてのクエリを記録する一般的なロギングをオンにします。
SET GLOBAL general_log = 'ON';
To turn off:
SET GLOBAL general_log = 'OFF';
これにより、実行中のクエリが次の場所にあるテキストファイルに書き込まれます。
C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
ログ情報をリアルタイムで出力するコンソールアプリを作成/実行します。
ソース:
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);
}
}
}
}
AgilDataは最近、Gibbs MySQLにアップロードするクエリのライブストリームをキャプチャできるGibbs MySQL Scalability Advisor(無料のセルフサービスツール)をリリースしました。Spyglass(オープンソース)は、MySQLサーバーとクライアントアプリケーション間の相互作用を監視します。MySQLデータベースサーバーの再構成や再起動は必要ありません(クライアントまたはアプリ)。
GitHub:AgilData / gibbs-mysql-spyglass
インストールコマンド:
curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash