
Ich habe ein Problem mit der CPU-Auslastung auf der Website, die WordPress, Apache und MySQL verwendet. Im Laufe des Tages steigt die CPU-Auslastung durch MySQL und Apache von Zeit zu Zeit auf 2400 % (ich habe insgesamt 24 Kerne), der Server friert ein, die durchschnittliche Auslastung steigt auf 24.
Vor kurzem gab es etwas mehr Verkehr als üblich, aber das sollte nicht dauerhaft sein, oder? Ich habe den Kernel, die Datenbank, die Bibliotheken aktualisiert und viele Male neu gestartet. Und trotzdem friert es ein. Ich habe mir die Prozessliste der Datenbank angesehen, aber da ist nichts Außergewöhnliches. In der Datenbank befinden sich ziemlich große Datenmengen. Vor ein paar Wochen hat es noch einwandfrei funktioniert, jetzt nicht mehr. Es sollten also keine nicht optimierten Abfragen sein.
Was können die Ursachen für ein solches Verhalten sein?
Aktualisieren:
das Ergebnis von A) SHOW GLOBAL STATUS LIKE 'com_%r%_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Com_alter_table | 5 |
| Com_create_table | 34 |
| Com_drop_table | 0 |
| Com_rename_table | 0 |
| Com_show_create_table | 0 |
+-----------------------+-------+
5 rows in set (3.04 sec)
B) GLOBALEN STATUS WIE „uptime%“ ANZEIGEN;
+---------------------------+--------+
| Variable_name | Value |
+---------------------------+--------+
| Uptime | 455524 |
| Uptime_since_flush_status | 455524 |
+---------------------------+--------+
2 rows in set (0.01 sec)
C) GLOBALEN STATUS WIE „%dirty%“ ANZEIGEN;
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_dirty | 0 |
| Innodb_buffer_pool_bytes_dirty | 0 |
+--------------------------------+-------+
2 rows in set (0.00 sec)
PS: Ich habe immer noch Probleme mit dem Server. Ich musste den Zeichensatz in einer der Datenbanken ändern und das hat bei nur 400.000 Zeilen etwas mehr als einen Tag gedauert. Früher hat es etwas gedauert, aber nicht so lange. Ich frage mich, ob es nach dem DDOS-Angriff zu Änderungen an der Datenbank kommen könnte, sodass sie schlechter funktioniert?
Aktualisierung 2:
mysqltuner-Ergebnisse:
[--] Skipped version check for MySQLTuner script
[OK] Logged in using credentials from Debian maintenance account.
[OK] Currently running supported MySQL version 8.0.26-0ubuntu0.20.04.2
[OK] Operating on 64-bit architecture
-------- Log file Recommendations ------------------------------------------------------------------
[OK] Log file /var/log/mysql/error.log exists
[--] Log file: /var/log/mysql/error.log(0B)
[--] Log file /var/log/mysql/error.log is empty. Assuming log-rotation. Use --server-log={file} for explicit file
-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA
[--] Data in InnoDB tables: 262.4G (Tables: 179)
[OK] Total fragmented tables: 0
-------- Analysis Performance Metrics --------------------------------------------------------------
[--] innodb_stats_on_metadata: OFF
[OK] No stat updates during querying INFORMATION_SCHEMA.
-------- Security Recommendations ------------------------------------------------------------------
[--] Skipped due to unsupported feature for MySQL 8
-------- CVE Security Recommendations --------------------------------------------------------------
[OK] NO SECURITY CVE FOUND FOR YOUR VERSION
-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 5d 11h 4m 6s (15M q [31.945 qps], 191K conn, TX: 80G, RX: 2G)
[--] Reads / Writes: 99% / 1%
[--] Binary logging is enabled (GTID MODE: OFF)
[--] Physical Memory : 31.4G
[--] Max MySQL memory : 9.8G
[--] Other process memory: 0B
[--] Total buffers: 176.0M global + 65.1M per thread (151 max threads)
[--] P_S Max memory usage: 72B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 9.8G (31.14% of installed RAM)
[OK] Maximum possible memory usage: 9.8G (31.14% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 0% (0/15M)
[!!] Highest connection usage: 100% (151/151)
[OK] Aborted connections: 0.09% (174/191712)
[!!] name resolution is active : a reverse name resolution is made for each new connection and can reduce performance
[--] Query cache have been removed in MySQL 8
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 5M sorts)
[OK] No joins without indexes
[OK] Temporary tables created on disk: 0% (0 on disk / 2M total)
[OK] Thread cache hit rate: 92% (15K created / 191K connections)
[OK] Table cache hit rate: 99% (21M hits / 21M requests)
[OK] table_definition_cache(2000) is upper than number of tables(506)
[OK] Open file limit used: 0% (6/10K)
[OK] Table locks acquired immediately: 100% (9 immediate / 9 locks)
[OK] Binlog cache memory access: 99.57% (25538 Memory / 25647 Total)
-------- Performance schema ------------------------------------------------------------------------
[--] Memory used by P_S: 72B
[--] Sys schema is installed.
-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.
-------- MyISAM Metrics ----------------------------------------------------------------------------
[--] MyISAM Metrics are disabled on last MySQL versions.
-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Concurrency: 0
[OK] InnoDB File per table is activated
[!!] InnoDB buffer pool / data size: 128.0M/262.4G
[!!] Ratio InnoDB log file size / InnoDB Buffer pool size (75 %): 48.0M * 2/128.0M should be equal to 25%
[OK] InnoDB buffer pool instances: 1
[--] Number of InnoDB Buffer Pool Chunk : 1 for 1 Buffer Pool Instance(s)
[OK] Innodb_buffer_pool_size aligned with Innodb_buffer_pool_chunk_size & Innodb_buffer_pool_instances
[OK] InnoDB Read buffer efficiency: 98.29% (925392031 hits/ 941450541 total)
[!!] InnoDB Write Log efficiency: 309.39% (25100125 hits/ 8112662 total)
[!!] InnoDB log waits: 0.00% (65 waits / 33212787 writes)
-------- Aria Metrics ------------------------------------------------------------------------------
[--] Aria Storage Engine not available.
-------- TokuDB Metrics ----------------------------------------------------------------------------
[--] TokuDB is disabled.
-------- XtraDB Metrics ----------------------------------------------------------------------------
[--] XtraDB is disabled.
-------- Galera Metrics ----------------------------------------------------------------------------
[--] Galera is disabled.
-------- Replication Metrics -----------------------------------------------------------------------
[--] Galera Synchronous replication: NO
[--] No replication slave(s) for this server.
[--] Binlog format: ROW
[--] XA support enabled: ON
[--] Semi synchronous replication Master: Not Activated
[--] Semi synchronous replication Slave: Not Activated
[--] This is a standalone server
-------- Recommendations ---------------------------------------------------------------------------
General recommendations:
Reduce or eliminate persistent connections to reduce connection usage
Configure your accounts with ip or subnets only, then update your configuration with skip-name-resolve=1
Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: *link*
Variables to adjust:
max_connections (> 151)
wait_timeout (< 28800)
interactive_timeout (< 28800)
innodb_buffer_pool_size (>= 262.4G) if possible.
innodb_log_file_size should be (=16M) if possible, so InnoDB total log files size equals to 25% of buffer pool size.
innodb_log_buffer_size (>= 16M)
Aktualisierung 3:
Heute ist mein Server wieder eingefroren. Der Prozess, der die CPU überlastet hat, war Apache2. Ich habe es geschafft, den Dienst zu stoppen. Und plötzlich funktionierte alles wieder reibungslos. Ich habe versucht, ein Backup der Datenbank zu machen, die mit den meisten Zeilen, und es hat einwandfrei funktioniert. Aber nach einiger Zeit ist alles wieder eingefroren: Die CPU-Auslastung einiger Prozesse lag bei 2400 %, die durchschnittliche Auslastung überstieg 24. Daher vermute ich, dass es nicht Apache ist, der die CPU belastet, und auch nicht MySQL. Einige der Prozesse, wie htop oder gzip, die ich für das Backup verwende, haben von Zeit zu Zeit auch eine hohe CPU-Auslastung. Was könnte es dann sein? Könnte dies das Ergebnis eines DDOS-Angriffs sein, und wenn ja, wie kann ich es beheben?
Antwort1
Rate pro Sekunde = RPS
Vorschläge zur Berücksichtigung Ihres my.cnf-Abschnitts [mysqld]
innodb_buffer_pool_size=22G # from 128M to better accomodate your 262G of data
max_connections=256 # from 151 since you have had all connections used
thread_cache_size=150 # from 9 to reduce threads_created RPhr of 111
innodb_log_file_size=4G # from 50M to support more than and hour before rotation
innodb_log_buffer_size=1G # from 16M to support ~ 30 min before write to media
Die Leistung sollte deutlich verbessert sein. Es gibt noch viele weitere Möglichkeiten zur Leistungssteigerung. Sehen Sie sich das Profil an, um Kontaktinformationen und kostenlos herunterladbare Utility-Skripts zur Leistungssteigerung zu erhalten.
Antwort2
Das ist sehr schwer zu sagen, aber Sie sagen, dass Sie WordPress ausführen und Ihre 24 Kerne in der Spitze zu 100 % ausgelastet sind. Denken Sie nur daran, dass eine einzelne Abfrage nicht immer nur einen Thread gleichzeitig verwenden kann.
Das klingt nach einer sehr schlechten Abfrageleistung und nicht direktem Zugriff auf Ihren Apache-Webserver. Haben Sie versucht, Ihre Abfragen mit dem Plugin „WP Redis Cache“ in Redis zwischenzuspeichern, um die Abfragesuche zu speichern?
Das nächste Plugin, das Sie installieren können, ist „Query Monitor“. Es zeigt Ihnen die SQL-Abfragen, die Sie aufrufen, im laufenden Betrieb an und ist ein sehr gutes Debugging-Tool für WordPress.
Denken Sie daran, dass Sie sich bei der Entwicklung eigener Plugins in WordPress selbst um Redis kümmern müssen, indem Sie die integrierten Funktionen zum Zwischenspeichern Ihrer Abfrageergebnisse verwenden.
Und zum Abschluss dieser Methode zum Debuggen empfehle ich Ihnen, die Slow-Log-Abfrage für MySQL für alles über 1 Sekunde zu aktivieren. Möglicherweise finden Sie Abfragen, bei denen der Index für die Spalte(n) fehlt.