ฉันจะติดตามการสืบค้น MySQL บนเซิร์ฟเวอร์ Linux ของฉันได้อย่างไร
ตัวอย่างเช่นฉันชอบตั้งค่าผู้ฟังบางประเภทแล้วขอหน้าเว็บและดูข้อความค้นหาทั้งหมดที่โปรแกรมเรียกใช้หรือดูข้อความค้นหาทั้งหมดที่ทำงานอยู่บนเซิร์ฟเวอร์ที่ใช้งานจริง ฉันจะทำสิ่งนี้ได้อย่างไร
ฉันจะติดตามการสืบค้น MySQL บนเซิร์ฟเวอร์ Linux ของฉันได้อย่างไร
ตัวอย่างเช่นฉันชอบตั้งค่าผู้ฟังบางประเภทแล้วขอหน้าเว็บและดูข้อความค้นหาทั้งหมดที่โปรแกรมเรียกใช้หรือดูข้อความค้นหาทั้งหมดที่ทำงานอยู่บนเซิร์ฟเวอร์ที่ใช้งานจริง ฉันจะทำสิ่งนี้ได้อย่างไร
คำตอบ:
คุณสามารถเรียกใช้คำสั่ง MySQL SHOW FULL PROCESSLIST;
เพื่อดูว่ามีการประมวลผลข้อความค้นหาอย่างไรในเวลาที่กำหนด แต่นั่นอาจจะไม่เป็นไปตามที่คุณคาดหวัง
วิธีที่ดีที่สุดในการรับประวัติโดยไม่ต้องแก้ไขทุกแอปพลิเคชันที่ใช้เซิร์ฟเวอร์อาจเป็นทริกเกอร์ คุณสามารถตั้งค่าทริกเกอร์เพื่อให้ทุกแบบสอบถามเรียกใช้ผลลัพธ์ในแบบสอบถามที่ถูกแทรกลงในตารางเรียงลำดับบางส่วนของประวัติแล้วสร้างหน้าแยกต่างหากเพื่อเข้าถึงข้อมูลนี้
โปรดทราบว่าสิ่งนี้อาจทำให้ทุกอย่างบนเซิร์ฟเวอร์ช้าลงโดยการเพิ่มข้อความพิเศษINSERT
ทุกข้อความค้นหา
แก้ไข: อีกทางเลือกหนึ่งคือบันทึกการสืบค้นทั่วไปแต่การเขียนลงในไฟล์แบบแฟลตจะเป็นการลบความเป็นไปได้มากมายสำหรับความยืดหยุ่นในการแสดงโดยเฉพาะในแบบเรียลไทม์ หากคุณต้องการวิธีที่ง่ายและใช้งานง่ายเพื่อดูว่าเกิดอะไรขึ้นการเปิดใช้งาน GQL และการใช้งานtail -f
บน logfile จะเป็นการหลอกลวง
คุณสามารถบันทึกทุกข้อสงสัยไปยังไฟล์บันทึกได้อย่างง่ายดาย:
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';
หรือประสิทธิภาพจะลดลงและดิสก์ของคุณจะเต็ม!
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: ช่วงเวลาของฉันถูกตั้งค่าไว้ที่หนึ่งวินาทีและหากมีแบบสอบถามที่ใช้.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;
เช่นแสดง UPDATE ที่กำลังทำงานอยู่ทั้งหมด:
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND INFO LIKE '%UPDATE %';
สำหรับรายละเอียดทั้งหมดดู: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html
ฉันอยู่ในสถานการณ์เฉพาะที่ฉันไม่ได้รับอนุญาตให้เปิดการเข้าสู่ระบบและจะไม่มีสิทธิ์ในการดูบันทึกหากเปิดใช้งานอยู่ ฉันไม่สามารถเพิ่มทริกเกอร์ได้ แต่ฉันได้รับอนุญาตให้เรียกรายการแสดงกระบวนการ ดังนั้นฉันจึงใช้ความพยายามอย่างดีที่สุดและทำสิ่งนี้:
สร้างสคริปต์ทุบตีที่เรียกว่า "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
รันสคริปต์:
./showsqlprocesslist > showsqlprocesslist.out &
ตัดเอาท์พุท:
tail -f showsqlprocesslist.out
บิงโก bango แม้ว่าจะไม่ได้ควบคุมปริมาณ แต่ใช้ CPU 2-4% ในกล่องที่ฉันวิ่งเท่านั้น ฉันหวังว่านี่อาจช่วยคนได้
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 Server killall -HUP mysqld
เริ่มต้นใหม่อีกครั้ง:
general_log
จากแบบสอบถาม MySQL มันจะเริ่มเขียนไฟล์ที่general_log_file
ชี้ไป
นี่เป็นการตั้งค่าที่ง่ายที่สุดบนเครื่อง Linux Ubuntu ที่ฉันเจอ ไม่อยากดูคิวรี่ทั้งหมดอยู่
ค้นหาและเปิดไฟล์การกำหนดค่า MySQL ของคุณโดยปกติจะเป็น /etc/mysql/my.cnf บน Ubuntu ค้นหาส่วนที่ระบุว่า "การบันทึกและการจำลองแบบ"
#
# * 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
เพียงยกเลิกการใส่เครื่องหมาย "ตัวแปร" เพื่อเปิดการบันทึก รีสตาร์ท MySQL ด้วยคำสั่งนี้:
sudo /etc/init.d/mysql restart
ตอนนี้เราพร้อมที่จะเริ่มการตรวจสอบเคียวรีตามที่มาเปิดเทอร์มินัลใหม่และเรียกใช้คำสั่งนี้เพื่อเลื่อนไฟล์บันทึกการปรับเส้นทางหากจำเป็น
tail -f /var/log/mysql/mysql.log
เรียกใช้แอปพลิเคชันของคุณ คุณจะเห็นข้อความค้นหาฐานข้อมูลเริ่มต้นขึ้นในหน้าต่างเทอร์มินัลของคุณ (ตรวจสอบให้แน่ใจว่าคุณได้เลื่อนและเปิดใช้งานประวัติบนเทอร์มินัล)
จากhttp://www.howtogeek.com/howto/database/monitor-all-sql-queries-in-mysql/
จากบรรทัดคำสั่งคุณสามารถเรียกใช้:
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;
mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete.
mtop.sourceforge.netมันมีประโยชน์บ้างในบางครั้ง
ฉันกำลังมองหาที่จะทำเช่นเดียวกันและมี cobbled ร่วมกันแก้ปัญหาจากการโพสต์ต่าง ๆ รวมทั้งสร้างแอปคอนโซลขนาดเล็กเพื่อส่งออกข้อความแบบสอบถามสดขณะที่มันถูกเขียนไปยังไฟล์บันทึก นี่เป็นสิ่งสำคัญในกรณีของฉันเนื่องจากฉันใช้ Entity Framework กับ MySQL และฉันต้องสามารถตรวจสอบ SQL ที่สร้างขึ้นได้
ขั้นตอนในการสร้างไฟล์บันทึก (การทำซ้ำโพสต์อื่น ๆ ทั้งหมดที่นี่เพื่อความเรียบง่าย):
แก้ไขไฟล์ที่อยู่ที่:
C:\Program Files (x86)\MySQL\MySQL Server 5.5\my.ini
เพิ่ม "log = development.log" ที่ด้านล่างของไฟล์ (หมายเหตุการบันทึกไฟล์นี้ทำให้ฉันต้องเรียกใช้ตัวแก้ไขข้อความในฐานะผู้ดูแลระบบ)
ใช้ MySql workbench เพื่อเปิดบรรทัดคำสั่งป้อนรหัสผ่าน
เรียกใช้ต่อไปนี้เพื่อเปิดการบันทึกทั่วไปซึ่งจะบันทึกการสืบค้นทั้งหมดที่ทำงาน:
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);
}
}
}
}
นอกเหนือจากคำตอบก่อนหน้านี้ที่อธิบายถึงวิธีการเปิดใช้งานการบันทึกทั่วไปฉันต้องแก้ไขตัวแปรเพิ่มเติมหนึ่งตัวในการติดตั้ง vanilla MySql 5.6 ของฉันก่อนที่จะเขียน SQL ลงในบันทึก:
SET GLOBAL log_output = 'FILE';
การตั้งค่าเริ่มต้นคือ 'ไม่มี'
AgilData เปิดตัวเมื่อเร็ว ๆ นี้Gibbs MySQL Scalability Advisor (เครื่องมือบริการตนเองฟรี) ซึ่งช่วยให้ผู้ใช้สามารถจับภาพสตรีมมิ่งคำถามที่จะอัปโหลดไปยัง Gibbs Spyglass (ซึ่งเป็นโอเพ่นซอร์ส) จะรับชมการมีปฏิสัมพันธ์ระหว่างเซิร์ฟเวอร์ MySQL ของคุณและแอปพลิเคชันไคลเอนต์ ไม่จำเป็นต้องกำหนดค่าใหม่หรือรีสตาร์ทเซิร์ฟเวอร์ฐานข้อมูล MySQL (ไคลเอนต์หรือแอป)
GitHub: AgilData / gibbs-mysql-spyglass
เรียนรู้เพิ่มเติม: การจับแพ็คเก็ต MySQL ด้วยสนิม
ติดตั้งคำสั่ง:
curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash