Leistungsprobleme sind häufige Probleme bei der Verwaltung von MySQL-Datenbanken. Manchmal sind diese Probleme tatsächlich auf langsame Abfragen zurückzuführen. In diesem Blog befassen wir uns mit langsamen Abfragen und wie Sie diese identifizieren können.
Überprüfen Sie Ihre Protokolle für langsame Abfragen
MySQL kann langsame Abfragen filtern und protokollieren. Es gibt verschiedene Möglichkeiten, diese zu untersuchen, aber die gebräuchlichste und effizienteste Methode ist die Verwendung der Protokolle für langsame Abfragen.
Sie müssen zuerst feststellen, ob Ihre Protokolle für langsame Abfragen aktiviert sind. Um damit umzugehen, können Sie zu Ihrem Server gehen und die folgende Variable abfragen:
MariaDB [(none)]> show global variables like 'slow%log%';
+---------------------+-------------------------------+
| Variable_name | Value |
+---------------------+-------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /var/log/mysql/mysql-slow.log |
+---------------------+-------------------------------+
2 rows in set (0.001 sec)
Sie müssen sicherstellen, dass die Variable slow_query_log auf ON gesetzt ist, während die slow_query_log_file den Pfad bestimmt, in dem Sie Ihre langsamen Abfrageprotokolle platzieren müssen. Wenn diese Variable nicht gesetzt ist, wird sie das DATA_DIR Ihres MySQL-Datenverzeichnisses verwenden.
Von der Slow_query_log-Variablen begleitet sind long_query_time und min_examined_row_limit, die sich auf die Funktionsweise der langsamen Abfrageprotokollierung auswirken. Grundsätzlich funktionieren die Protokolle für langsame Abfragen als SQL-Anweisungen, deren Ausführung länger als long_query_time Sekunden dauert und die außerdem mindestens min_examined_row_limit Zeilen untersuchen müssen. Es kann verwendet werden, um Abfragen zu finden, deren Ausführung viel Zeit in Anspruch nimmt und die daher Kandidaten für eine Optimierung sind, und dann können Sie externe Tools verwenden, um den Bericht für Sie zu erstellen, auf den später eingegangen wird.
Standardmäßig fallen Verwaltungsanweisungen (ALTER TABLE, ANALYZE TABLE, CHECK TABLE, CREATE INDEX, DROP INDEX, OPTIMIZE TABLE und REPAIR TABLE) nicht in langsame Abfrageprotokolle. Dazu müssen Sie die Variable log_slow_admin_statements aktivieren.
Prozessliste und InnoDB-Statusmonitor abfragen
In einer normalen DBA-Routine ist dieser Schritt die häufigste Methode, um Abfragen mit langer oder aktiver Ausführung zu ermitteln, die zu Leistungseinbußen führen. Es kann sogar dazu führen, dass Ihr Server hängen bleibt, gefolgt von gestapelten Warteschlangen, die sich aufgrund einer Sperre, die von einer laufenden Abfrage abgedeckt wird, langsam vergrößern. Sie können einfach laufen,
SHOW [FULL] PROCESSLIST;
oder
SHOW ENGINE INNODB STATUS \G
Wenn Sie ClusterControl verwenden, können Sie es finden, indem Sie
oder mit
MySQL-Anfragen analysieren
Die Protokolle zu langsamen Abfragen zeigen Ihnen eine Liste von Abfragen, die als langsam identifiziert wurden, basierend auf den angegebenen Werten in den Systemvariablen, wie zuvor erwähnt. Die Definition langsamer Abfragen kann in verschiedenen Fällen unterschiedlich sein, da es bestimmte Fälle gibt, in denen sogar eine 10-Sekunden-Abfrage akzeptabel und immer noch nicht langsam ist. Wenn es sich bei Ihrer Anwendung jedoch um ein OLTP handelt, ist es sehr üblich, dass eine 10- oder sogar 5-Sekunden-Abfrage ein Problem darstellt oder die Leistung Ihrer Datenbank beeinträchtigt. Das MySQL-Abfrageprotokoll hilft Ihnen dabei, aber es reicht nicht aus, die Protokolldatei zu öffnen, da es Ihnen keinen Überblick darüber gibt, was diese Abfragen sind, wie sie funktionieren und wie häufig sie auftreten. Daher können Ihnen Tools von Drittanbietern dabei helfen.
pt-query-digest
Die Verwendung von Percona Toolkit, das meiner Meinung nach am häufigsten verwendete DBA-Tool ist, pt-query-digest zu verwenden. pt-query-digest bietet Ihnen einen sauberen Überblick über einen bestimmten Bericht, der aus Ihrem Protokoll für langsame Abfragen stammt. Dieser spezifische Bericht zeigt beispielsweise eine saubere Perspektive zum Verständnis der Berichte zu langsamen Abfragen in einem bestimmten Knoten:
# A software update is available:
# 100ms user time, 100ms system time, 29.12M rss, 242.41M vsz
# Current date: Mon Feb 3 20:26:11 2020
# Hostname: testnode7
# Files: /var/log/mysql/mysql-slow.log
# Overall: 24 total, 14 unique, 0.00 QPS, 0.02x concurrency ______________
# Time range: 2019-12-12T10:01:16 to 2019-12-12T15:31:46
# Attribute total min max avg 95% stddev median
# ============ ======= ======= ======= ======= ======= ======= =======
# Exec time 345s 1s 98s 14s 30s 19s 7s
# Lock time 1s 0 1s 58ms 24ms 252ms 786us
# Rows sent 5.72M 0 1.91M 244.14k 1.86M 629.44k 0
# Rows examine 15.26M 0 1.91M 651.23k 1.86M 710.58k 961.27k
# Rows affecte 9.54M 0 1.91M 406.90k 961.27k 546.96k 0
# Bytes sent 305.81M 11 124.83M 12.74M 87.73M 33.48M 56.92
# Query size 1.20k 25 244 51.17 59.77 40.60 38.53
# Profile
# Rank Query ID Response time Calls R/Call V/M
# ==== ================================ ============= ===== ======= =====
# 1 0x00C8412332B2795DADF0E55C163... 98.0337 28.4% 1 98.0337 0.00 UPDATE sbtest?
# 2 0xDEF289292EA9B2602DC12F70C7A... 74.1314 21.5% 3 24.7105 6.34 ALTER TABLE sbtest? sbtest3
# 3 0x148D575F62575A20AB9E67E41C3... 37.3039 10.8% 6 6.2173 0.23 INSERT SELECT sbtest? sbtest
# 4 0xD76A930681F1B4CC9F748B4398B... 32.8019 9.5% 3 10.9340 4.24 SELECT sbtest?
# 5 0x7B9A47FF6967FD905289042DD3B... 20.6685 6.0% 1 20.6685 0.00 ALTER TABLE sbtest? sbtest3
# 6 0xD1834E96EEFF8AC871D51192D8F... 19.0787 5.5% 1 19.0787 0.00 CREATE
# 7 0x2112E77F825903ED18028C7EA76... 18.7133 5.4% 1 18.7133 0.00 ALTER TABLE sbtest? sbtest3
# 8 0xC37F2569578627487D948026820... 15.0177 4.3% 2 7.5088 0.00 INSERT SELECT sbtest? sbtest
# 9 0xDE43B2066A66AFA881D6D45C188... 13.7180 4.0% 1 13.7180 0.00 ALTER TABLE sbtest? sbtest3
# MISC 0xMISC 15.8605 4.6% 5 3.1721 0.0 <5 ITEMS>
# Query 1: 0 QPS, 0x concurrency, ID 0x00C8412332B2795DADF0E55C1631626D at byte 5319
# Scores: V/M = 0.00
# Time range: all events occurred at 2019-12-12T13:23:15
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 4 1
# Exec time 28 98s 98s 98s 98s 98s 0 98s
# Lock time 1 25ms 25ms 25ms 25ms 25ms 0 25ms
# Rows sent 0 0 0 0 0 0 0 0
# Rows examine 12 1.91M 1.91M 1.91M 1.91M 1.91M 0 1.91M
# Rows affecte 20 1.91M 1.91M 1.91M 1.91M 1.91M 0 1.91M
# Bytes sent 0 67 67 67 67 67 0 67
# Query size 7 89 89 89 89 89 0 89
# String:
# Databases test
# Hosts localhost
# Last errno 0
# Users root
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms
# 1s
# 10s+ ################################################################
# Tables
# SHOW TABLE STATUS FROM `test` LIKE 'sbtest3'\G
# SHOW CREATE TABLE `test`.`sbtest3`\G
update sbtest3 set c=substring(MD5(RAND()), -16), pad=substring(MD5(RAND()), -16) where 1\G
# Converted for EXPLAIN
# EXPLAIN /*!50100 PARTITIONS*/
select c=substring(MD5(RAND()), -16), pad=substring(MD5(RAND()), -16) from sbtest3 where 1\G
# Query 2: 0.00 QPS, 0.01x concurrency, ID 0xDEF289292EA9B2602DC12F70C7A041A9 at byte 3775
# Scores: V/M = 6.34
# Time range: 2019-12-12T12:41:47 to 2019-12-12T15:25:14
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 12 3
# Exec time 21 74s 6s 36s 25s 35s 13s 30s
# Lock time 0 13ms 1ms 8ms 4ms 8ms 3ms 3ms
# Rows sent 0 0 0 0 0 0 0 0
# Rows examine 0 0 0 0 0 0 0 0
# Rows affecte 0 0 0 0 0 0 0 0
# Bytes sent 0 144 44 50 48 49.17 3 49.17
# Query size 8 99 33 33 33 33 0 33
# String:
# Databases test
# Hosts localhost
# Last errno 0 (2/66%), 1317 (1/33%)
# Users root
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms
# 1s ################################
# 10s+ ################################################################
# Tables
# SHOW TABLE STATUS FROM `test` LIKE 'sbtest3'\G
# SHOW CREATE TABLE `test`.`sbtest3`\G
ALTER TABLE sbtest3 ENGINE=INNODB\G
Performance_schema verwenden
Langsame Abfrageprotokolle können ein Problem darstellen, wenn Sie keinen direkten Zugriff auf die Datei haben, z. B. wenn Sie RDS verwenden oder vollständig verwaltete Datenbankdienste wie Google Cloud SQL oder Azure SQL verwenden. Obwohl Sie möglicherweise einige Variablen benötigen, um diese Funktionen zu aktivieren, ist es praktisch, wenn Sie nach Abfragen suchen, die in Ihrem System angemeldet sind. Sie können es bestellen, indem Sie eine Standard-SQL-Anweisung verwenden, um ein Teilergebnis abzurufen. Zum Beispiel
mysql> SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_TIMER_WAIT/1000000000000 SUM_TIMER_WAIT_SEC, MIN_TIMER_WAIT/1000000000000 MIN_TIMER_WAIT_SEC, AVG_TIMER_WAIT/1000000000000 AVG_TIMER_WAIT_SEC, MAX_TIMER_WAIT/1000000000000 MAX_TIMER_WAIT_SEC, SUM_LOCK_TIME/1000000000000 SUM_LOCK_TIME_SEC, FIRST_SEEN, LAST_SEEN FROM events_statements_summary_by_digest;
+--------------------+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+--------------------+--------------------+--------------------+--------------------+-------------------+---------------------+---------------------+
| SCHEMA_NAME | DIGEST | DIGEST_TEXT | COUNT_STAR | SUM_TIMER_WAIT_SEC | MIN_TIMER_WAIT_SEC | AVG_TIMER_WAIT_SEC | MAX_TIMER_WAIT_SEC | SUM_LOCK_TIME_SEC | FIRST_SEEN | LAST_SEEN |
+--------------------+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+--------------------+--------------------+--------------------+--------------------+-------------------+---------------------+---------------------+
| NULL | 390669f3d1f72317dab6deb40322d119 | SELECT @@`skip_networking` , @@`skip_name_resolve` , @@`have_ssl` = ? , @@`ssl_key` , @@`ssl_ca` , @@`ssl_capath` , @@`ssl_cert` , @@`ssl_cipher` , @@`ssl_crl` , @@`ssl_crlpath` , @@`tls_version` | 1 | 0.0373 | 0.0373 | 0.0373 | 0.0373 | 0.0000 | 2020-02-03 20:22:54 | 2020-02-03 20:22:54 |
| NULL | fba95d44e3d0a9802dd534c782314352 | SELECT `UNIX_TIMESTAMP` ( ) | 2 | 0.0002 | 0.0001 | 0.0001 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | 18c649da485456d6cdf12e4e6b0350e9 | SELECT @@GLOBAL . `SERVER_ID` | 2 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | dd356b8a5a6ed0d7aee2abd939cdb6c9 | SET @? = ? | 6 | 0.0003 | 0.0000 | 0.0001 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | 1c5ae643e930af6d069845d74729760d | SET @? = @@GLOBAL . `binlog_checksum` | 2 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | ad5208ffa004a6ad7e26011b73cbfb4c | SELECT @? | 2 | 0.0001 | 0.0000 | 0.0000 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | ed0d1eb982c106d4231b816539652907 | SELECT @@GLOBAL . `GTID_MODE` | 2 | 0.0001 | 0.0000 | 0.0000 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | cb47e22372fdd4441486b02c133fb94f | SELECT @@GLOBAL . `SERVER_UUID` | 2 | 0.0001 | 0.0000 | 0.0000 | 0.0001 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | 73301368c301db5d2e3db5626a21b647 | SELECT @@GLOBAL . `rpl_semi_sync_master_enabled` | 2 | 0.0001 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 2020-02-03 20:22:57 | 2020-02-03 20:23:00 |
| NULL | 0ff7375c5f076ba5c040e78a9250a659 | SELECT @@`version_comment` LIMIT ? | 1 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0000 | 2020-02-03 20:45:59 | 2020-02-03 20:45:59 |
| NULL | 5820f411e67a393f987c6be5d81a011d | SHOW TABLES FROM `performance_schema` | 1 | 0.0008 | 0.0008 | 0.0008 | 0.0008 | 0.0002 | 2020-02-03 20:46:11 | 2020-02-03 20:46:11 |
| NULL | a022a0ab966c51eb820da1521349c7ef | SELECT SCHEMA ( ) | 1 | 0.0005 | 0.0005 | 0.0005 | 0.0005 | 0.0000 | 2020-02-03 20:46:29 | 2020-02-03 20:46:29 |
| performance_schema | e4833a7c1365b0b4492e9a514f7b3bd4 | SHOW SCHEMAS | 1 | 0.1167 | 0.1167 | 0.1167 | 0.1167 | 0.0001 | 2020-02-03 20:46:29 | 2020-02-03 20:46:29 |
| performance_schema | 1107f048fe6d970cb6a553bd4727a1b4 | SHOW TABLES | 1 | 0.0002 | 0.0002 | 0.0002 | 0.0002 | 0.0000 | 2020-02-03 20:46:29 | 2020-02-03 20:46:29 |
...
Sie können die Tabelle performance_schema.events_statements_summary_by_digest verwenden. Obwohl es möglich ist, dass die Einträge in den Tabellen von performance_schema bündig sind, können Sie sich dafür entscheiden, dies in einer bestimmten Tabelle zu speichern. Werfen Sie einen Blick auf diesen externen Post von Percona MySQL Query Digest with Performance Schema.
Falls Sie sich fragen, warum wir die Wartezeitspalten teilen müssen (SUM_TIMER_WAIT, MIN_TIMER_WAIT_SEC, AVG_TIMER_WAIT_SEC), diese Spalten verwenden Pikosekunden, sodass Sie möglicherweise etwas rechnen oder aufrunden müssen es besser lesbar für Sie.
Langsame Abfragen mit ClusterControl analysieren
Wenn Sie ClusterControl verwenden, gibt es verschiedene Möglichkeiten, damit umzugehen. In einem MariaDB-Cluster, den ich unten habe, zeigt es Ihnen beispielsweise die folgende Registerkarte (Query Monitor) und seine Dropdown-Elemente (Top Queries, Running Queries, Query Outliers):
- Top-Abfragen – aggregierte Liste aller Ihrer Top-Abfragen, die auf allen Knoten Ihres Datenbank-Clusters ausgeführt werden
- Laufende Abfragen – Zeigen Sie aktuell laufende Abfragen auf Ihrem Datenbank-Cluster an, ähnlich dem SHOW FULL PROCESSLIST-Befehl in MySQL
- Abfrageausreißer – Zeigt Abfragen an, die Ausreißer sind. Ein Ausreißer ist eine Abfrage, die länger dauert als die normale Abfrage dieses Typs.
Darüber hinaus erfasst ClusterControl auch die Abfrageleistung mithilfe von Diagrammen, die Ihnen einen schnellen Überblick darüber geben, wie Ihr Datenbanksystem in Bezug auf die Abfrageleistung abschneidet. Siehe unten,
Warte, es ist noch nicht vorbei. ClusterControl bietet auch eine hochauflösende Metrik mit Prometheus und zeigt sehr detaillierte Metriken und erfasst Echtzeitstatistiken vom Server. Wir haben dies in unseren vorherigen Blogs besprochen, die in zwei Blog-Teilserien unterteilt sind. Schauen Sie sich Teil 1 und dann die Blogs zu Teil 2 an. Es bietet Ihnen Möglichkeiten, nicht nur die langsamen Abfragen, sondern die Gesamtleistung Ihrer MySQL-, MariaDB- oder Percona-Datenbankserver effizient zu überwachen.
Es gibt auch andere Tools in ClusterControl, die Hinweise und Hinweise liefern, die eine langsame Abfrageleistung verursachen können, selbst wenn dies noch nicht aufgetreten ist oder vom Protokoll für langsame Abfragen erfasst wurde. Sehen Sie sich die Registerkarte "Leistung" an, wie unten gezeigt,
diese Elemente bieten Ihnen Folgendes:
- Übersicht - Auf dieser Seite können Sie Diagramme verschiedener Datenbankzähler anzeigen
- Advisors – Listen der Ergebnisse geplanter Advisors, die in ClusterControl> Manage> Developer Studio mit ClusterControl DSL erstellt wurden.
- DB-Status – Der DB-Status bietet einen schnellen Überblick über den MySQL-Status über alle Ihre Datenbankknoten hinweg, ähnlich der SHOW STATUS-Anweisung
- DB-Variablen – DB-Variablen bieten einen schnellen Überblick über MySQL-Variablen, die über alle Ihre Datenbankknoten hinweg gesetzt sind, ähnlich der SHOW GLOBAL VARIABLES-Anweisung
- DB-Wachstum – Bietet eine Zusammenfassung Ihres Datenbank- und Tabellenwachstums auf täglicher Basis für die letzten 30 Tage.
- InnoDB-Status – Ruft die aktuelle Ausgabe des InnoDB-Monitors für den ausgewählten Host ab, ähnlich dem Befehl SHOW ENGINE INNODB STATUS.
- Schema Analyzer - Analysiert Ihre Datenbankschemata auf fehlende Primärschlüssel, redundante Indizes und Tabellen mithilfe der MyISAM-Speicher-Engine.
- Transaktionsprotokoll – Listet Transaktionen mit langer Laufzeit und Deadlocks im gesamten Datenbank-Cluster auf, wo Sie leicht sehen können, welche Transaktionen die Deadlocks verursachen. Der Standardschwellenwert für die Abfragezeit beträgt 30 Sekunden.
Fazit
Das Nachverfolgen Ihres MySQL-Leistungsproblems ist mit MySQL nicht wirklich schwierig. Es gibt verschiedene externe Tools, die Ihnen die Effizienz und die Fähigkeiten bieten, nach denen Sie suchen. Das Wichtigste ist, dass es einfach zu bedienen ist und Sie in der Lage sind, Produktivität bei der Arbeit zu bieten. Beheben Sie die ausstehenden Probleme oder vermeiden Sie sogar eine bestimmte Katastrophe, bevor sie passieren kann.