Linux 서버에서 MySQL 쿼리가 발생할 때 어떻게 추적합니까?
예를 들어 일종의 리스너를 설정 한 다음 웹 페이지를 요청하고 엔진이 실행 한 모든 쿼리를 보거나 프로덕션 서버에서 실행중인 모든 쿼리를보고 싶습니다. 어떻게해야합니까?
Linux 서버에서 MySQL 쿼리가 발생할 때 어떻게 추적합니까?
예를 들어 일종의 리스너를 설정 한 다음 웹 페이지를 요청하고 엔진이 실행 한 모든 쿼리를 보거나 프로덕션 서버에서 실행중인 모든 쿼리를보고 싶습니다. 어떻게해야합니까?
답변:
MySQL 명령 SHOW FULL PROCESSLIST;
을 실행하여 주어진 시간에 어떤 쿼리가 처리되는지 확인할 수 있지만 원하는 결과를 얻지 못할 수 있습니다.
서버를 사용하여 모든 응용 프로그램을 수정하지 않고 기록을 얻는 가장 좋은 방법은 아마도 트리거를 통하는 것입니다. 모든 쿼리 실행으로 인해 쿼리가 일종의 기록 테이블에 삽입되도록 트리거를 설정 한 다음 별도의 페이지를 만들어이 정보에 액세스 할 수 있습니다.
이렇게하면 INSERT
모든 단일 쿼리 위에 추가 항목이 추가 되어 서버의 모든 항목이 상당히 느려질 수 있습니다.
편집 : 또 다른 대안은 일반 쿼리 로그 이지만 플랫 파일에 작성하면 특히 실시간으로 표시 할 수있는 유연성이 많이 제거됩니다. 간단하고 구현하기 쉬운 방법을 원한다면 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';
모든 DB에서 쿼리를 수행하십시오. 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
빙고 방고. 스로틀되지는 않았지만 내가 실행 한 상자에서 2-4 %의 CPU 만 차지했습니다. 어쩌면 이것이 누군가를 돕기를 바랍니다.
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 시작하기
이 답변을 참조하십시오 .
다음은 개발 제안에 유용한 단계입니다.
이 라인을 귀하 ~/.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_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을 확인하십시오 .
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 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