Ist es sicher, ANALYZE TABLE auf MySQL- und Mainstream-Zweigversionen auszuführen?

Manchmal ist es notwendig, Tabellen- und Indexstatistiken manuell mit dem Befehl ANALYZE TABLE zu aktualisieren. Ohne weiter auf die Gründe für diese Notwendigkeit einzugehen, möchte ich das Thema im Hinblick auf den Mehraufwand ansprechen, der mit der Ausführung von Befehlen auf einem Produktionssystem verbunden ist. Der hier besprochene Mehraufwand ist jedoch unabhängig von den üblichen Kosten für den Drilldown in Tabellenzeilen zum Sammeln von Statistiken, die wir durch Festlegen der Anzahl der Beispielseiten steuern können .

Vor fünf Jahren veröffentlichte meine Kollegin Sveta einen schönen Blogbeitrag über eine Verbesserung, die in Percona Server für MySQL eingeführt wurde, um unnötige Wartezeiten zu vermeiden:

„ANALYZE TABLE ist kein blockierender Vorgang mehr“

In der Vergangenheit bestand das Problem bei der Ausführung des Befehls ANALYZE TABLE in MySQL darin, dass die Abfrage eine exklusive Sperre für den Tabellendefinitions-Cache-Eintrag der Tabelle erforderte. Dies führt dazu, dass die Abfrage auf den Abschluss lang laufender Abfragen wartet, kann aber auch eine Kaskade von Wartezeiten auf andere eingehende Anforderungen auslösen. Kurz gesagt, ANALYZE kann in Produktionsumgebungen mit hoher Auslastung zu höheren Latenzen führen.

MySQL/Percona/MariaDB haben seitdem alle einige Änderungen erfahren, aber es gibt auch heute noch Versionen, die viele Produktionssysteme betreffen. Werfen wir einen Blick zurück auf die Entwicklung der Dinge im Laufe der Jahre.

MySQL

Dieses Problem betrifft alle MySQL-Versionen vor 8.0.23. Es gibt keine Verbesserungen für die 5.7-Serie (die übrigens diesen Monat ihr EOL erreichen wird!), was bedeutet, dass sogar die neueste Version 5.7.43 betroffen sein wird. Hier sind Beispielszenarien, denen Sie begegnen könnten:

mysql > select @@version,@@version_comment;
+-----------+------------------------------+
| @@version | @@version_comment            |
+-----------+------------------------------+
| 5.7.43    | MySQL Community Server (GPL) |
+-----------+------------------------------+
1 row in set (0.00 sec)

mysql > show processlist;
+----+----------+-----------+------+---------+------+-------------------------+----------------------------------------------------------------+
| Id | User     | Host      | db   | Command | Time | State                   | Info                                                           |
+----+----------+-----------+------+---------+------+-------------------------+----------------------------------------------------------------+
|  4 | msandbox | localhost | db1  | Query   |   54 | Sending data            | select avg(k) from sbtest1 where pad not like '%f%' group by c |
| 13 | msandbox | localhost | db1  | Query   |   29 | Waiting for table flush | analyze table sbtest1                                          |
| 17 | msandbox | localhost | db1  | Query   |    0 | starting                | show processlist                                               |
| 18 | msandbox | localhost | db1  | Query   |   15 | Waiting for table flush | select * from sbtest1 where id=100                             |
+----+----------+-----------+------+---------+------+-------------------------+----------------------------------------------------------------+
4 rows in set (0.00 sec)

Eine langsame Abfrage führte dazu, dass ANALYZE wartete, und eine andere Abfrage, die normalerweise sehr schnell wäre, wartet jetzt ebenfalls.

Die gleiche Situation kann auch bei der MySQL 8.0-Serie, einschließlich 8.0.23, auftreten. Glücklicherweise ist dieses Problem in Version 8.0.24 behoben . In den Versionshinweisen können wir nur einige Kommentare zur Lösung dieses Problems lesen :

Tatsächlich führt ab Version 8.0.24 die Ausführung eines ähnlichen Tests während einer langsamen Abfrage zu einer sofortigen Abfrageausführung:

mysql > select @@version,@@version_comment;
+-----------+------------------------------+
| @@version | @@version_comment            |
+-----------+------------------------------+
| 8.0.24    | MySQL Community Server - GPL |
+-----------+------------------------------+
1 row in set (0.00 sec)

mysql > analyze table sbtest1;
+-------------+---------+----------+----------+
| Table       | Op      | Msg_type | Msg_text |
+-------------+---------+----------+----------+
| db1.sbtest1 | analyze | status   | OK       |
+-------------+---------+----------+----------+
1 row in set (0.00 sec)

Allerdings können wir auch mit Version 8.1 immer noch Warnungen in der offiziellen Dokumentation finden, wie folgt:

ANALYZE TABLE entfernt die Tabelle aus dem Tabellendefinitionscache, was eine Flush-Sperre erfordert. Wenn noch lange laufende Anweisungen oder Transaktionen die Tabelle verwenden, müssen nachfolgende Anweisungen und Transaktionen auf den Abschluss dieser Vorgänge warten, bevor die Flush-Sperre aufgehoben wird. Da ANALYZE TABLE selbst normalerweise schnell abgeschlossen wird, ist es möglicherweise nicht offensichtlich, dass verzögerte Transaktionen oder Anweisungen, die dieselbe Tabelle betreffen, auf die verbleibende Flush-Sperre zurückzuführen sind.

Entschuldigung

Wie oben erwähnt, hat Percona zur Behebung dieses Fehlerberichts einen Fix eingeführt und unnötige Tabellendefinitions-Cache-Sperren entfernt.

Bei Verwendung von Percona ist es bereits sicher, ANALYZE TABLE ab den Versionen 5.6.38 und 5.7.20 auszuführen, da dies zu diesem Zeitpunkt die aktiven Versionen waren.

Percona Server für MySQL Version 8.0 weist dieses Problem seit den ersten Veröffentlichungen (einschließlich der ersten GA-Version 8.0.13-3) nicht mehr auf, da Verbesserungen aus der Percona Server für MySQL 5.7- Serie zusammengeführt wurden .

MariaDB

Das Problem mit ANALYZE TABLE tritt in allen MariaDB-Versionen vor 10.5.3 auf. Percona wurde in Version 10.5.4 behoben.

Wenn Sie die Abfrage also in 10.5.3 oder niedriger und einer früheren Serie (sogar der neuesten Version 10.4.31) ausführen, erhalten Sie möglicherweise Folgendes:

mysql > select @@version,@@version_comment;
+----------------+-------------------+
| @@version      | @@version_comment |
+----------------+-------------------+
| 10.5.3-MariaDB | MariaDB Server    |
+----------------+-------------------+
1 row in set (0.000 sec)

mysql > show processlist;
+----+----------+-----------+------+---------+------+-------------------------+----------------------------------------------------------------+----------+
| Id | User     | Host      | db   | Command | Time | State                   | Info                                                           | Progress |
+----+----------+-----------+------+---------+------+-------------------------+----------------------------------------------------------------+----------+
|  4 | msandbox | localhost | db1  | Query   |   18 | Sending data            | select avg(k) from sbtest1 where pad not like '%f%' group by c |    0.000 |
| 13 | msandbox | localhost | db1  | Query   |   16 | Waiting for table flush | analyze table sbtest1                                          |    0.000 |
| 14 | msandbox | localhost | db1  | Query   |   14 | Waiting for table flush | select * from sbtest1 where id=100                             |    0.000 |
| 15 | msandbox | localhost | NULL | Query   |    0 | starting                | show processlist                                               |    0.000 |
+----+----------+-----------+------+---------+------+-------------------------+----------------------------------------------------------------+----------+
4 rows in set (0.000 sec)

mysql > select @@version,@@version_comment;
+-----------------+-------------------+
| @@version       | @@version_comment |
+-----------------+-------------------+
| 10.4.31-MariaDB | MariaDB Server    |
+-----------------+-------------------+
1 row in set (0.000 sec)

mysql > show processlist;
+----+-------------+-----------+------+---------+------+--------------------------+----------------------------------------------------------------+----------+
| Id | User        | Host      | db   | Command | Time | State                    | Info                                                           | Progress |
+----+-------------+-----------+------+---------+------+--------------------------+----------------------------------------------------------------+----------+
|  1 | system user |           | NULL | Daemon  | NULL | InnoDB purge coordinator | NULL                                                           |    0.000 |
|  2 | system user |           | NULL | Daemon  | NULL | InnoDB purge worker      | NULL                                                           |    0.000 |
|  3 | system user |           | NULL | Daemon  | NULL | InnoDB purge worker      | NULL                                                           |    0.000 |
|  4 | system user |           | NULL | Daemon  | NULL | InnoDB purge worker      | NULL                                                           |    0.000 |
|  5 | system user |           | NULL | Daemon  | NULL | InnoDB shutdown handler  | NULL                                                           |    0.000 |
|  9 | msandbox    | localhost | db1  | Query   |   18 | Sending data             | select avg(k) from sbtest1 where pad not like '%f%' group by c |    0.000 |
| 18 | msandbox    | localhost | db1  | Query   |   16 | Waiting for table flush  | analyze table sbtest1                                          |    0.000 |
| 19 | msandbox    | localhost | db1  | Query   |   12 | Waiting for table flush  | select * from sbtest1 where id=100                             |    0.000 |
| 22 | msandbox    | localhost | NULL | Query   |    0 | Init                     | show processlist                                               |    0.000 |
+----+-------------+-----------+------+---------+------+--------------------------+----------------------------------------------------------------+----------+
9 rows in set (0.000 sec)

Zusammenfassen

Solange Ihre Datenbank auf der neuesten Version von MySQL oder MariaDB läuft, sollte die Ausführung von ANALYZE TABLE absolut sicher sein und keine unerwarteten Pausen verursachen.

Benutzer von Percona Server für MySQL-Serien: 5.6.38+, 5.7.20+ und 8.0.x sind sicher.

MariaDB-Benutzer müssen auf 10.5.4 oder höher aktualisieren, um Sperrprobleme zu vermeiden.

Weitere technische Artikel finden Sie unter: https://opensource.actionsky.com/

Über SQLE

SQLE ist eine umfassende SQL-Qualitätsmanagementplattform, die die SQL-Prüfung und -Verwaltung von der Entwicklung bis zur Produktionsumgebung abdeckt. Es unterstützt gängige Open-Source-, kommerzielle und inländische Datenbanken, bietet Prozessautomatisierungsfunktionen für Entwicklung, Betrieb und Wartung, verbessert die Online-Effizienz und verbessert die Datenqualität.

SQLE erhalten

Typ Adresse
Repository https://github.com/actiontech/sqle
dokumentieren https://actiontech.github.io/sqle-docs/
Neuigkeiten veröffentlichen https://github.com/actiontech/sqle/releases
Entwicklungsdokumentation für das Datenaudit-Plug-in https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
Spring Boot 3.2.0 wird offiziell veröffentlicht. Der schwerwiegendste Servicefehler in der Geschichte von Didi. Liegt der Schuldige an der zugrunde liegenden Software oder an „Kostensenkung und zunehmendem Lachen“? Programmierer manipulierten ETC-Guthaben und veruntreuten mehr als 2,6 Millionen Yuan pro Jahr. Google-Mitarbeiter kritisierten den Big Boss, nachdem sie ihren Job aufgegeben hatten. Sie waren stark in das Flutter-Projekt involviert und formulierten HTML-bezogene Standards. Microsoft Copilot Web AI wird offiziell am eingeführt 1. Dezember, Unterstützung für chinesisches PHP 8.3 GA Firefox im Jahr 2023 Rust Web Framework Rocket ist schneller geworden und hat Version 0.5 veröffentlicht: Unterstützt asynchron, SSE, WebSockets usw. Der Desktop-Prozessor Loongson 3A6000 wird offiziell veröffentlicht, das Licht der inländischen Produktion! Broadcom gibt erfolgreiche Übernahme von VMware bekannt
{{o.name}}
{{m.name}}

おすすめ

転載: my.oschina.net/actiontechoss/blog/10310115