라이브 MySQL 쿼리를 보려면 어떻게해야합니까?


493

Linux 서버에서 MySQL 쿼리가 발생할 때 어떻게 추적합니까?

예를 들어 일종의 리스너를 설정 한 다음 웹 페이지를 요청하고 엔진이 실행 한 모든 쿼리를 보거나 프로덕션 서버에서 실행중인 모든 쿼리를보고 싶습니다. 어떻게해야합니까?


문제가 얼마나 나쁜지에 따라 MySql Proxy를 사용해 보는 것이 좋습니다. B / C는 앱 서버에 배치 할 수 있으며 a) 확장 가능하며 b) db의 모든 트래픽에 영향을 줄 필요는 없습니다. 그것은 '알파'에 있지만 오래 전부터 사용되었습니다. dev.mysql.com/downloads/mysql-proxy
Jeff Maass

15
왜 닫혔습니까?! 권장 사항이 아닌 X 수행 방법을 묻습니다 . 약 200 명이이 질문이 유용하다고 생각했습니다. 개조는 진정해야합니다.
Cerin

1
나는 도구에 대한 언급을 생략하기 위해이 질문을 다시 작성했다. 이 질문은 "우리가해야 할 쿼리를 실행하고 있습니까?" 데이터베이스 관련 문제를 디버깅하는 첫 번째 단계입니다.
Jeffrey Bosboom 2014

1
@MaasSql mysql 프록시는 PDO를 쿼리로 사용하고 값이 서버에서만 바인딩되는 동안 PHP 개발자에게는 도움이되지 않습니다.
Ananda

답변:


299

MySQL 명령 SHOW FULL PROCESSLIST;을 실행하여 주어진 시간에 어떤 쿼리가 처리되는지 확인할 수 있지만 원하는 결과를 얻지 못할 수 있습니다.

서버를 사용하여 모든 응용 프로그램을 수정하지 않고 기록을 얻는 가장 좋은 방법은 아마도 트리거를 통하는 것입니다. 모든 쿼리 실행으로 인해 쿼리가 일종의 기록 테이블에 삽입되도록 트리거를 설정 한 다음 별도의 페이지를 만들어이 정보에 액세스 할 수 있습니다.

이렇게하면 INSERT모든 단일 쿼리 위에 추가 항목이 추가 되어 서버의 모든 항목이 상당히 느려질 수 있습니다.


편집 : 또 다른 대안은 일반 쿼리 로그 이지만 플랫 파일에 작성하면 특히 실시간으로 표시 할 수있는 유연성이 많이 제거됩니다. 간단하고 구현하기 쉬운 방법을 원한다면 GQL을 활성화 한 다음 tail -f로그 파일에서 실행을 사용 하여 트릭을 수행하십시오.


5
어리석게 들릴 수 있지만 GQL을 정확히 어떻게 활성화 할 수 있습니까? log_output = file, general_log = 1 및 general_log_file = / pathtofile을 추가하고 로그 파일을 tail 's하고 사이트를 방문했으며 아무것도 얻지 못했습니다. 내가 무엇을 잘못하고 있지?
barfoon 2019

아무것도 확신 할 수 없지만 서버를 다시 시작했는지, 선택한 파일이 mysql이 쓰기 권한을 가지고있는 파일인지 확인하십시오.
차드 버치

7
나는 그것을 알아 냈습니다. 내 my.cnf에 필요한 것은 log = / path / to / log뿐이었습니다. 그냥 꼬리를 막고 모든 쿼리를 표시합니다.
barfoon

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

모든 DB에서 쿼리를 수행하십시오. 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

매개 변수가 지정된 변수를 로그에 기록하는 방법이 있습니까? 나는보고 SELECT name FROM person where id=?있지만 나는 무엇인지 모른다 id.
Jeff

SHOW VARIABLES나를 위해 작동하지 않았다. 그러나 SELECT @@GLOBAL.general_log_file;잘 작동합니다. (MariaDB 10.1.9)
필 pirozhkov

1
중요 –로 로깅 출력을 확인해야합니다 SHOW VARIABLES LIKE "log_output%". 로 설정된 경우 table로그는 mysql.general_log파일 시스템이 아닌 테이블 자체에 데이터베이스에 저장됩니다 . 다음 file 과 같이 변경할 수 있습니다SET GLOBAL log_output = 'file';
Arnis Juraga

199

답변이 이미 수락되었지만 가장 간단한 옵션이 무엇인지 제시하고 싶습니다.

$ mysqladmin -u bob -p -i 1 processlist

그러면 화면에 현재 쿼리가 매 초마다 인쇄됩니다.

  • -u 명령을 실행하려는 mysql 사용자
  • -p 암호를 묻습니다 (파일에 저장하거나 명령 내역에 명령을 표시하지 않아도 됨)
  • i 초 단위의 간격입니다.
  • --verbose플래그를 사용하여 전체 프로세스 목록을 표시하고 각 프로세스에 대한 전체 쿼리를 표시하십시오. (감사합니다, nmat )

가능한 단점이 있습니다. 빠른 쿼리가 설정 한 간격 사이에 실행될 경우 빠른 쿼리가 표시되지 않을 수 있습니다. IE : 내 간격이 1 초로 설정되어 있으며 .02실행 하는 데 몇 초가 걸리고 간격 사이에 실행 되는 쿼리가 있으면 볼 수 없습니다.

리스너 등을 설정하지 않고 실행중인 쿼리를 빠르게 확인하려는 경우이 옵션을 사용하는 것이 좋습니다.


11
이것이 최고의 솔루션입니다!
1398287

3
내 의견으로는이 더 나은 솔루션은 매번 명령을 보내기 위해 새로운 mysql 연결을 사용하지 않기 때문에 하나의 mysql 연결을 열고 이것을 사용하여 show processlist를 보냅니다.
Jose Nobile

@JoseNobile 어댑터에서 mysql 연결을 열어두면 실제로 중요하지 않습니다. 솔루션이 어댑터에서 사용할 준비가되지 않았으므로 솔루션이 OP에 적합하지 않습니다. 그러나 빠르고 쉽습니다.
halfpastfour.am

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

빙고 방고. 스로틀되지는 않았지만 내가 실행 한 상자에서 2-4 %의 CPU 만 차지했습니다. 어쩌면 이것이 누군가를 돕기를 바랍니다.


하아! 맛있는. 그것을 사랑하십시오.
Darth

너무 자세한 출력을 피하려면 약간의 지연이 필요합니다. 내 편집을 참조하십시오.
Slyx

@Slyx는 루프에서 잠을 자라는 제안에 감사드립니다. 그러나 잠자기보다 짧은 시간 동안 지속되는 짧은 수명의 쿼리를 찾으려면 원하는 것을 놓칠 수 있습니다. 실제로 스냅 샷을 찾고 있다면 루프에서 실행해서는 안됩니다. 이것은 여전히 ​​매우 짧은 라이브 쿼리를 놓칠 수 있습니다.
Michael Krauklis

17

strace

실시간 MySQL / MariaDB 쿼리를 보는 가장 빠른 방법은 디버거를 사용하는 것입니다. Linux에서는 다음을 사용할 수 있습니다 strace.

sudo strace -e trace=read,write -s 2000 -fp $(pgrep -nf mysql) 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 망원경

답변을 참조하십시오 .

로그

다음은 개발 제안에 유용한 단계입니다.

이 라인을 귀하 ~/.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.


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
예, 그러나 데비안 또는 우분투에 설치하는 것이 행운입니다 : bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner

데비안에서 실행되도록 관리했지만 많은 쿼리가 없기 때문에 그만한 가치가 없습니다. 쿼리 카운터가 지속적으로 올라가는 것을 볼 수 있지만 쿼리가 거의 표시되지 않습니다. 약 1 초 이상 걸리는 쿼리 만 표시하는 것 같습니다.
Cobra_Fast

@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

1

일반 로깅을 사용하는 방법을 설명하는 이전 답변 외에도 SQL이 로그에 작성되기 전에 내 바닐라 MySql 5.6 설치에서 하나의 추가 변수를 수정해야했습니다.

SET GLOBAL log_output = 'FILE';

기본 설정은 '없음'입니다.


0

깁스 MySQL 망원경

AgilData는 최근 Gibbs MySQL Scalability Advisor (무료 셀프 서비스 도구)를 출시하여 사용자가 Gibbs에 업로드 할 실시간 쿼리 스트림을 캡처 할 수 있도록합니다. 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.