it-swarm.it

Perché MySQL dice che ho esaurito la memoria?

Stavo cercando di eseguire un INSERT...SELECT Abbastanza grande in MySQL con JDBC e ho ottenuto la seguente eccezione:

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

Dal momento che in realtà non sto restituendo un oggetto ResultSet, ho pensato che lo spazio heap Java non dovesse essere un problema. Tuttavia, ho comunque provato a risolverlo e non ha funzionato. Ho provato per eseguire la dichiarazione in MySQL Workbench e ho ottenuto sostanzialmente la stessa cosa:

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

Dovrei avere un sacco di RAM per completare queste operazioni (abbastanza per adattarsi all'intero tavolo da cui sto selezionando), ma suppongo che ci siano varie impostazioni che devo modificare per sfruttare tutta la mia memoria. Sto eseguendo un Amazon EC2 High Memory Double Extra Large Instance con un AMI di Windows Server 2008. Ho provato a giocherellare con il file my.ini per utilizzare impostazioni migliori, ma per tutti So che avrei potuto peggiorare le cose. Ecco un dump di quel file:

[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

Quindi è solo una questione di modificare le impostazioni sopra per funzionare meglio per il mio ambiente? In tal caso, quali impostazioni dovrei usare? Sono l'unico che abbia mai usato questa istanza; Lo uso per il mio progetto di hobby personale che prevede l'analisi statistica di grandi set di dati. In quanto tale, sono libero di lasciarlo consumare tutte le risorse disponibili per le mie query.

Se non si tratta di modificare tali impostazioni, qual è il problema? Grazie per l'aiuto che puoi offrire per come configurare al meglio tutto.

9
Michael McGowan

Dato che si tratta di un'installazione di Windows, @DTest ha comunque fornito la direzione iniziale corretta.

Applica la seguente formula:

Molte persone usano questo:

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

Preferisco questo:

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)

Queste variabili sono quelle che devi regolare fino a quando la formula non fornisce l'80% di installato RAM o inferiore.

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
9
RolandoMySQLDBA

Vorrei provare ad abbassare le dimensioni del buffer. Renderli grandi quanto li hai causa problemi. Quanta memoria hai a disposizione per eseguire questi valori:

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

Alcune dimensioni del buffer sono allocate per thread, ad esempio myisam_sort_buffer_size di 10G alloca 10G per ogni thread.

Innanzitutto ridurrei drasticamente quei valori, e quindi indagerei su quali valori hai davvero bisogno di avere così tanto RAM allocato (se presente).

4
Derek Downey

Un modo rapido per determinare la quantità di memoria che MySQL pensa di poter allocare è il seguente:

wget mysqltuner.pl

Perl mysqltuner.pl

Quando esegui questo script, ti dirà quale percentuale del installato RAM MySQL pensa che possa allocare in modo sicuro. Se la risposta fornita è superiore al 100%, devi sicuramente ridurre le dimensioni del buffer. I principali su cui concentrarsi sono:

sort_buffer_size
Read_buffer_size
Read_rnd_buffer_size
Join_buffer_size
max_connections
key_buffer_size (non molto efficace oltre il 4G)

@DTest ha già impostato la direzione per te nella sua risposta, quindi +1 per la sua risposta. Lo script Perl ti dirà cosa succede se non lo imposti o se cambi un valore. Ecco un esempio:

Un mio cliente ha
Read_buffer_size = 128 K
Read_rnd_buffer_size = 256 K
Sort_buffer_size = 2M
Join_buffer_size = 128 K
Max_connections = 1050

Ecco l'output di mysqltuner.pl:

MySQLTuner 1.2.0 - Maggiore Hayden
Segnalazioni di bug, richieste di funzionalità e download su http://mysqltuner.com/
Esegui con '--help' per opzioni aggiuntive e filtro di output
Inserisci il tuo login amministrativo MySQL: lwdba
Inserisci la tua password amministrativa di MySQL:

-------- Statistiche generali ---------------------------------------- ----------
[-] Controllo versione saltata per lo script MySQLTuner
[OK] Attualmente in esecuzione MySQL versione 5.0.51a-community-log supportata
[!!] Passa al sistema operativo a 64 bit: attualmente MySQL non può utilizzare tutta la RAM

-------- Statistiche del motore di archiviazione --------------------------------------- ----
[-] Stato: + Archivio -BDB + Federato + InnoDB -ISAM -NDBCluster
[-] Dati nelle tabelle MyISAM: 319M (Tabelle: 108)
[-] Dati nelle tabelle InnoDB: 2M (Tabelle: 5)
[!!] Totale tabelle frammentate: 22

-------- Metriche delle prestazioni ---------------------------------------- ---------
[-] Fino a: 52d 23h 15m 57s (72M q [15.875 qps], 241K conn, TX: 2B, RX: 1B)
[-] Letture/Scritture: 59%/41%
[-] Buffer totali: 34,0 M globali + 2,7 M per thread (1050 thread massimo)
[!!] Allocazione> 2 GB RAM sui sistemi a 32 bit può causare instabilità del sistema
[!!] Utilizzo massimo di memoria possibile: 2,8 G (72% della RAM installata)
[OK] Query lente: 0% (54/72M)
[OK] Massimo utilizzo di connessioni disponibili: 6% (65/1050)
[OK] Dimensione buffer chiave/indici MyISAM totali: 8,0 M/82,1 M
[OK] Percentuale di hit buffer chiave: 100,0% (4B memorizzato nella cache/1 milione di letture)
[!!] La cache delle query è disabilitata
[OK] Ordinamenti che richiedono tabelle temporanee: 0% (ordinamenti 0 temp/ordinamenti 948K)
[OK] Tabelle temporanee create su disco: 3% (11K su disco/380K totali)
[!!] La cache del thread è disabilitata
[!!] Percentuale di riscontri nella cache della tabella: 0% (64 aperti/32K aperti)
[OK] Limite file aperto utilizzato: 2% (125/5K)
[OK] Blocchi tabella acquisiti immediatamente: 99% (blocchi 30 M immediati/30 M)
[OK] Dimensione dati/pool buffer InnoDB: 2,7 M/8,0 M

-------- Consigli ----------------------------------------- ------------
Raccomandazioni generali:
Esegui OPTIMIZE TABLE per deframmentare le tabelle per prestazioni migliori
Abilita il registro delle query lente per risolvere le query errate
Imposta thread_cache_size su 4 come valore iniziale
Aumenta gradualmente table_cache per evitare i limiti del descrittore di file
Variabili da regolare:
query_cache_size (> = 8M)
thread_cache_size (inizio alle 4)
table_cache (> 64)

Si prega di notare sotto le metriche delle prestazioni

[-] Buffer totali: 34,0 M globali + 2,7 M per thread (1050 thread massimo)

che MySQL può allocare fino al 72% di installato RAM in base alle impostazioni in /etc/my.cnf.

34M si basa su innodb_buffer_pool_size e key_buffer_size combinati

Il 2.7M per thread si basava su read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size.

I multipli di 2.7M si basano su max_connections.

Pertanto, è necessario modificare questi parametri fino a quando il rapporto sulle metriche delle prestazioni indica che hai meno del 100% (preferibilmente inferiore all'80%) di RAM installata.

4
RolandoMySQLDBA

Non hai detto quanto RAM hai? Presumo che sia almeno 32 GB.

innodb_buffer_pool_size - 23G

Buono per così tanta RAM.

query_cache_size = 1G

Troppo grande. È inefficiente quando è grande. Raccomandare non più di 50M.

key-buffer_size = 5G

Potrebbe esserci un limite rigido di 4G (ancora) su Windows, un limite rigido di 4G. Il tuo 5G potrebbe essere diventato 1G. Comunque, se tutti i tuoi tavoli sono InnoDB, perché sprecare il ram. Impostalo su 50M.

Poiché il messaggio di errore aveva esattamente 1G, ha l'odore di sort_buffer_size. 32M potrebbe essere ragionevole.

1
Rick James