it-swarm.com.de

Warum sagt MySQL, dass mir der Speicher ausgeht?

Ich habe versucht, mit JDBC ein ziemlich großes INSERT...SELECT In MySQL auszuführen, und habe die folgende Ausnahme erhalten:

Exception in thread "main" Java.sql.SQLException: Out of memory (Needed 1073741824 bytes)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:1073)

Da ich eigentlich kein ResultSet-Objekt zurückgebe, dachte ich, dass der Java Heap-Speicherplatz kein Problem sein sollte. Ich habe jedoch trotzdem versucht, ihn zu aktualisieren, und es hat nichts gebracht. Ich habe es dann versucht Um die Anweisung in MySQL Workbench auszuführen, habe ich im Wesentlichen dasselbe erhalten:

Error Code 5: Out of memory (Needed 1073741816 bytes)

Ich sollte genügend RAM) haben, um diese Vorgänge abzuschließen (genug, um in die gesamte Tabelle zu passen, aus der ich auswähle), aber ich vermute, dass ich verschiedene Einstellungen vornehmen muss, um die Vorteile zu nutzen Mein gesamter Speicher. Ich verwende eine Amazon EC2 High Memory Double Extra Large Instance mit einem Windows Server 2008 AMI. Ich habe versucht, mit der Datei my.ini zu fummeln, um bessere Einstellungen zu verwenden, aber für alle Ich weiß, dass ich die Dinge möglicherweise noch schlimmer gemacht habe. Hier ist ein Speicherauszug dieser Datei:

[client]
port=3306
[mysql]
default-character-set=latin1
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.5/"
datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
character-set-server=latin1
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=100
query_cache_size=1024M
table_cache=256
tmp_table_size=25G
thread_cache_size=8
myisam_max_sort_file_size=100G
myisam_repair_threads = 2
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_additional_mem_pool_size=26M
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=13M
innodb_buffer_pool_size=23G
innodb_log_file_size=622M
innodb_thread_concurrency=18
innodb_file_per_table=TRUE
join_buffer_size=4G
max_heap_table_size = 10G

Geht es also nur darum, die oben genannten Einstellungen zu ändern, um für meine Umgebung besser zu funktionieren? Wenn ja, welche Einstellungen sollte ich verwenden? Ich bin der einzige, der diese Instanz jemals verwendet. Ich verwende es für mein persönliches Hobbyprojekt, bei dem große Datensätze statistisch analysiert werden. Daher kann ich zulassen, dass alle verfügbaren Ressourcen für meine eigenen Abfragen verwendet werden.

Was ist das Problem, wenn es nicht darum geht, diese Einstellungen zu ändern? Vielen Dank für jede Hilfe, die Sie anbieten können, um alles besser zu konfigurieren.

9
Michael McGowan

Da es sich um eine Windows-Installation handelt, hat @DTest immer noch die richtige Richtung angegeben.

Wenden Sie die folgende Formel an:

Die meisten Leute benutzen dies:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + (read_buffer_size + sort_buffer_size) X max_connections

Ich bevorzuge das:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + ((read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size) X max_connections)

Diese Variablen müssen angepasst werden, bis die Formel 80% der installierten RAM oder weniger) ergibt.

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
9
RolandoMySQLDBA

Ich würde versuchen, Ihre Puffergrößen zu verringern. Wenn Sie sie so groß machen, wie Sie sie haben, wird dies zu Problemen führen. Wie viel Speicher steht Ihnen zur Verfügung, um diese Werte auszuführen:

query_cache_size=1024M
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_buffer_pool_size=23G

Einige der Puffergrößen werden pro Thread zugewiesen, z. B. weist myisam_sort_buffer_size von 10G jedem Thread 10G zu.

Ich würde diese Werte zuerst drastisch reduzieren und dann untersuchen, welche Werte Sie wirklich benötigen, um so viel RAM zugewiesen (falls vorhanden)) zu haben.

4
Derek Downey

Ein schneller Weg, um festzustellen, wie viel Speicher MySQL zuordnen könnte, ist folgender:

wget mysqltuner.pl

Perl mysqltuner.pl

Wenn Sie dieses Skript ausführen, erfahren Sie, wie viel Prozent des installierten RAM MySQL glaubt, dass es sicher zugeordnet werden kann. Wenn die Antwort über 100% liegt, müssen Sie auf jeden Fall Ihre Puffergrößen verringern. Die wichtigsten Punkte sind:

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
key_buffer_size (nach 4G nicht wirklich wirksam)

@DTest hat bereits in seiner Antwort die Richtung für Sie festgelegt, also +1 für seine Antwort. Das Perl-Skript sagt Ihnen, was passiert, wenn Sie es nicht festlegen oder einen Wert ändern. Hier ist ein Beispiel:

Ein Kunde von mir hat
read_buffer_size = 128K
read_rnd_buffer_size = 256K
sort_buffer_size = 2M
join_buffer_size = 128K
Max_connections = 1050

Hier ist die Ausgabe von mysqltuner.pl:

MySQLTuner 1.2.0 - Major Hayden
Fehlerberichte, Funktionsanfragen und Downloads unter http://mysqltuner.com/
Mit '--help' ausführen, um zusätzliche Optionen und Ausgabefilterung zu erhalten
Bitte geben Sie Ihr MySQL-Administrator-Login ein: lwdba
Bitte geben Sie Ihr MySQL-Administratorkennwort ein:

-------- Allgemeine Statistiken ---------------------------------------- ----------
[-] Versionsprüfung für MySQLTuner-Skript übersprungen
[OK] Derzeit wird MySQL Version 5.0.51a-community-log unterstützt
[!!] Wechseln Sie zum 64-Bit-Betriebssystem - MySQL kann derzeit nicht den gesamten Arbeitsspeicher nutzen

-------- Storage Engine-Statistiken --------------------------------------- ----
[-] Status: + Archiv -BDB + Verbund + InnoDB -ISAM -NDBCluster
[-] Daten in MyISAM-Tabellen: 319M (Tabellen: 108)
[-] Daten in InnoDB-Tabellen: 2M (Tabellen: 5)
[!!] Fragmentierte Gesamttabellen: 22

-------- Leistungsmetriken ------------------------------------ ---------
[-] Bis zu: 52d 23h 15m 57s (72M q [15,875 qps], 241K conn, TX: 2B, RX: 1B)
[-] Liest/schreibt: 59%/41%
[-] Gesamtpuffer: 34,0 M global + 2,7 M pro Thread (maximal 1050 Threads)
[!!] Das Zuweisen von> 2 GB RAM auf 32-Bit-Systemen kann zu Systeminstabilität führen
[!!] Maximal mögliche Speichernutzung: 2,8 G (72% des installierten RAM)
[OK] Langsame Abfragen: 0% (54/72M)
[OK] Höchste Auslastung der verfügbaren Verbindungen: 6% (65/1050)
[OK] Schlüsselpuffergröße/Gesamt-MyISAM-Indizes: 8,0 M/82,1 M.
[OK] Trefferquote des Schlüsselpuffers: 100,0% (4B zwischengespeichert/1M Lesevorgänge)
[!!] Der Abfrage-Cache ist deaktiviert
[OK] Sortierungen, die temporäre Tabellen erfordern: 0% (0 temporäre Sortierungen/948K-Sortierungen)
[OK] Auf der Festplatte erstellte temporäre Tabellen: 3% (11 KB auf der Festplatte/insgesamt 380 KB)
[!!] Der Thread-Cache ist deaktiviert
[!!] Tabellen-Cache-Trefferquote: 0% (64 offen/32K geöffnet)
[OK] Verwendetes offenes Dateilimit: 2% (125/5K)
[OK] Sofort erworbene Tabellensperren: 99% (30 Millionen Sofort-/30 Millionen Sperren)
[OK] InnoDB-Datengröße/Pufferpool: 2,7 M/8,0 M.

-------- Empfehlungen ------------------------------------- ------------
Generelle Empfehlungen:
Führen Sie OPTIMIZE TABLE aus, um Tabellen für eine bessere Leistung zu defragmentieren
Aktivieren Sie das langsame Abfrageprotokoll, um fehlerhafte Abfragen zu beheben
Setzen Sie thread_cache_size als Startwert auf 4
Erhöhen Sie table_cache schrittweise, um die Grenzen des Dateideskriptors zu vermeiden
Zu justierende Variablen:
query_cache_size (> = 8M)
thread_cache_size (ab 4)
table_cache (> 64)

Bitte beachten Sie unter Leistungsmetriken

[-] Gesamtpuffer: 34,0 Millionen global + 2,7 Millionen pro Thread (maximal 1050 Threads)

dass MySQL bis zu 72% der installierten RAM basierend auf den Einstellungen in /etc/my.cnf) zuweisen kann.

Der 34M basiert auf innodb_buffer_pool_size und key_buffer_size zusammen

Die 2,7 Millionen pro Thread basierten auf read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size.

Vielfache der 2.7M basieren auf max_connections.

Daher müssen Sie diese Parameter tweeken, bis der Leistungsmetrikbericht angibt, dass Sie weniger als 100% (vorzugsweise weniger als 80%) des installierten Arbeitsspeichers haben.

4
RolandoMySQLDBA

Sie haben nicht gesagt, wie viel RAM Sie haben? Ich nehme an, es sind mindestens 32 GB.

innodb_buffer_pool_size - 23G

Gut für so viel RAM.

query_cache_size = 1G

Viel zu groß. Es ist ineffizient, wenn es groß ist. Empfehlen Sie nicht mehr als 50M.

key-buffer_size = 5G

Es könnte ein hartes Limit von 4G (noch) unter Windows geben, hatte ein hartes Limit von 4G. Ihr 5G hat sich möglicherweise in 1G verwandelt. Wie auch immer, wenn alle Ihre Tische InnoDB sind, warum sollten Sie den RAM verschwenden? Stellen Sie es auf 50M ein.

Da die Fehlermeldung genau 1G hatte, riecht es nach sort_buffer_size. 32M könnte vernünftig sein.

1
Rick James