Bagaimana saya bisa melihat permintaan langsung MySQL?

493

Bagaimana saya bisa melacak permintaan MySQL di server Linux saya saat terjadi?

Misalnya saya ingin menyiapkan semacam pendengar, kemudian meminta halaman web dan melihat semua permintaan yang dieksekusi mesin, atau hanya melihat semua permintaan yang dijalankan di server produksi. Bagaimana saya bisa melakukan ini?

barfoon
sumber
Bergantung pada seberapa buruk masalahnya, saya sangat merekomendasikan mencoba MySql Proxy. B / c dapat ditempatkan di server aplikasi, a) itu dapat diskalakan, b) tidak harus mempengaruhi semua lalu lintas ke db. Itu dalam 'alpha', tetapi sudah ada sejak lama. dev.mysql.com/downloads/mysql-proxy
Jeff Maass
15
Kenapa ini ditutup ?! Itu bertanya bagaimana melakukan X , bukan untuk rekomendasi. Hampir 200 orang menganggap pertanyaan ini bermanfaat. Mod perlu tenang.
Cerin
1
Saya telah menulis ulang pertanyaan ini untuk menghilangkan referensi ke alat. Saya pikir pertanyaan ini sangat sesuai dengan topik di sini, karena "apakah kita menjalankan pertanyaan seharusnya?" adalah langkah pertama yang bagus dalam men-debug masalah yang berhubungan dengan basis data.
Jeffrey Bosboom
1
@MaasSql proxy mysql tidak membantu pengembang php saat menggunakan PDO karena kueri dan nilai hanya terikat di server.
Ananda

Jawaban:

300

Anda dapat menjalankan perintah MySQL SHOW FULL PROCESSLIST;untuk melihat permintaan apa yang sedang diproses pada waktu tertentu, tetapi itu mungkin tidak akan mencapai apa yang Anda harapkan.

Metode terbaik untuk mendapatkan riwayat tanpa harus memodifikasi setiap aplikasi menggunakan server mungkin melalui pemicu. Anda bisa mengatur pemicu sehingga setiap kueri menjalankan hasil dalam kueri yang dimasukkan ke dalam semacam tabel riwayat, dan kemudian membuat halaman terpisah untuk mengakses informasi ini.

Perlu diketahui bahwa ini mungkin akan sangat memperlambat segala sesuatu di server, dengan menambahkan tambahan INSERTdi atas setiap permintaan tunggal.


Sunting: alternatif lain adalah General Query Log , tetapi dengan menuliskannya pada file datar akan menghapus banyak kemungkinan untuk fleksibilitas tampilan, terutama dalam waktu nyata. Jika Anda hanya ingin cara sederhana, mudah diimplementasikan untuk melihat apa yang terjadi, mengaktifkan GQL dan kemudian menggunakan menjalankan tail -fpada logfile akan melakukan trik.

Chad Birch
sumber
5
Ini mungkin terdengar konyol tapi bagaimana tepatnya saya bisa mengaktifkan GQL? Saya telah menambahkan log_output = file, general_log = 1, dan general_log_file = / pathtofile, dan mengekor file log, tekan situs dan tidak mendapatkan apa-apa. Apa yang saya lakukan salah?
barfoon
Saya tidak bisa memastikan apa pun, tetapi pastikan Anda me-restart server, dan juga file yang Anda pilih adalah salah satu yang mysql akan memiliki akses tulis.
Chad Birch
7
Saya telah menemukan jawabannya - semua yang saya butuhkan di my.cnf adalah log = / path / to / log Kemudian saya hanya melakukan ekornya dan menampilkan semua pertanyaan.
barfoon
1
Sejauh yang saya tahu, tidak ada cara untuk memicu apa pun pada pernyataan SELECT. Pemicu hanya berlaku untuk INSERT, UPDATE, DELETE ... atau apakah saya salah informasi?
gabe.
1
Saya berada di tempat yang sama sebelumnya. Saat ini, saya menggunakan Monyog yang melakukan semua ini dengan overhead yang sangat sedikit, karenanya tidak ada yang melambat.
520

Anda dapat mencatat setiap kueri ke file log dengan sangat mudah:

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

Lakukan pertanyaan Anda (pada db apa pun). Grep atau periksa/var/run/mysqld/mysqld.log

Maka jangan lupa

mysql> SET GLOBAL general_log = 'OFF';

atau kinerjanya akan menurun dan disk Anda akan terisi!

artfulrobot
sumber
37
Jawaban yang bagus! Anda dapat menggunakannya tail -f -n300 /var/run/mysqld/mysqld.loguntuk melacak langsung file log Anda
Claudio Bredfeldt
4
Perhatikan bahwa MySQL 5.1.12 atau lebih tinggi diperlukan untuk variabel-variabel ini. Sebelum itu, Anda harus me-restart MySQL untuk mengubah pengaturan ini.
jlh
Apakah ada cara untuk mendapatkan variabel parameter ditulis ke log? Saya melihat SELECT name FROM person where id=?tetapi saya tidak tahu apa iditu.
Jeff
SHOW VARIABLEStidak bekerja untuk saya. Namun SELECT @@GLOBAL.general_log_file;berfungsi dengan baik. (MariaDB 10.1.9)
phil pirozhkov
1
penting - Anda harus memeriksa hasil pencatatan dengan SHOW VARIABLES LIKE "log_output%". Jika diatur ke table, maka log akan disimpan ke dalam database itu sendiri, tabel mysql.general_logtidak dalam sistem file. Anda dapat mengubahnya file denganSET GLOBAL log_output = 'file';
Arnis Juraga
199

Meskipun jawaban telah diterima, saya ingin menyampaikan apa yang mungkin menjadi pilihan paling sederhana:

$ mysqladmin -u bob -p -i 1 processlist

Ini akan mencetak pertanyaan saat ini di layar Anda setiap detik.

  • -u Pengguna mysql yang ingin Anda jalankan sebagai perintah
  • -p Meminta kata sandi Anda (jadi Anda tidak harus menyimpannya di file atau memiliki perintah muncul di riwayat perintah Anda)
  • i Interval dalam hitungan detik.
  • Gunakan --verbosebendera untuk menampilkan daftar proses lengkap, menampilkan seluruh permintaan untuk setiap proses. (Terima kasih, nmat )

Ada kemungkinan downside: kueri cepat mungkin tidak muncul jika mereka berjalan di antara interval yang Anda atur. IE: Interval saya disetel pada satu detik dan jika ada kueri yang membutuhkan .02detik untuk dijalankan dan dijalankan di antara interval, Anda tidak akan melihatnya.

Gunakan opsi ini lebih disukai ketika Anda dengan cepat ingin memeriksa menjalankan kueri tanpa harus mengatur pendengar atau apa pun.

halfpastfour.am
sumber
11
INI adalah solusi terbaik!
user1398287
3
Menurut pendapat saya ini solusi yang lebih baik karena tidak menggunakan koneksi mysql baru untuk mengirim perintah setiap kali, sebaliknya buka satu koneksi mysql dan gunakan ini untuk mengirim daftar proses show;
Jose Nobile
@JoseNobile Jika Anda membiarkan koneksi mysql tetap terbuka di adaptor Anda, itu tidak masalah. Solusi saya tidak tepat untuk OP karena solusi saya tidak siap untuk digunakan dalam adaptor. Namun, cepat dan mudah.
halfpastfour.am
7
Anda dapat menambahkan --verboseuntuk melihat kueri lengkap
nmat
2
Inilah jawaban yang saya cari. Itu harus diterima sebagai jawabannya. Ini juga jawaban termudah untuk diterapkan.
Chad
51

Jalankan query SQL yang mudah ini untuk melihat menjalankan query MySQL. Itu dapat dijalankan dari lingkungan apa pun yang Anda suka, kapan pun Anda suka, tanpa ada perubahan kode atau overhead. Mungkin memerlukan beberapa konfigurasi izin MySQL, tetapi bagi saya itu hanya berjalan tanpa setup khusus.

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

Satu-satunya masalah adalah Anda sering melewatkan kueri yang dieksekusi dengan sangat cepat, sehingga sangat berguna untuk kueri yang berjalan lebih lama atau ketika server MySQL memiliki kueri yang mencadangkan - dalam pengalaman saya ini adalah waktu yang tepat ketika saya ingin melihat " pertanyaan "langsung".

Anda juga dapat menambahkan kondisi untuk membuatnya lebih spesifik sembarang query SQL.

mis. Menunjukkan semua permintaan berjalan selama 5 detik atau lebih:

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

mis. Tampilkan semua UPDATE yang sedang berjalan:

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

Untuk detail selengkapnya, lihat: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html

python1981
sumber
17

Saya berada dalam situasi tertentu di mana saya tidak memiliki izin untuk menghidupkan logging, dan tidak akan memiliki izin untuk melihat log jika mereka dihidupkan. Saya tidak dapat menambahkan pemicu, tetapi saya memiliki izin untuk memanggil daftar proses tampilkan. Jadi, saya memberikan upaya terbaik dan membuat ini:

Buat skrip bash yang disebut "showsqlprocesslist":

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

Jalankan skrip:

./showsqlprocesslist > showsqlprocesslist.out &

Buntut keluaran:

tail -f showsqlprocesslist.out

Bingo bango. Meskipun tidak dibatasi, hanya membutuhkan 2-4% CPU pada kotak tempat saya menjalankannya. Saya harap mungkin ini membantu seseorang.

Michael Krauklis
sumber
Ha! Lezat. Suka.
Darth Egregious
Perlu beberapa penundaan untuk menghindari terlalu banyak keluaran verbose. Silakan lihat Edit saya.
Slyx
@Slyx terima kasih atas sarannya untuk tidur di loop. Namun, jika Anda mencari kueri yang berumur pendek dan hanya menghabiskan waktu kurang dari tidur, Anda akan berpotensi kehilangan apa yang Anda cari. Jika Anda benar-benar hanya mencari snapshot dalam waktu, ini tidak boleh dijalankan dalam satu lingkaran. Perlu juga dicatat bahwa ini masih berpotensi melewatkan pertanyaan yang sangat singkat.
Michael Krauklis
17

strace

Cara tercepat untuk melihat permintaan langsung MySQL / MariaDB adalah dengan menggunakan debugger. Di Linux Anda dapat menggunakan strace, misalnya:

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

Karena ada banyak karakter yang lolos, Anda dapat memformat output strace dengan memipet (cukup tambahkan |antara dua satu-liner) di atas ke dalam perintah berikut:

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"

Jadi Anda akan melihat pertanyaan SQL yang cukup bersih tanpa waktu, tanpa menyentuh file konfigurasi.

Jelas ini tidak akan menggantikan cara standar untuk mengaktifkan log, yang dijelaskan di bawah ini (yang melibatkan memuat ulang server SQL).

dtrace

Gunakan probe MySQL untuk melihat permintaan langsung MySQL tanpa menyentuh server. Skrip contoh:

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

Simpan skrip di atas ke file (seperti watch.d), dan jalankan:

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

Pelajari lebih lanjut: Memulai dengan DTracing MySQL

Gibbs MySQL Spyglass

Lihat jawaban ini .

Log

Berikut adalah langkah-langkah yang berguna untuk proposal pengembangan.

Tambahkan baris ini ke dalam ~/.my.cnfatau global Anda my.cnf:

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

Jalur: /var/log/mysqld.logatau /usr/local/var/log/mysqld.logmungkin juga berfungsi tergantung pada izin file Anda.

kemudian restart MySQL / MariaDB Anda dengan (awalan dengan sudojika perlu):

killall -HUP mysqld

Kemudian periksa log Anda:

tail -f /tmp/mysqld.log

Setelah selesai, perubahan general_logke 0(sehingga Anda dapat menggunakannya di masa depan), kemudian hapus file dan me-restart SQL Server lagi: killall -HUP mysqld.

kenorb
sumber
1
Tidak perlu mematikan server jika Anda menyetel general_logdari kueri MySQL. Itu akan mulai menulis ke file yang general_log_filemenunjuk ke.
Robert Brisita
15

Ini adalah pengaturan termudah pada mesin Linux Ubuntu yang saya temui. Gila melihat semua pertanyaan langsung.

Temukan dan buka file konfigurasi MySQL Anda, biasanya /etc/mysql/my.cnf di Ubuntu. Cari bagian yang mengatakan "Penebangan dan Replikasi"

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

Batalkan komentar pada variabel "log" untuk menghidupkan logging. Mulai ulang MySQL dengan perintah ini:

sudo /etc/init.d/mysql restart

Sekarang kita siap untuk mulai memantau permintaan ketika mereka masuk. Buka terminal baru dan jalankan perintah ini untuk menggulir file log, menyesuaikan jalur jika perlu.

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

Sekarang jalankan aplikasi Anda. Anda akan melihat permintaan basis data mulai terbang di jendela terminal Anda. (pastikan Anda telah mengaktifkan scrolling dan history pada terminal)

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

Wil
sumber
13

Dari baris perintah Anda dapat menjalankan:

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

Ganti nilai [x] dengan nilai Anda.

Atau lebih baik lagi:

 mysqladmin -u root -p -i 1 processlist;
berulang
sumber
1
Ini sebenarnya cuplikan yang sangat bagus yang mungkin berguna .. Terima kasih!
MGP
persis apa yang saya cari !! jam tangan harus dipasang secara terpisah.
Tilo
12

Lihatlah mtop .

Chris KL
sumber
1
Ya, tapi semoga berhasil menginstalnya di Debian atau Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner
Berhasil membuatnya berjalan di debian, tetapi jenisnya tidak berharga karena melewatkan banyak pertanyaan. Saya dapat melihat penghitung kueri terus naik tetapi jarang menampilkan kueri. Sepertinya itu hanya menampilkan permintaan yang membutuhkan waktu lebih dari sekitar 1 detik.
Cobra_Fast
@Cobra_Fast dengan jelas dinyatakan di halaman Sourceforge mtop: mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete. mtop.sourceforge.net Terkadang cukup berguna.
Ian Lewis
7

Saya sudah mencari untuk melakukan hal yang sama, dan telah mengumpulkan solusi dari berbagai posting, ditambah membuat aplikasi konsol kecil untuk menampilkan teks permintaan langsung seperti yang ditulis ke file log. Ini penting dalam kasus saya karena saya menggunakan Entity Framework dengan MySQL dan saya harus dapat memeriksa SQL yang dihasilkan.

Langkah-langkah untuk membuat file log (beberapa duplikasi posting lain, semuanya di sini untuk kesederhanaan):

  1. Edit file yang terletak di:

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

    Tambahkan "log = development.log" ke bagian bawah file. (Catatan menyimpan file ini mengharuskan saya untuk menjalankan editor teks saya sebagai admin).

  2. Gunakan meja kerja MySql untuk membuka baris perintah, masukkan kata sandi.

    Jalankan berikut ini untuk mengaktifkan pencatatan umum yang akan mencatat semua kueri yang dijalankan:

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

    Ini akan menyebabkan kueri yang sedang berjalan ditulis ke file teks di lokasi berikut.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. Buat / Jalankan aplikasi konsol yang akan menampilkan informasi log secara real time:

    Sumber tersedia untuk diunduh di sini

    Sumber:

    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);
            }
        }
      }
    }
gb2d
sumber
1
Ini terlihat sangat keren dan saya pasti akan melihatnya, senang untuk mengambil ini sebagai proyek OSS dan membuat alat profil!
Rippo
Saya pikir itu ide yang bagus. Saya telah meletakkan repo SVN di kode google. Mungkin proyek OS terkecil yang pernah ada, tetapi sejauh ini sangat bermanfaat. Saya mungkin akan memperpanjangnya, tertarik untuk melihat apakah ada orang lain yang mengambilnya lebih lanjut. code.google.com/p/livelogs
gb2d
OP membutuhkannya untuk bekerja pada mesin Linux-nya. Sepertinya jawaban Anda ditujukan untuk mesin Windows. Meskipun jawaban ini mencerminkan kreativitas, itu mungkin tidak bermanfaat bagi orang lain.
halfpastfour.am
1

Selain jawaban sebelumnya yang menjelaskan cara mengaktifkan pencatatan umum, saya harus memodifikasi satu variabel tambahan di instalasi vanilla MySql 5.6 saya sebelum SQL ditulis ke log:

SET GLOBAL log_output = 'FILE';

Pengaturan default adalah 'NONE'.

David B
sumber
0

Gibbs MySQL Spyglass

AgilData baru-baru ini meluncurkan Gibbs MySQL Scalability Advisor (alat swalayan gratis) yang memungkinkan pengguna untuk menangkap streaming langsung kueri yang akan diunggah ke Gibbs. Spyglass (yang merupakan Open Source) akan menonton interaksi antara Server MySQL Anda dan aplikasi klien. Tidak diperlukan konfigurasi ulang atau restart server database MySQL (baik klien atau aplikasi).

GitHub: AgilData / gibbs-mysql-spyglass

Pelajari lebih lanjut: Paket Menangkap MySQL dengan Rust

Instal perintah:

curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash
kenorb
sumber
2
Spyglass tampaknya memerlukan kunci API dari server yang sedang down, dan komit terakhir adalah 3 tahun yang lalu. Tidak yakin produk ini masih didukung / berfungsi.
Dan Tenenbaum