Eine hohe CPU-Auslastung in einer Instanz kann durch verschiedene Gründe verursacht werden, z. B. eine Erhöhung der Arbeitslasten, umfangreiche Transaktionen, langsame Abfragen und lang andauernde Transaktionen.
Der Recommender für unterdimensionierte Instanzen analysiert die CPU-Auslastung. Wenn die CPU-Auslastung in den letzten 30 Tagen für einen beträchtlichen Zeitraum bei oder über 95% gelegen hat, benachrichtigt Sie der Recommender und bietet Ihnen zusätzliche Informationen, um das Problem zu beheben.
In diesem Dokument wird erläutert, wie Sie eine Cloud SQL for MySQL-Instanz prüfen und optimieren, wenn diese Instanz laut dem Recommender für unterdimensionierte Instanzen eine hohe CPU-Auslastung hat.
Empfehlungen
Die CPU-Auslastung steigt proportional mit der Arbeitslast. Prüfen Sie die laufenden Abfragen und optimieren Sie sie, um die CPU-Auslastung zu reduzieren. Hier sind einige Schritte zum Prüfen des CPU-Verbrauchs.
Prüfen Sie
Threads_running
undThreads_connected
.Verwenden Sie die folgende Abfrage, um die Anzahl der aktiven Threads zu sehen:
> SHOW STATUS like 'Threads_%';
Threads_running
ist eine Teilmenge vonThreads_connected
. Die restlichen Threads sind inaktiv. Eine Erhöhung vonThreads_running
würde zu einer Erhöhung der CPU-Nutzung führen. Es empfiehlt sich zu prüfen, was in diesen Threads ausgeführt wird.Abfragestatus prüfen
Führen Sie den Befehl
SHOW PROCESSLIST
aus, um die laufenden Abfragen zu sehen. Er gibt der Reihe nach alle verbundenen Threads sowie ihre aktuell ausgeführte SQL-Anweisung zurück.mysql> SHOW [FULL] PROCESSLIST;
Achten Sie auf die Spalten für den Status und die Dauer. Prüfen Sie, ob viele Abfragen im selben Status festhängen.
- Wenn für viele Threads
Updating
angezeigt wird, kann es zu Konflikten durch Datensatzsperren kommen. Fahren Sie mit dem nächsten Schritt fort. - Wenn bei vielen Threads
Waiting
für die Tabellenmetadatensperre angezeigt wird, prüfen Sie die Abfrage, um die Tabelle zu bestimmen, und suchen Sie nach einer DDL (z. B.ALTER TABLE
), die die Metadatensperre verursachen könnte. Eine DDL wartet möglicherweise auch auf eine Tabellenmetadatensperre, wenn eine frühzeitige Abfrage, z. B. ein lang andauerndesSELECT query
, sie verursacht.
- Wenn für viele Threads
Auf Konflikte durch Datensatzsperren prüfen
Wenn Transaktionen Sperren für beliebte Indexdatensätze verursachen, blockieren sie andere Transaktionen, die dieselben Sperren anfordern. Dies kann zu einer verketteten Wirkung und zu einer Reihe von Anfragen führen, die hängen bleiben, und den Wert von
Threads_running
erhöhen. Verwenden Sie die Tabelleinformation_schema.innodb_lock_waits
, um Sperrenkonflikte zu diagnostizieren.Die folgende Abfrage listet jede blockierende Transaktion und die Anzahl der zugehörigen blockierten Transaktionen auf.
SELECT t.trx_id, t.trx_state, t.trx_started, COUNT(distinct w.requesting_trx_id) AS blocked_trxs FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx t ON t.trx_id = w.blocking_trx_id GROUP BY t.trx_id,t.trx_state, t.trx_started ORDER BY t.trx_id;
Sowohl eine einzelne große DML als auch viele gleichzeitige kleine DML können zu Zeilensperrenkonflikten führen. Dies können Sie auf der Anwendungsseite mit den folgenden Schritten optimieren:
- Vermeiden Sie lange Transaktionen, da Zeilensperren beibehalten werden, bis die Transaktion endet.
- Teilen Sie eine einzelne große DML in kleine DMLs auf.
- Teilen Sie eine einzelne Zeilen-DML in kleine Blöcke auf.
- Minimieren Sie Konflikte zwischen Threads. Wenn der Anwendungscode beispielsweise einen Verbindungspool verwendet, weisen Sie demselben Thread einen ID-Bereich zu.
Lang andauernde Transaktionen ermitteln
SHOW ENGINE INNODB STATUS
verwendenIm Bereich TRANSAKTIONEN werden alle offenen Transaktionen von der neuesten zur ältesten sortiert angezeigt.
mysql> SHOW ENGINE INNODB STATUS\G …… ------------ TRANSACTIONS ------------ … ---TRANSACTION 245762, ACTIVE 262 sec 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1 MySQL thread id 9210, OS thread handle 140262286128896, query id 202218 localhost root
Beginnen Sie mit den ältesten Transaktionen und suchen Sie nach Antworten auf die folgenden Fragen:
- Wie lange laufen diese Transaktionen schon?
- Wie viele Sperrstrukturen und Zeilensperren sind vorhanden?
- Wie viele Logeinträge zum Rückgängigmachen gibt es?
- Welche Hosts und Nutzer stellen eine Verbindung her?
- Was ist die laufende SQL-Anweisung?
information_schema.innodb_trx
verwendenWenn
SHOW ENGINE INNODB STATUS
abgeschnitten wurde, können Sie alle offenen Transaktionen alternativ mit der Tabelleinformation_schema.innodb_trx
überprüfen:SELECT trx_id, trx_state, timestampdiff(second, trx_started, now()) AS active_secs, timestampdiff(second, trx_wait_started, now()) AS wait_secs, trx_tables_in_use, trx_tables_locked, trx_lock_structs, trx_rows_locked, trx_rows_modified, trx_query FROM information_schema.innodb_trx
Wenn die Transaktionen die aktuell lang andauernden Anweisungen anzeigen, können Sie diese Transaktionen entweder stoppen, um den Druck auf dem Server zu verringern, oder auf den Abschluss der kritischen Transaktionen warten. Wenn für die älteren Transaktionen keine Aktivitäten angezeigt werden, fahren Sie mit dem nächsten Schritt fort, um den Transaktionsverlauf zu finden.
SQL-Anweisungen von lang andauernden Transaktionen prüfen
performance_schema
verwendenDamit Sie
performance_schema
verwenden können, müssen Sie es zuerst aktivieren. Es ist eine Änderung, die einen Neustart der Instanz erfordert. Prüfen Sie nach dem Aktivieren vonperformance_schema
, ob die Instrumente und Nutzer aktiviert sind:SELECT * FROM setup_consumers where name like 'events_statements_history'; SELECT * FROM setup_instruments where name like 'statement/sql/%';
Wenn sie nicht aktiviert sind, aktivieren Sie sie:
UPDATE setup_instruments SET ENABLED = 'YES', timed = 'YES' WHERE NAME LIKE 'statement/%'; UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_statements%';
Standardmäßig behält jeder Thread die letzten zehn Ereignisse bei, die durch
performance_schema_events_statements_history_size
definiert sind. Diese reichen im Allgemeinen aus, um die Transaktion im Anwendungscode zu finden. Dieser Parameter ist nicht dynamisch.Fragen Sie mit der
mysql thread id
, dieprocesslist_id
entspricht, die Verlaufsereignisse ab:SELECT t.thread_id, event_name, sql_text, rows_affected, rows_examined, processlist_id, processlist_time, processlist_state FROM events_statements_history h INNER JOIN threads t ON h.thread_id = t.thread_id WHERE processlist_id = <mysql thread id> ORDER BY event_id;
Log für langsame Abfragen verwenden
Bei der Fehlerbehebung können Sie alle Abfragen, die länger als
N
Sekunden in Anspruch genommen haben, im Log für langsame Abfragen erfassen. Sie können die Logs für langsame Abfragen aktivieren. Bearbeiten Sie dazu die Instanzeinstellungen auf der Instanzseite der Google Cloud Console oder dergcloud CLI
und sehen Sie sich die Logs dann in der Loganzeige der Google Cloud Console oder dergloud CLI
an.
Semaphor-Konflikte prüfen
In einer gleichzeitigen Umgebung können Mutex und Lese-/Schreibvorgänge, die gemeinsam genutzte Ressourcen in Anspruch nehmen, die Konfliktursache sein und die Serverleistung verlangsamen. Wenn die Semaphor-Wartezeit mehr als 600 Sekunden beträgt, kann das System abstürzen um die Ausführungsunterbrechung zu beenden.
Verwenden Sie den folgenden Befehl, um den Semaphor-Konflikt anzuzeigen:
mysql> SHOW ENGINE INNODB STATUS\G ---------- SEMAPHORES ---------- ... --Thread 140396021667584 has waited at row0purge.cc line 862 for 241.00 seconds the semaphore: S-lock on RW-latch at 0x30c03e8 created in file dict0dict.cc line 1183 a writer (thread id 140395996489472) has reserved it in mode exclusive number of readers 0, waiters flag 1, lock_word: 0 Last time read locked in file row0purge.cc line 862 Last time write locked in file /build/mysql-5.7-FFKPr6/mysql-5.7-5.7.22/storage/innobase/dict/dict0stats.cc line 2376 ...
Bei jedem Semaphor-Wartevorgang zeigt die erste Zeile den Thread, der wartet, den spezifischen Semaphor und die Wartezeit. Wenn es bei wiederholter Ausführung von
SHOW ENGINE INNODB STATUS
zu vielen Semaphoren kommt, insbesondere zu Wartezeiten von mehr als ein paar Sekunden, bedeutet dies, dass das System Nebenläufigkeitsengpässe aufweist.Es gibt unterschiedliche Konfliktursachen bei verschiedenen Arbeitslasten und Konfigurationen.
Wenn sich die Semaphoren oft in btr0sea.c befinden, kann die adaptive Hash-Indexierung die Konfliktquelle sein. Versuchen Sie, sie mit der Google Cloud Console oder der
gcloud CLI
zu deaktivieren.Lange
SELECT
-Abfragen optimierenÜberprüfen Sie zuerst die Abfrage. Identifizieren Sie das Ziel der Abfrage und den besten Weg, die Ergebnisse zu erhalten. Der beste Abfrageplan ist jener, der den Datenzugriff minimiert.
- Prüfen Sie den Abfrageausführungsplan:
mysql> EXPLAIN <the query>;
In der MySQL-Dokumentation erfahren Sie, wie die Ausgabe interpretiert und die Abfrageeffizienz bewertet wird.
- Richtigen Index verwenden
Prüfen Sie in der Schlüsselspalte, um zu sehen, ob der erwartete Index verwendet wird. Aktualisieren Sie andernfalls die Indexstatistiken:
mysql> analyze table <table_name>
Erhöhen Sie die Anzahl der Beispielseiten, die zur Berechnung von Indexstatistiken verwendet werden. Weitere Informationen finden Sie in der MySQL-Dokumentation.
- Index vollständig nutzen
Wenn Sie einen mehrspaltigen Index verwenden, prüfen Sie die
key_len
-Spalten, um festzustellen, ob der Index vollständig zum Filtern der Datensätze genutzt wird. Die Spalten ganz links müssen Gleichheitsvergleiche sein und der Index kann bis zur ersten Bereichsbedingung (einschließlich dieser) verwendet werden.- Optimierer-Hinweise verwenden
Eine weitere Möglichkeit, die Verwendung des richtigen Index sicherzustellen, ist die Nutzung von Indexhinweisen und Hinweisen für die Tabellen-Join-Reihenfolge.
Lange Verlaufsliste mit READ COMMITTED vermeiden
Die Verlaufsliste ist die Liste der nicht gelöschten Transaktionen im Tablespace zum Rückgängigmachen. Die Standardisolationsebene einer Transaktion ist REPEATABLE READ, sodass eine Transaktion während ihrer gesamten Dauer denselben Snapshot lesen muss. Daher blockiert eine
SELECT
-Abfrage das Löschen von Logdatensätzen zum Rückgängigmachen, die seit dem Start der Abfrage (oder Transaktion) erstellt wurden. Eine lange Verlaufsliste verlangsamt daher die Abfrageleistung. Wenn Sie vermeiden möchten, dass eine lange Verlaufsliste erstellt wird, können Sie z. B. die Transaktionsisolationsebene in READ COMMITTED ändern. Bei READ COMMITTED wird die Verlaufsliste nicht mehr für eine konsistente Leseansicht benötigt. Sie können die Transaktionsisolationsebene global für alle Sitzungen, für eine einzelne Sitzung oder für die nächste einzelne Transaktion ändern. Weitere Informationen finden Sie in der MySQL-Dokumentation.Serverkonfiguration abstimmen
Es gibt viel über die Serverkonfiguration zu sagen. Die vollständige Thematik wird in diesem Dokument nicht behandelt. Es sollte aber erwähnt werden, dass der Server auch verschiedene Statusvariablen meldet, die Hinweise darauf geben, wie gut die zugehörigen Konfigurationen sind. Beispiel:
- Passen Sie
thread_cache_size
an, wennThreads_created/Connections
groß ist. Ein ordnungsgemäßer Thread-Cache würde die Erstellungszeit des Threads reduzieren und eine stark gleichzeitige Arbeitslast unterstützen. - Passen Sie
table_open_cache
an, wennTable_open_cache_misses/Table_open_cache_hits
nicht trivial ist. Tabellen im Tabellen-Cache sparen Ausführungszeit bei Abfragen und können in einer stark gleichzeitigen Umgebung einen Unterschied machen.
- Passen Sie
Unerwünschte Verbindung beenden
Sie können die Abfrage beenden, wenn sie ungültig zu sein scheint oder nicht mehr benötigt wird. Informationen zum Identifizieren und Beenden des MySQL-Threads finden Sie unter Datenbankverbindungen verwalten.
Wenn die CPU-Auslastung immer noch hoch ist und die Abfragen erforderlichen Traffic verursachen, sollten Sie eventuell die CPU-Ressourcen in Ihrer Instanz erhöhen, um Datenbankabstürze oder -ausfälle zu vermeiden.