web-dev-qa-db-ja.com

MySQLのライブクエリを表示するにはどうすればいいですか?

Linuxサーバー上で発生したMySQLクエリを追跡するにはどうすればよいですか。

たとえば、ある種のリスナーを設定してから、Webページをリクエストしてエンジンが実行したすべてのクエリを表示したり、本番サーバーで実行されているすべてのクエリを表示したりします。これどうやってするの?

448
barfoon

MySQLコマンドSHOW FULL PROCESSLIST;を実行して、どのクエリがいつ処理されているのかを確認することができますが、それはおそらくあなたが望んでいることを達成することはできません。

サーバーを使用してすべてのアプリケーションを変更せずに履歴を取得する最善の方法は、おそらくトリガーを使用することです。クエリを実行するたびにクエリが何らかの履歴テーブルに挿入されるようにトリガを設定してから、この情報にアクセスするための別のページを作成することができます。

ただし、これによってサーバー上のすべての処理が大幅に遅くなる可能性があることに注意してください。ただし、クエリごとに余分なINSERTが追加されます。


編集:もう一つの代替案は General Query Log ですが、それをフラットファイルに書き込むことで、特にリアルタイムでの表示の柔軟性に対する多くの可能性が取り除かれます。しかし、GQLを有効にしてからログファイルでtail -fを実行すると、うまくいきます。

266
Chad Birch

すべてのクエリをログファイルに簡単に記録できます。

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

(任意のデータベースに対して)クエリを実行します。 /var/run/mysqld/mysqld.logをgrepまたはそうでなければ調べます

それから忘れないで

mysql> SET GLOBAL general_log = 'OFF';

またはパフォーマンスが落ち、ディスクがいっぱいになります。

469
artfulrobot

答えはすでに受け入れられていますが、私は最も簡単な選択肢でさえあるかもしれないものを提示したいと思います。

$ mysqladmin -u bob -p -i 1 processlist

これにより、現在のクエリが毎秒画面に表示されます。

  • -uコマンドを実行したいmysqlユーザー
  • -pパスワードの入力を促します(パスワードをファイルに保存したり、コマンド履歴にコマンドを表示したりする必要はありません)。
  • i秒単位の間隔です。
  • 全プロセスリストを表示し、各プロセスのクエリ全体を表示するには、--verboseフラグを使用します。 (ありがとう、 nmat

短所がある可能性があります:速いクエリが設定した間隔の間に実行されれば現われないかもしれません。 IE:私の間隔は1秒に設定されていて、実行に.02秒かかり、間隔の間に実行されるクエリがある場合、それは表示されません。

このオプションは、リスナーなどを設定しなくても、実行中のクエリをすばやく確認したい場合に使用します。

169
halfpastfour.am

この便利なSQLクエリを実行してMySQLクエリの実行を確認します。コードの変更やオーバーヘッドを発生させることなく、いつでも好きな環境から実行できます。 MySQLのパーミッション設定が必要かもしれませんが、私にとっては特別な設定なしで動作します。

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

たった1つの問題は、非常に速く実行されるクエリを見逃しがちなことです。そのため、実行時間の長いクエリや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 を参照してください。

40
python1981

私はログオンを有効にする権限がなく、ログが有効になっている場合にログを表示する権限がないという特別な状況にあります。トリガーを追加できませんでしたが、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%にすぎません。私は多分これが誰かに役立つことを願っています。

17

strace

MySQL/MariaDBのライブクエリを確認する最も簡単な方法は、デバッガを使用することです。 Linuxでは、straceを使用できます。次に例を示します。

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

エスケープされた文字がたくさんあるので、 straceの出力を by piping (上記の2つのワンライナーの間に|を追加するだけ)で次のコマンドにフォーマットできます。

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を使い始める

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サーバーを再起動します。killall -HUP mysqld

16
kenorb

これは私が遭遇した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/

15
Wil

コマンドラインから実行することができます:

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;
13
recurse

mtop をチェックしてください。

12
Chris KL

私は同じことをやろうと思っていて、さまざまな投稿からの解決策をまとめて、ログファイルに書かれているとおりにライブのクエリテキストを出力するための小さなコンソールアプリケーションを作成しました。私はMySQLでEntity Frameworkを使用しており、生成された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);
            }
        }
      }
    }
    
7
gb2d

一般的なロギングを有効にする方法を説明した以前の回答に加えて、SQLがログに書き込まれる前に、Vanilla MySql 5.6インストールで1つの追加変数を変更する必要がありました。

SET GLOBAL log_output = 'FILE';

デフォルト設定は 'NONE'でした。

1
David B

Gibbs MySQLスパイグラス

AgilDataが最近、 Gibbs MySQLスケーラビリティアドバイザ (無料のセルフサービスツール)を発表しました。これにより、ユーザーは、Gibbsにアップロードされるライブストリームのクエリをキャプチャできます。 Spyglass (オープンソース)は、MySQLサーバーとクライアントアプリケーション間のやり取りを監視します。 MySQLデータベースサーバーの再設定や再起動は必要ありません(クライアントまたはアプリケーション)。

GitHub: AgilData/gibbs-mysql-spyglass

詳細はこちら: MySQLを錆で捕獲する

インストールコマンド:

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