Làm cách nào tôi có thể xem các truy vấn MySQL trực tiếp?


493

Làm cách nào tôi có thể theo dõi các truy vấn MySQL trên máy chủ Linux của mình khi chúng xảy ra?

Ví dụ: tôi muốn thiết lập một số loại trình nghe, sau đó yêu cầu một trang web và xem tất cả các truy vấn mà công cụ đã thực hiện hoặc chỉ xem tất cả các truy vấn đang chạy trên máy chủ sản xuất. Tôi có thể làm cái này như thế nào?


Tùy thuộc vào mức độ nghiêm trọng của sự cố, tôi khuyên bạn nên dùng thử MySql Proxy. B / c nó có thể được đặt trên máy chủ ứng dụng, a) nó có thể mở rộng, b) không phải ảnh hưởng đến tất cả lưu lượng truy cập đến db. Đó là 'alpha', nhưng đã có từ lâu. dev.mysql.com/doads/mysql-proxy
Jeff Maass

15
Tại sao điều này bị đóng cửa?! Đó là hỏi làm thế nào để làm X , không phải cho một đề nghị. Gần 200 người tìm thấy câu hỏi này hữu ích. Các mod cần bình tĩnh.
Cerin

1
Tôi đã điều chỉnh lại câu hỏi này để bỏ qua mọi tham chiếu đến các công cụ. Tôi nghĩ rằng câu hỏi này hoàn toàn thuộc chủ đề ở đây, vì "chúng ta có đang chạy các truy vấn không?" là bước đầu tiên tuyệt vời để gỡ lỗi một vấn đề liên quan đến cơ sở dữ liệu.
Jeffrey Bosboom

1
Proxy mysql @MaasSql không hữu ích cho các nhà phát triển php trong khi sử dụng PDO làm truy vấn và các giá trị chỉ bị ràng buộc tại máy chủ.
Ananda

Câu trả lời:


299

Bạn có thể chạy lệnh MySQL SHOW FULL PROCESSLIST;để xem những truy vấn nào đang được xử lý tại bất kỳ thời điểm nào, nhưng điều đó có thể sẽ không đạt được những gì bạn đang hy vọng.

Phương pháp tốt nhất để có được lịch sử mà không phải sửa đổi mọi ứng dụng bằng máy chủ có lẽ là thông qua kích hoạt. Bạn có thể thiết lập các kích hoạt để mọi truy vấn chạy kết quả trong truy vấn được chèn vào một loại bảng lịch sử nào đó, sau đó tạo một trang riêng để truy cập thông tin này.

Tuy nhiên, hãy lưu ý rằng điều này có thể sẽ làm chậm đáng kể mọi thứ trên máy chủ, với việc thêm một phần bổ sung INSERTvào đầu mỗi truy vấn.


Chỉnh sửa: một cách khác là Nhật ký truy vấn chung , nhưng việc ghi nó vào một tệp phẳng sẽ loại bỏ rất nhiều khả năng hiển thị linh hoạt, đặc biệt là trong thời gian thực. Nếu bạn chỉ muốn một cách đơn giản, dễ thực hiện để xem những gì đang diễn ra, kích hoạt GQL và sau đó sử dụng chạy tail -ftrên logfile sẽ thực hiện thủ thuật.


5
Điều này nghe có vẻ ngớ ngẩn nhưng làm thế nào chính xác tôi có thể kích hoạt GQL? Tôi đã thêm logDefput = file, general_log = 1 và general_log_file = / pathtofile và đuôi tệp nhật ký, nhấn trang web và không nhận được gì. Tôi đang làm gì sai?
barfoon

Tôi không thể chắc chắn bất cứ điều gì, nhưng hãy chắc chắn rằng bạn đã khởi động lại máy chủ và tập tin bạn chọn là tập tin mà mysql có quyền truy cập ghi.
Chad Birch

7
Tôi đã tìm ra nó - tất cả những gì tôi cần trong my.cnf là log = / path / to / log Sau đó tôi chỉ cần làm cái đuôi và nó sẽ hiển thị tất cả các truy vấn.
barfoon

1
Theo như tôi có thể nói, không có cách nào để kích hoạt bất cứ điều gì trên câu lệnh CHỌN. Kích hoạt chỉ áp dụng cho CHERTN, CẬP NHẬT, XÓA ... hoặc tôi đang hiểu sai?
gabe.

1
Tôi đã ở cùng một chỗ trước đó. Hiện tại, tôi đang sử dụng Monyog , thực hiện tất cả những điều này với chi phí rất thấp, do đó không có gì chậm lại.

520

Bạn có thể đăng nhập mọi truy vấn vào một tệp nhật ký thực sự dễ dàng:

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

Thực hiện các truy vấn của bạn (trên bất kỳ db). Grep hoặc kiểm tra khác/var/run/mysqld/mysqld.log

Vậy thì đừng quên

mysql> SET GLOBAL general_log = 'OFF';

hoặc hiệu suất sẽ giảm mạnh và đĩa của bạn sẽ lấp đầy!


37
Câu trả lời tốt! Bạn có thể sử dụng tail -f -n300 /var/run/mysqld/mysqld.logđể theo dõi trực tiếp tệp nhật ký của mình
Claudio Bredfeldt

4
Lưu ý rằng MySQL 5.1.12 trở lên là bắt buộc đối với các biến này. Trước đó, bạn phải khởi động lại MySQL để thay đổi các cài đặt này.
jlh

Có cách nào để có được các biến tham số được ghi vào nhật ký không? Tôi đang nhìn thấy SELECT name FROM person where id=?nhưng tôi không biết nó idlà gì .
Jeff

SHOW VARIABLESkhông làm việc cho tôi. Tuy nhiên SELECT @@GLOBAL.general_log_file;hoạt động tốt. (MariaDB 10.1.9)
phil pirozhkov

1
quan trọng - Bạn phải kiểm tra đầu ra đăng nhập với SHOW VARIABLES LIKE "log_output%". Nếu nó được đặt thành table, thì các bản ghi sẽ được lưu vào cơ sở dữ liệu, bảng mysql.general_logkhông nằm trong hệ thống tệp. Bạn có thể thay đổi nó thành file vớiSET GLOBAL log_output = 'file';
Arnis Juraga

199

Mặc dù câu trả lời đã được chấp nhận, tôi muốn trình bày những gì thậm chí có thể là lựa chọn đơn giản nhất:

$ mysqladmin -u bob -p -i 1 processlist

Điều này sẽ in các truy vấn hiện tại trên màn hình của bạn mỗi giây.

  • -u Người dùng mysql bạn muốn thực thi lệnh như
  • -p Nhắc mật khẩu của bạn (vì vậy bạn không phải lưu nó trong một tệp hoặc có lệnh xuất hiện trong lịch sử lệnh của bạn)
  • i Khoảng thời gian tính bằng giây.
  • Sử dụng --verbosecờ để hiển thị danh sách quy trình đầy đủ, hiển thị toàn bộ truy vấn cho từng quy trình. (Cảm ơn, nmat )

Có một nhược điểm có thể xảy ra: các truy vấn nhanh có thể không hiển thị nếu chúng chạy giữa khoảng thời gian bạn thiết lập. IE: Khoảng của tôi được đặt ở một giây và nếu có một truy vấn cần.02 vài giây để chạy và được chạy giữa các khoảng thời gian, bạn sẽ không thấy nó.

Sử dụng tùy chọn này tốt nhất là khi bạn muốn nhanh chóng kiểm tra các truy vấn đang chạy mà không phải thiết lập trình nghe hoặc bất cứ điều gì khác.


11
Đây là giải pháp tốt nhất!
dùng1398287

3
Theo tôi, giải pháp tốt hơn này vì không sử dụng kết nối mysql mới để gửi lệnh mỗi lần, thay vào đó hãy mở một kết nối mysql và sử dụng kết nối này để gửi danh sách quy trình hiển thị;
Jose Nobile

@JoseNobile Nếu bạn giữ kết nối mysql mở trong bộ điều hợp, điều đó không thực sự quan trọng. Giải pháp của tôi không chính xác cho OP vì giải pháp của tôi chưa sẵn sàng để sử dụng trong một bộ chuyển đổi. Đó là, tuy nhiên, nhanh chóng và dễ dàng.
Halfpastfour.am

7
Bạn có thể thêm --verboseđể xem toàn bộ các truy vấn
nmat

2
Đây là câu trả lời mà tôi đang tìm kiếm. Nó nên được chấp nhận là câu trả lời. Đó cũng là câu trả lời dễ nhất để thực hiện.
Chad

51

Chạy truy vấn SQL thuận tiện này để xem chạy truy vấn MySQL. Nó có thể được chạy từ bất kỳ môi trường nào bạn thích, bất cứ khi nào bạn muốn, mà không có bất kỳ thay đổi mã hoặc chi phí nào. Nó có thể yêu cầu một số cấu hình quyền của MySQL, nhưng đối với tôi nó chỉ chạy mà không có bất kỳ thiết lập đặc biệt nào.

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

Điều hấp dẫn duy nhất là bạn thường bỏ lỡ các truy vấn thực thi rất nhanh, vì vậy nó hữu ích nhất cho các truy vấn chạy dài hơn hoặc khi máy chủ MySQL có các truy vấn đang sao lưu - theo kinh nghiệm của tôi, đây chính xác là thời điểm tôi muốn xem " "truy vấn" trực tiếp.

Bạn cũng có thể thêm các điều kiện để làm cho nó cụ thể hơn bất kỳ truy vấn SQL nào.

ví dụ: Hiển thị tất cả các truy vấn chạy trong 5 giây trở lên:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME >= 5;

ví dụ: Hiển thị tất cả các CẬP NHẬT đang chạy:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND INFO LIKE '%UPDATE %';

Để biết chi tiết đầy đủ, hãy xem: http://dev.mysql.com/doc/refman/5.1/en/ Processlist-table.html


17

Tôi đang ở trong một tình huống cụ thể khi tôi không có quyền bật đăng nhập và sẽ không có quyền xem nhật ký nếu chúng được bật. Tôi không thể thêm trình kích hoạt, nhưng tôi đã có quyền gọi danh sách quy trình chương trình. Vì vậy, tôi đã nỗ lực hết mình và nghĩ ra điều này:

Tạo một tập lệnh bash có tên là "showsql Processlist":

#!/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

Thực thi tập lệnh:

./showsqlprocesslist > showsqlprocesslist.out &

Đuôi đầu ra:

tail -f showsqlprocesslist.out

Bingo bango. Mặc dù nó không được điều chỉnh, nhưng nó chỉ chiếm 2-4% CPU trên các hộp tôi chạy. Tôi hy vọng có thể điều này sẽ giúp ai đó.


Hà! Thơm ngon. Yêu nó.
Darth Egregious

Nó cần một số độ trễ để tránh đầu ra quá dài. Xem Chỉnh sửa của tôi xin vui lòng.
Slyx

@Slyx cảm ơn bạn đã gợi ý đặt một giấc ngủ vào vòng lặp. Tuy nhiên, nếu bạn đang tìm kiếm các truy vấn ngắn, sống trong thời gian ngắn hơn thời gian ngủ, bạn sẽ có khả năng bỏ lỡ những gì bạn đang tìm kiếm. Nếu bạn thực sự chỉ đang tìm kiếm một ảnh chụp nhanh trong thời gian này thì không nên chạy trong một vòng lặp. Cũng cần lưu ý rằng điều này vẫn có khả năng bỏ lỡ các truy vấn sống rất ngắn.
Michael Krauklis

17

strace

Cách nhanh nhất để xem các truy vấn MySQL / MariaDB trực tiếp là sử dụng trình gỡ lỗi. Trên Linux, bạn có thể sử dụng strace, ví dụ:

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

Vì có rất nhiều ký tự thoát, bạn có thể định dạng đầu ra của strace bằng đường ống (chỉ cần thêm |giữa hai lớp lót này) ở trên vào lệnh sau:

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"

Vì vậy, bạn sẽ thấy các truy vấn SQL khá sạch sẽ mà không cần thời gian, mà không cần chạm vào các tệp cấu hình.

Rõ ràng điều này sẽ không thay thế cách kích hoạt nhật ký tiêu chuẩn, được mô tả bên dưới (liên quan đến việc tải lại máy chủ SQL).

dtrace

Sử dụng các đầu dò MySQL để xem các truy vấn MySQL trực tiếp mà không cần chạm vào máy chủ. Kịch bản ví dụ:

#!/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));
}

Lưu tập lệnh trên vào một tệp (như watch.d) và chạy:

pfexec dtrace -s watch.d -p $(pgrep -x mysqld)

Tìm hiểu thêm: Bắt đầu với DTracing MySQL

Gibbs MySQL Spylass

Xem câu trả lời này .

Nhật ký

Dưới đây là các bước hữu ích cho đề xuất phát triển.

Thêm những dòng này vào ~/.my.cnfhoặc toàn cầu của bạn my.cnf:

[mysqld]
general_log=1
general_log_file=/tmp/mysqld.log

Đường dẫn: /var/log/mysqld.loghoặc /usr/local/var/log/mysqld.logcũng có thể hoạt động tùy thuộc vào quyền truy cập tệp của bạn.

sau đó khởi động lại MySQL / MariaDB của bạn bằng (tiền tố với sudonếu cần):

killall -HUP mysqld

Sau đó kiểm tra nhật ký của bạn:

tail -f /tmp/mysqld.log

Sau khi kết thúc, thay đổi general_logthành 0(để bạn có thể sử dụng nó trong tương lai), sau đó xóa tệp và khởi động lại máy chủ SQL : killall -HUP mysqld.


1
Không cần phải giết máy chủ nếu bạn đặt general_logtừ truy vấn MySQL. Nó sẽ bắt đầu ghi vào tập tin general_log_fileđang trỏ tới.
Robert Brisita

15

Đây là thiết lập dễ nhất trên máy Linux Linux mà tôi đã gặp. Điên để xem tất cả các truy vấn trực tiếp.

Tìm và mở tệp cấu hình MySQL của bạn, thường là /etc/mysql/my.cnf trên Ubuntu. Hãy tìm phần có nội dung ghi nhật ký và sao chép

#
# * 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

Chỉ cần bỏ ghi chú biến log Nhật ký để bật đăng nhập. Khởi động lại MySQL bằng lệnh này:

sudo /etc/init.d/mysql restart

Bây giờ chúng tôi đã sẵn sàng để bắt đầu theo dõi các truy vấn khi chúng đến. Mở một thiết bị đầu cuối mới và chạy lệnh này để cuộn tệp nhật ký, điều chỉnh đường dẫn nếu cần.

tail -f /var/log/mysql/mysql.log

Bây giờ chạy ứng dụng của bạn. Bạn sẽ thấy các truy vấn cơ sở dữ liệu bắt đầu bay qua trong cửa sổ thiết bị đầu cuối của bạn. (đảm bảo bạn đã cuộn và lịch sử được bật trên thiết bị đầu cuối)

TỪ http://www.howtogeek.com/howto/database/monitor-all-sql-queries-in-mysql/


13

Từ một dòng lệnh bạn có thể chạy:

watch --interval=[your-interval-in-seconds] "mysqladmin -u root -p[your-root-pw] processlist | grep [your-db-name]"

Thay thế các giá trị [x] bằng các giá trị của bạn.

Hoặc thậm chí tốt hơn:

 mysqladmin -u root -p -i 1 processlist;

1
Đây thực sự là một đoạn rất hay có thể có ích .. Cảm ơn!
MGP

Chính xác những gì tôi đang tìm kiếm!! đồng hồ cần phải được cài đặt riêng.
Tilo

12

Kiểm tra mtop .


1
Có, nhưng may mắn cài đặt nó trên Debian hoặc Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner

Quản lý để có được nó chạy trên debian, nhưng nó không có giá trị vì nó bỏ lỡ rất nhiều truy vấn. Tôi có thể thấy bộ đếm truy vấn tăng lên liên tục nhưng nó hiếm khi hiển thị bất kỳ truy vấn nào. Có vẻ như nó chỉ hiển thị các truy vấn mất nhiều thời gian hơn khoảng 1 giây.
Cobra_Fast

@Cobra_Fast được nêu rõ trên trang Sourceforge của mtop: mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete. mtop.sourceforge.net Đôi khi nó khá hữu ích.
Ian Lewis

7

Tôi đã tìm cách làm tương tự và đã cùng nhau đưa ra một giải pháp từ nhiều bài đăng khác nhau, cộng với việc tạo ra một ứng dụng bảng điều khiển nhỏ để xuất văn bản truy vấn trực tiếp như được ghi vào tệp nhật ký. Điều này rất quan trọng trong trường hợp của tôi vì tôi đang sử dụng Entity Framework với MySQL và tôi cần có khả năng kiểm tra SQL được tạo.

Các bước để tạo tệp nhật ký (một số sao chép của các bài đăng khác, tất cả đều ở đây để đơn giản):

  1. Chỉnh sửa tập tin nằm ở:

    C:\Program Files (x86)\MySQL\MySQL Server 5.5\my.ini

    Thêm "log = Development.log" vào cuối tệp. (Lưu ý lưu tệp này yêu cầu tôi chạy trình soạn thảo văn bản của mình với tư cách quản trị viên).

  2. Sử dụng bàn làm việc MySql để mở một dòng lệnh, nhập mật khẩu.

    Chạy phần sau để bật ghi nhật ký chung sẽ ghi lại tất cả các truy vấn đã chạy:

    SET GLOBAL general_log = 'ON';
    
    To turn off:
    
    SET GLOBAL general_log = 'OFF';

    Điều này sẽ khiến các truy vấn đang chạy được ghi vào tệp văn bản tại vị trí sau.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. Tạo / Chạy ứng dụng bảng điều khiển sẽ xuất thông tin nhật ký theo thời gian thực:

    Nguồn có sẵn để tải về ở đây

    Nguồn:

    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
Điều này trông thật tuyệt và tôi chắc chắn sẽ xem xét nó, thật tuyệt khi thực hiện điều này như một dự án OSS và tạo ra một công cụ định hình!
Rippo

Tôi nghĩ đó là một ý tưởng tốt. Tôi đã đặt một repo SVN trên mã google. Có lẽ là dự án hệ điều hành nhỏ nhất từ ​​trước đến nay, nhưng điều này rất hữu ích cho đến nay. Có lẽ tôi sẽ mở rộng nó, quan tâm xem liệu có ai khác đưa nó đi xa hơn không. code.google.com/p/leelsogs
gb2d

OP cần nó để hoạt động trên máy Linux của mình. Có vẻ như câu trả lời của bạn dành cho máy Windows. Mặc dù câu trả lời này phản ánh sự sáng tạo, nó có thể không hữu ích cho người khác.
Halfpastfour.am

1

Ngoài các câu trả lời trước mô tả cách bật ghi nhật ký chung, tôi đã phải sửa đổi một biến bổ sung trong cài đặt MySql 5.6 của vanilla trước khi bất kỳ SQL nào được ghi vào nhật ký:

SET GLOBAL log_output = 'FILE';

Cài đặt mặc định là 'KHÔNG'.


0

Gibbs MySQL Spylass

AgilData ra mắt gần đây cố vấn khả năng mở rộng Gibbs MySQL (một công cụ tự phục vụ miễn phí) cho phép người dùng nắm bắt một luồng truy vấn trực tiếp để được tải lên Gibbs. Spylass (là Nguồn mở) sẽ xem các tương tác giữa Máy chủ MySQL và ứng dụng khách của bạn. Không cần cấu hình lại hoặc khởi động lại máy chủ cơ sở dữ liệu MySQL (máy khách hoặc ứng dụng).

GitHub: AgilData / gibbs-mysql-spylass

Tìm hiểu thêm: Gói chụp MySQL với Rust

Lệnh cài đặt:

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

2
Spylass dường như yêu cầu khóa API từ máy chủ bị hỏng và lần cam kết cuối cùng là 3 năm trước. Không chắc chắn sản phẩm này vẫn được hỗ trợ / làm việc.
Dan Tenenbaum
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.