Lösungen für MySQL OOM (Speicherüberlauf)

Lösungen für MySQL OOM (Speicherüberlauf)

OOM steht für „Out Of Memory“, was so viel bedeutet wie Speicherüberlauf.

Speicherüberlauf ist seit fast 40 Jahren ein bestehendes Problem in der Softwareentwicklung. Beim Ausführen verschiedener Software auf dem Betriebssystem übersteigt der von der Software benötigte Speicher die Größe, die der physische Speicher verkraften kann, bei weitem. Dies wird als Speicherüberlauf bezeichnet.

Es gibt viele Gründe für einen Speicherüberlauf. Wenn der Speicher ernsthaft nicht ausreicht, hat der Kernel zwei Möglichkeiten:

  1. Direkte Panik
  2. Beenden Sie einige Prozesse, um einige Kerne freizugeben.

In den meisten Fällen wird der Prozess, der das OOM verursacht hat, beendet und das System wird wiederhergestellt. Normalerweise fügen wir Überwachungsalarme für den Speicher hinzu. Wenn beispielsweise die Speicher- oder Swap-Nutzung 90 % überschreitet, wird eine Alarmbenachrichtigung ausgelöst und ein rechtzeitiges Eingreifen ist erforderlich.

Wenn OOM aufgetreten ist, können Sie es mit dem Befehl dmesg anzeigen. CentOS7 und höhere Versionen unterstützen die Option -T, mit der der Zeitstempel in das Zeitformat konvertiert werden kann, sodass die genaue Zeit leichter angezeigt werden kann:

[root@localhost ~]# free -m insgesamt genutzte freie gemeinsam genutzte Puffer cachedMem: 128937 128527 409 1 166 1279-/+ buffers/cache: 127081 1855Swap: 16383 16252 131

Die Protokolle können Informationen darüber enthalten, welche Prozesse ausgeführt werden und wie viel Speicher sie belegen. Außerdem werden Prozesse, die viel Speicher belegen, beendet.

Beheben von Speicherproblemen

1. Überprüfung des Betriebssystemspeichers

Am Beispiel von MySQL wird nach OOM der mysqld-Prozess beendet und der Speicher freigegeben. Der Prozess mysqld_safe startet mysqld und der zu diesem Zeitpunkt angezeigte Systemspeicher weist einen normalen Wert auf. Wenn die Speicherauslastung hoch ist, aber kein OOM aufgetreten ist, kann die Systemspeicherauslastung wie folgt aussehen:

[root@localhost ~]# free -m insgesamt genutzte freie gemeinsam genutzte Puffer cachedMem: 128937 128527 409 1 166 1279-/+ buffers/cache: 127081 1855Swap: 16383 16252 131

Es ist ersichtlich, dass die Speichernutzung zu diesem Zeitpunkt bereits sehr hoch ist. Der physische Speicher und der virtuelle Swap-Speicher sind fast aufgebraucht. Es gibt nicht viele Puffer und Caches. OOM kann jederzeit auftreten.

Zeigen Sie zunächst mit top den Prozess an, der den meisten Speicher beansprucht:

Mit Umschalt+O kann die Sortiermethode ausgewählt werden, und n steht für %MEM.

[root@localhost ~]# topMem: 132031556k gesamt, 131418864k genutzt, 612692k frei, 212104k buffersSwap: 16777212k gesamt, 0k genutzt, 16777212k frei, 14648144k zwischengespeichert
 PID USER PR NI VIRT RES SHR S %CPU %MEM ZEIT+ COMMAND14920 mysql 20 0 125g 109g 6164 S 6.6 87.0 27357:08 mysqld 

Es ist ersichtlich, dass der mysqld-Prozess den größten Speicher belegt, was auch folgendermaßen überprüft werden kann:

130738976 2017 mysql 50032070 mysqld_safe /bin/sh /export/servers/mys 0,0 296 106308 2017 root 0

RSZ ist die Größe des vom Prozess belegten privaten Speichers in KB.
VSZ ist die zugeordnete virtuelle Speichergröße in KB.

Das Verhältnis der gesamten Speichernutzung kann auch über RSZ/Gesamt berechnet werden.

2. Überprüfen Sie den MySQL zugewiesenen Speicher

Der Hauptspeicher in MySQL kann durch die folgende Anweisung gefunden werden:

MYSQL >SET @giga_bytes = 1024*1024*1024;SELECT (@@key_buffer_size + @@query_cache_size + @@tmp_table_size + @@innodb_buffer_pool_size + @@innodb_additional_mem_pool_size + @@innodb_log_buffer_size + (Anzahl(HOST) aus information_schema.processlist auswählen)/*@@max_connections*/*(@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size + @@join_buffer_size + @@binlog_cache_size + @@thread_stack)) / @giga_bytes AS MAX_MEMORY_GB;

Jeder Parameter konfiguriert die Größe:

*************************** 1. row ****************************** * @@key_buffer_size: 67108864 @@query_cache_size: 0 @@tmp_table_size: 268435456 @@innodb_buffer_pool_size: 38654705664 @@innodb_additional_mem_pool_size: 134217728 @@innodb_log_buffer_size: 8388608 @@max_connections: 3000 @@read_buffer_size: 4194304 @@read_rnd_buffer_size: 4194304 @@sort_buffer_size: 2097152 @@join_buffer_size: 2097152 @@binlog_cache_size: 32768 @@thread_stack: 262144

Konfigurationsbeschreibung jedes Parameters:

innodb_buffer_pool_size Parameter, die den meisten Speicher beanspruchen
innodb_additional_mem_pool_size Zusätzlicher Speicher, entfernt nach MySQL 5.7
innodb_log_buffer_size Größe des Redo-Log-Cache
Schlüsselpuffergröße Wird nur für die MyISAM-Engine verwendet und muss nicht zu groß sein
temporäre_Tabellengröße Größe des temporären Tabellencaches
Abfrage-Cachegröße Abfrage-Cache, es wird empfohlen, zu schließen
Max_Verbindungen Maximale Anzahl von Verbindungen
Puffergröße lesen Puffergröße lesen RUN-Puffergröße sortieren Puffergröße verbinden Puffergröße binärer Cache Thread-Stack Diese Parameter beziehen sich alle auf Threads und der belegte Speicher ist die Summe dieser Parameter * der maximalen Anzahl von Verbindungen. Je mehr Verbindungen bestehen, desto mehr Speicher wird belegt. Es wird empfohlen, 512 KB nicht zu überschreiten. Der Standardwert von binlog_cache_size beträgt 32 KB und der Standardwert von thread_stack beträgt 256 KB.

Wie viel Speicher Sie MySQL zuweisen müssen, hängt direkt von den oben genannten Parametern ab. Wenn es zu groß ist, führt dies zu unzureichendem Speicher, und wenn es zu klein ist, beeinträchtigt es die Leistung. Wie ein angemessener Wert zugewiesen wird, hängt von der Geschäftssituation ab. Es gibt jedoch viele Geschäftsszenarien und jede Geschäftskonfiguration ist anders, was zu hohen Betriebs- und Wartungskosten führt. Daher reicht es aus, einen Satz von Konfigurationsvorlagen anzupassen, die für die meisten Szenarien geeignet sind.

1. Wenn der von MySQL zugewiesene Speicher größer ist als der Systemspeicher

Wenn der Systemspeicher beispielsweise 128 G beträgt, ist der MySQL zugewiesene Speicher bereits größer als 128 G, aber das System selbst und andere Programme benötigen ebenfalls Speicher, sogar mysqldump benötigt Speicher. Daher kann es leicht zu unzureichendem Systemspeicher und damit zu OOM kommen. Jetzt müssen wir herausfinden, welche Parameter zu groß eingestellt sind und die Speicherzuweisung entsprechend reduzieren.

innodb_buffer_pool belegt den größten Speicher in MySQL. Durch die Reduzierung der innodb_buffer_pool_size können OOM-Probleme effektiv reduziert werden. Wenn der Wert jedoch zu klein eingestellt ist, erhöht sich die Häufigkeit des Löschens schmutziger Seiten im Speicher, die E/A nimmt zu und die Leistung nimmt ab. Normalerweise erachten wir innodb_buffer_pool_size 60 % bis 75 % des Systemspeichers als optimal.

Überprüfen Sie die Verwendung des Pufferpools:

MySQL> SELECT POOL_ID, POOL_SIZE, FREE_BUFFERS, DATEBABE_PAGES, old_database_pages, modifiziert_database_pages, Pages_Made_young, pages_not_made_young aus Informationen -----------------+--------------+--------------+| -------+----------------+------------------------------+------------------+| 309816 |

Es ist ersichtlich, dass buffer_pool in 3 Instanzen unterteilt ist, POOL_SIZE ist die Größe jeder Instanz, hier ist die Anzahl der Seiten. Wir wissen, dass die Standardgröße einer MySQL-Seite 16 KB beträgt, also beträgt die tatsächliche Größe einer einzelnen Instanz 611669*16 KB. Nach 5.6 muss FREE_BUFFERS mindestens 1024 Seiten behalten. Wenn weniger als 1024 Seiten vorhanden sind, müssen schmutzige Daten zwangsweise gelöscht werden. Der folgende Wert kann die Situation mit schmutzigen Seiten zeigen. Wenn PAGES_MADE_YOUNG viel größer als PAGES_NOT_MADE_YOUNG ist, kann außerdem der Speicherverbrauch relativ hoch sein und die innodb_buffer_pool_size kann entsprechend reduziert werden.

Ein weiterer Artikel stellt auch buffer_pool vor: Ein Befehl zum Interpretieren der InnoDB-Speicher-Engine – show engine innodb status

Wenn innodb_buffer_pool_size nicht sehr groß ist, die Speichernutzung aber trotzdem sehr hoch ist, kann dies an zu vielen gleichzeitigen Threads liegen. Sie müssen bestätigen, ob es sich um eine Anwendungsanomalie handelt oder ob Sie max_connections anpassen müssen. Wenn zu viele Verbindungen vorhanden sind, belegt jede Verbindung einen unabhängigen Speicher. Die Caches zum Lesen, Sortieren und Verbinden befinden sich alle auf Sitzungsebene. Je mehr Verbindungen vorhanden sind, desto mehr Speicher wird benötigt. Daher können diese Parameter nicht zu groß eingestellt werden.

Es ist zu beachten, dass einige Parameter keine dynamische Änderung unterstützen. Sie können nur wirksam werden, wenn die Konfigurationsdatei geändert und MySQL dann neu gestartet wird. Bestätigen Sie daher unbedingt den Parameterwert, bevor Sie MySQL starten.

2. Wenn der von MySQL zugewiesene Speicher kleiner ist als der Systemspeicher

Wenn die MySQL-Parametereinstellungen sinnvoll sind, aber trotzdem OOM auftritt, kann dies daran liegen, dass MySQL auf Systemebene nicht genügend Speicher benötigt. Denn wenn MySQL eine Tabelle liest und mehrere Sitzungen gleichzeitig auf eine Tabelle verweisen, werden mehrere Tabellenobjekte erstellt. Dies verringert zwar die Konkurrenz um interne Tabellensperren, erhöht aber den Speicherverbrauch.

Zunächst können Sie mit lsof -p pid die Anzahl der vom Prozess geöffneten Systemdateien anzeigen, wobei pid die Prozess-ID von mysqld ist.

[root@localhost ~]# ps -ef | grep mysqld[root@localhost ~]# lsof -p 3455COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEmysqld 30012 mysql cwd DIR 8,3 12288 58982404 /mysql/datamysqld 30012 mysql mem REG 8,1 599392 272082 /lib64/libm-2.12.somysqld 30012 mysql mem REG 8,1 91096 272089 /lib64/libz.so.1.2.3mysqld 30012 mysql mem REG 8,1 93320 272083 /lib64/libgcc_s-4.4.7-20120601.so.1mysqld 30012 mysql mem REG 8,1 43392 272095 /lib64/libcrypt-2.12.somysqld 30012 mysql 10uW REG 8,3 536870912 59015176 /mysql/data/ib_logfile0mysqld 30012 mysql 11uW REG 8,3 536870912 59015177 /mysql/data/ib_logfile1mysqld 30012 mysql 12uW REG 8,3 536870912 59015178 /mysql/data/ib_logfile2mysqld 30012 mysql 13uW REG 8,3 675282944 59001816 /mysql/data/test/table6.ibdmysqld 30012 mysql 14uW REG 8,3 2155872256 58985613 /mysql/data/test/table487.ibdmysqld 30012 mysql 15u REG 8,3 0 58982414 /mysql/tmp/ibhNDzPM (deleted)mysqld 30012 mysql 16uW REG 8,3 2306867200 58983861 /mysql/data/test/table327.ibdmysqld 30012 mysql 17uW REG 8,3 4169138176 58985467 /mysql/data/test/table615.ibdmysqld 30012 mysql 18uW REG 8,3 79691776 59020641 /mysql/data/test/table_v199_20170920.ibdmysqld 30012 mysql 19uW REG 8,3 67108864 59015043 /mysql/data/test/table_v39_20170920.ibdmysqld 30012 mysql 20uW REG 8,3 75497472 59014992 /mysql/data/test/table_v7_20170920.ibdmysqld 30012 mysql 21uW REG 8,3 83886080 59019735 /mysql/data/test/table_v167_20170920.ibdmysqld 30012 mysql 22uW REG 8,3 1367343104 58997684 /mysql/data/popfin6/table_uuid6.ibdmysqld 30012 mysql 23uW REG 8,3 1275068416 58984491 /mysql/data/test/table_uuid7.ibd...[root@localhost ~]# lsof -p 3455 |grep ibd|wc -l54869

Zeigen Sie die Begrenzung der Anzahl geöffneter Dateien für den MySQL-Dienst an:

MySQL >globale Variablen wie „open_files_limit“ anzeigen;+------------------+-------+| Variablenname | Wert |+------------------+-------+| open_files_limit | 65535 |+------------------+-------+

Überprüfen Sie das Limit für geöffnete Dateien des Betriebssystems:

[root@localhost ~]# ulimit -amax Speichergröße (KB, -m) unbegrenzt viele geöffnete Dateien (-n) 65535

Wenn zu diesem Zeitpunkt viele Dateien geöffnet sind, wird viel Speicher belegt.

Zweitens müssen Sie sich table_open_cache ansehen. Wenn eine Tabelle geöffnet wird, wird der Dateideskriptor der Tabelle zwischengespeichert.

MYSQL >globale Variablen anzeigen wie „table_open_cache“;+------------------+----------+| Variablenname | Wert |+------------------+-------+| table_open_cache | 16384 |+------------------+-------+MYSQL >globalen Status anzeigen wie „%open%tables%“;+------------------------+--------+| Variablenname | Wert |+------------------------+--------+| Open_tables | 16384 || Opened_tables | 401374 |+------------------------+--------+

Die beiden oben genannten Werte werden verwendet, um zu bestimmen, ob table_open_cache einen Engpass erreicht hat.
Wenn der Wert von open_tables im Cache nahe am Wert von table_open_cache liegt, bedeutet dies, dass der Tabellen-Cache-Pool fast voll ist, Opened_tables jedoch immer noch wächst, was bedeutet, dass immer noch viele Tabellen vorhanden sind, die nicht zwischengespeichert wurden.

Mit dem Befehl „show open tables from schema“ können Sie die zwischengespeicherten Tabellen in „table_open_cache“ anzeigen. Beim wiederholten Öffnen wird nur eine Tabelle angezeigt.

MYSQL >offene Tabellen von Sysbenchtest anzeigen;+--------------+----------+--------+-------------+| Datenbank | Tabelle | In_Verwendung | Name_gesperrt |+--------------+----------+--------+----------+| sysbenchtest | sbtest1 | 1 | 0 || sysbenchtest | sbtest2 | 0 | 0 || sysbenchtest | sbtest3 | 0 | 0 || sysbenchtest | sbtest4 | 0 | 0 || sysbenchtest | sbtest5 | 0 | 0 |

In_use zeigt die Anzahl der Threads an, die diese Tabelle derzeit verwenden. Wenn der Wert größer als 0 ist, bedeutet dies auch, dass diese Tabelle gesperrt ist.

Name_locked gilt nur für DROP und RENAME. Wenn Sie DROP oder RENAME ausführen, wird der Tabellendateideskriptor in table_open_cache entfernt, sodass Sie keinen anderen Wert als 0 sehen.

Wenn viele Bibliotheken und Tabellen (aufgeteilte Bibliotheken und Tabellen) vorhanden sind, kann es im Allgemeinen leicht zu einem hohen Speicherverbrauch kommen. Wenn Sie die Grundursache beheben möchten, müssen Sie die Bibliothekstabelle noch aufteilen.

3. Anderer Speicher in MySQL

Alle Tabellen unter information_schema verwenden die Speicher-Engine MEMORY. Daten werden nur im Speicher gehalten, beim Start geladen und nach dem Herunterfahren freigegeben.

Überprüfen Sie, ob eine andere MEMORY-Engine-Tabelle als die Systembibliothek vorhanden ist:

MySQL >select * from information_schema.tables where engine='MEMORY' und TABLE_SCHEMA !='information_schema';

Wenn Ihr Unternehmen die Speicher-Engine MEMORY verwendet, versuchen Sie, sie auf die InnoDB-Engine umzustellen.

4. MySQL-Ereignisspeicherindikatoren

Ab MySQL 5.7 wird die Speicherzuweisung im Performance-Schema aufgezeichnet.

Überprüfen Sie, für welche Metriken die Speichererfassung aktiviert ist:

MySQL >wählen Sie * aus performance_schema.setup_instruments aus, wobei NAME LIKE 'Speicher/%' ist;

Beginnen Sie mit der Erfassung von Speichermetriken:

MySQL >UPDATE performance_schema.setup_instruments SET ENABLED = „JA“, wobei NAME WIE „Speicher/%“ ist;

Die Speichererfassungsergebnisse des Indikators werden in der Ansicht unter der Sys-Bibliothek zusammengefasst:

MySQL-Stamm@[sys]>Tabellen wie „Speicher%“ anzeigen;+-----------------------------------+| Tables_in_sys (Speicher%) |+-----------------------------------+| Speicher_nach_Host_nach_aktuellen_Bytes || Speicher_nach_Thread_nach_aktuellen_Bytes || Speicher_nach_Benutzer_nach_aktuellen_Bytes || Speicher_global_nach_aktuellen_Bytes || Speicher_global_total |+-----------------------------------+

Diese Ansichten fassen die Speichernutzung zusammen, gruppiert nach Ereignistyp, standardmäßig in absteigender Reihenfolge:

MySQL> SELECT Event_name, Current_Count, Current_Alloc, High_Alloc aus Sys.memory_Global_By_Current_Bytes, wobei Current_Count> 0; -------------------------------------------------------+-----------+-----------+------------- 26.01 MIB || IStory |

Zusammenfassen:

Durch die obige Untersuchung können wir ungefähr erkennen, welche Bereiche mehr Speicher belegen, und dann spezifische Optimierungen für die Bereiche vornehmen, die mehr Speicher belegen. Wie zu Beginn des Artikels erwähnt, ist Speicherüberlauf seit fast 40 Jahren ein „altbekanntes“ Problem in der Geschichte der Softwareentwicklung. Darüber hinaus ist die Datenbankumgebung komplexer. Faktoren wie SQL-Syntax, Datentyp und Datengröße hängen alle mit dem Speicher zusammen. Daher sollten Sie bei der Entwicklung und Verwendung mehr über Speicherüberlaufprobleme nachdenken.

Oben finden Sie den detaillierten Inhalt der Lösung für MySQL OOM (Speicherüberlauf). Weitere Informationen zur Lösung für MySQL OOM (Speicherüberlauf) finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung der Speicherverwaltung der MySQL InnoDB-Speicher-Engine
  • Detaillierte Analyse des MySQL 8.0-Speicherverbrauchs
  • Detaillierte Erklärung zur Verwendung von MySQL-Speichertabellen und temporären Tabellen
  • Detaillierte Erklärung zum Anzeigen der MySQL-Speichernutzung
  • Die perfekte Lösung für den häufig auftretenden Startfehler bei MySQL mit unzureichendem Arbeitsspeicher
  • Test und Lösung für den großen Speicherverbrauch und die hohe CPU-Auslastung von MySQL
  • Lösung für hohen Speicherverbrauch beim Starten von MySQL 5.6
  • Teilen Sie den Prozess zur Fehlerbehebung bei abnormalem Speicheranstieg in der MySQL-Produktionsdatenbank

<<:  Detaillierte Erklärung zur Verwendung der Vue.js-Renderfunktion

>>:  Schritte für Docker zum Erstellen eines privaten Lagerhafens

Artikel empfehlen

Vue realisiert den Gleitkreuzeffekt des Balles

In diesem Artikelbeispiel wird der spezifische Co...

Über das Problem der Offline-Installation des Docker-Pakets unter CentOS 8.4

Die verwendete virtuelle Maschine ist CentOS 8.4,...

js implementiert ein einfaches Warenkorbmodul

In diesem Artikelbeispiel wird der spezifische Co...

Zusammenfassung der Tipps zum Erstellen von Webseiten

Vorwort Dieser Artikel fasst hauptsächlich einige...

Eine detaillierte Erklärung der subtilen Unterschiede zwischen Readonly und Disabled

Sowohl die Optionen „Nur lesen“ als auch „Deaktivi...

js Promise-Methode zur gleichzeitigen Steuerung

Inhaltsverzeichnis Frage Hintergrund Idee & U...

Implementierung der MySQL-Benutzerrechteverwaltung

1. Einführung in MySQL-Berechtigungen Es gibt 4 T...

Einführung in Linux-Komprimierungs- und Dekomprimierungsbefehle

Inhaltsverzeichnis Gängige Komprimierungsformate:...

Tägliche Studiennotizen im HTML-Designmuster

Studiennotizen zu HTML-Entwurfsmustern Diese Woch...

Zusammenfassung der Unterschiede zwischen Get- und Post-Anfragen in Vue

Die Betriebsumgebung dieses Tutorials: Windows 7-...

Tutorial zur Installation und Kennwortkonfiguration von MySQL 5.7.21

Tutorial zur Installation und Kennworteinstellung...

Docker stellt eine MySQL-Remoteverbindung bereit, um 2003-Probleme zu lösen

Herstellen einer Verbindung mit MySQL Hier verwen...