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


493

LinuxサーバーでMySQLクエリが発生したときにそれらを追跡するにはどうすればよいですか?

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


問題の程度によっては、MySql Proxyを試すことを強くお勧めします。B / cアプリサーバーに配置できます。a)スケーラブルです。b)dbへのすべてのトラフィックに影響を与える必要はありません。それは「アルファ版」ですが、ずっと前からあります。dev.mysql.com/downloads/mysql-proxy
Jeff Maass

15
なぜこれが閉じられたのですか?それは推奨ではなく、Xの実行方法を尋ねています。200人近くがこの質問を参考にしています。モッドは落ち着く必要があります。
Cerin

1
ツールへの言及を省略するために、この質問を書き直しました。この質問は、「本来あるべきクエリを実行していますか?」と、完全にここで話題になっていると思います。データベース関連の問題をデバッグするための素晴らしい最初のステップです。
Jeffrey Bosboom、2016

1
@MaasSql mysqlプロキシは、クエリと値がサーバーでのみバインドされるのでPDOを使用している間、php開発者には役立ちません。
アナンダ

回答:


299

MySQLコマンドSHOW FULL PROCESSLIST;を実行して、任意の時点でどのクエリが処理されているかを確認できますが、それではおそらく期待どおりの結果は得られません。

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

ただし、これにより、サーバー上のすべての速度が大幅に低下し、すべてのINSERTクエリに追加で追加されるため、注意してください。


編集:もう1つの代替案は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、2009

1
私の知る限り、SELECTステートメントで何かをトリガーする方法はありません。トリガーはINSERT、UPDATE、DELETE ...にのみ適用されますか、それとも誤解されますか?
ゲイブ。

1
以前同じ場所にいました。現在、私は非常に少ないオーバーヘッドでこれらすべてを行うMonyogを使用しているため、何も遅くなりません。

520

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

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:私の間隔は1秒に設定されており、実行に.02数秒かかり、間隔の間に実行されるクエリがある場合、表示されません。

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


11
これが最善の解決策です!
user1398287

3
新しいmysql接続を使用して毎回コマンドを送信するのではなく、1つのmysql接続を開き、これを使用してshow processlistを送信するので、私の意見ではこのより良い解決策です。
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

ビンゴバンゴ。スロットルされていませんが、実行したボックスでCPUを2〜4%しか消費していません。多分これが誰かを助けることを願っています。


ハ!おいしい。大好きです。
Darth Egregious 14

冗長な出力が多くなりすぎないようにするには、ある程度の遅延が必要です。私の編集を見てください。
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

エスケープされた文字がたくさんあるので、上記のパイプライン (これらの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の開始

ギブス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


1
general_logMySQLクエリからを設定した場合、サーバーを強制終了する必要はありません。general_log_file指しているファイルへの書き込みを開始します。
Robert Brisita

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

次に、アプリケーションを実行します。ターミナルウィンドウにデータベースクエリが表示されます。(ターミナルでスクロールと履歴が有効になっていることを確認してください)

FROM 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

まさに私が探していたもの!! 時計は別にインストールする必要があります。
は、Tilo

12

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


1
はい。ただし、DebianまたはUbuntuにインストールして頑張ってください:bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner

なんとか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これは非常に役立つことがあります。
Ian Lewis

7

私は同じことをしたいと考えており、さまざまな投稿からの解決策をまとめました。さらに、ログファイルに書き込まれるライブクエリテキストを出力する小さなコンソールアプリを作成しました。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);
            }
        }
      }
    }

1
これは本当にクールに見えます。私は間違いなくそれを見ていきます。これをOSSプロジェクトとして取り入れてプロファイリングツールを作成するのは素晴らしいことです!
Rippo

それは良い考えだと思います。GoogleコードにSVNリポジトリを配置しました。おそらくこれまでで最小のOSプロジェクトですが、これは今のところ非常に便利です。私はおそらくそれを拡張し、他の誰かがそれをさらに進めるかどうかを確認することに興味があります。code.google.com/p/livelogs
gb2d

OPはLinuxマシンで動作するためにそれを必要とします。あなたの答えはWindowsマシン向けのようです。この答えは創造性を反映していますが、他の人には役に立たないかもしれません。
halfpastfour.am 2014

1

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

SET GLOBAL log_output = 'FILE';

デフォルト設定は「なし」でした。


0

ギブスMySQLスパイグラス

AgilDataは最近、Gibbs MySQLにアップロードするクエリのライブストリームをキャプチャできるGibbs MySQL Scalability Advisor(無料のセルフサービスツール)をリリースしました。Spyglass(オープンソース)は、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.