Utilizzo massimo della memoria di MySQL


111

Vorrei sapere come è possibile impostare un limite massimo alla quantità di memoria utilizzata da MySQL su un server Linux.

In questo momento, MySQL continuerà a occupare memoria con ogni nuova query richiesta in modo che alla fine si esaurisca. C'è un modo per porre un limite in modo che MySQL non utilizzi più di tale importo?


4
MySQL non "occupa memoria per ogni nuova query e alla fine si esaurisce". L'utilizzo della memoria è molto più complesso di così.
Rick James

Risposte:


183

L'utilizzo massimo della memoria da parte di MySQL dipende molto dall'hardware, dalle impostazioni e dal database stesso.

Hardware

L'hardware è la parte più ovvia. Maggiore è la RAM, più veloci sono i dischi ftw . Non credere a quelle lettere di notizie mensili o settimanali però. MySQL non è scalabile in modo lineare, nemmeno su hardware Oracle. È un po 'più complicato di così.

La linea di fondo è: non esiste una regola generale per ciò che è consigliato per la tua configurazione MySQL. Tutto dipende dall'uso corrente o dalle proiezioni.

Impostazioni e database

MySQL offre innumerevoli variabili e interruttori per ottimizzarne il comportamento. Se si verificano problemi, è davvero necessario sedersi e leggere il manuale (f'ing).

Per quanto riguarda il database, alcuni importanti vincoli:

  • motore di tabella ( InnoDB, MyISAM, ...)
  • taglia
  • indici
  • uso

La maggior parte dei suggerimenti MySQL su stackoverflow ti parlerà delle 5-8 cosiddette impostazioni importanti. Prima di tutto, non tutte hanno importanza, ad esempio allocare molte risorse a InnoDB e non usare InnoDB non ha molto senso perché quelle risorse vengono sprecate.

Oppure - molte persone suggeriscono di aumentare la max_connectionvariabile - beh, poco sanno che implica anche che MySQL allocherà più risorse per soddisfare quelle max_connections- se mai necessario. La soluzione più ovvia potrebbe essere chiudere la connessione al database nel tuo DBAL o abbassare il wait_timeoutper liberare quei thread.

Se capisci la mia idea, c'è davvero molto, molto da leggere e da imparare.

motori

I motori di tabella sono una decisione piuttosto importante, molte persone se ne dimenticano all'inizio e poi improvvisamente si trovano a combattere con un MyISAMtavolo da 30 GB che blocca e blocca l'intera applicazione.

Non intendo dire che MyISAM fa schifo , ma InnoDBpuò essere ottimizzato per rispondere quasi o quasi alla stessa velocità MyISAMe offre qualcosa come il blocco delle righe UPDATEmentre MyISAMblocca l'intera tabella quando viene scritto.

Se sei libero di eseguire MySQL sulla tua infrastruttura, potresti anche voler controllare il server percona perché tra i molti contributi di aziende come Facebook e Google (che sanno velocemente), include anche il drop di Percona- in sostituzione di InnoDB, chiamato XtraDB.

Vedi la mia sintesi per l'installazione di percona-server (e -client) (su Ubuntu): http://gist.github.com/637669

Taglia

La dimensione del database è molto, molto importante: che tu ci creda o no, la maggior parte delle persone su Intarweb non ha mai gestito un'installazione MySQL di grandi dimensioni e di scrittura, ma quelle esistono davvero. Alcune persone trolleranno e diranno qualcosa del tipo "Usa PostgreSQL !!! 111", ma per ora ignoriamole.

La linea di fondo è: a giudicare dalle dimensioni, la decisione sull'hardware deve essere presa. Non puoi davvero far funzionare velocemente un database da 80 GB su 1 GB di RAM.

Indici

Non è: più siamo, meglio è. Devono essere impostati solo gli indici necessari e deve essere verificato l'utilizzo EXPLAIN. Aggiungete a ciò che MySQL EXPLAINè davvero limitato, ma è un inizio.

Configurazioni suggerite

Riguardo a questi my-large.cnfe ai my-medium.cnffile, non so nemmeno per chi siano stati scritti. Rotola il tuo.

Primer per l'accordatura

Un ottimo inizio è il manuale di messa a punto . È uno script bash (suggerimento: avrai bisogno di Linux) che prende l'output di SHOW VARIABLESe SHOW STATUSe lo racchiude in una raccomandazione, si spera utile. Se il tuo server ha funzionato per un po 'di tempo, la raccomandazione sarà migliore poiché ci saranno dati su cui basarli.

Il primer per l'accordatura non è però una salsa magica. Dovresti comunque documentarti su tutte le variabili che suggerisce di cambiare.

Lettura

Mi piace molto consigliare mysqlperformanceblog . È un'ottima risorsa per tutti i tipi di suggerimenti relativi a MySQL. E non è solo MySQL, sanno anche molto sull'hardware giusto o consigliano configurazioni per AWS, ecc. Questi ragazzi hanno anni e anni di esperienza.

Un'altra grande risorsa è planet-mysql , ovviamente.


Non so tuning primer, come si confronta con mysqltuner?
greg0ire

38

Usiamo queste impostazioni:

etc/my.cnf
innodb_buffer_pool_size = 384M
key_buffer = 256M
query_cache_size = 1M
query_cache_limit = 128M
thread_cache_size = 8
max_connections = 400
innodb_lock_wait_timeout = 100

per un server con le seguenti specifiche:

Dell Server
CPU cores: Two
Processor(s): 1x Dual Xeon
Clock Speed: >= 2.33GHz
RAM: 2 GBytes
Disks: 1×250 GB SATA

16
Penso che tu (e l'autore a cui ti colleghi) abbiate query_cache_size e query_cache_limit nel modo sbagliato. Stai dicendo a MySQL: alloca una cache da 1 MB ma non inserire query superiori a 128 MB. dev.mysql.com/doc/refman/5.0/en/query-cache-configuration.html
agtb

Abbasserei max_connections. Deciderei quale motore utilizzare e non allocherei molto spazio per entrambi.
Rick James

19

L'utilizzo della memoria del database è un argomento complesso. Il MySQL Performance Blog fa un buon lavoro nel rispondere alla tua domanda ed elenca molte ragioni per cui è estremamente poco pratico "riservare" la memoria.

Se vuoi davvero imporre un limite rigido, puoi farlo, ma dovresti farlo a livello di sistema operativo poiché non ci sono impostazioni integrate. In Linux, potresti utilizzare ulimit , ma probabilmente dovresti modificare il modo in cui MySQL si avvia per imporlo.


La soluzione migliore è mettere a punto il server, in modo che una combinazione delle normali impostazioni di memoria MySQL comporterà un utilizzo della memoria generalmente inferiore da parte della tua installazione MySQL. Questo ovviamente avrà un impatto negativo sulle prestazioni del tuo database, ma alcune delle impostazioni che puoi modificare my.inisono:

key_buffer_size
query_cache_size
query_cache_limit
table_cache
max_connections
tmp_table_size
innodb_buffer_pool_size

Comincerei da lì e vedrei se riesci a ottenere i risultati desiderati. Ci sono molti articoli in giro sulla regolazione delle impostazioni di memoria di MySQL.


Modificare:

Nota che alcuni nomi di variabili sono cambiati nelle versioni 5.1.x più recenti di MySQL .

Per esempio:

table_cache

È ora:

table_open_cache

2
Ciao! Grazie per la tua risposta. Ho notato che l'equazione citata dalle persone è la seguente: key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections = Total Memory. Ho impostato quanto segue: key_buffer_size = 128M, read_buffer_size = 1M, sort_buffer_size = 2M, max_connections = 120 e la memoria totale sul server è 512M. Tuttavia, dopo molte query, la memoria libera è scesa fino a 12M e probabilmente continuerebbe a diminuire con un ulteriore utilizzo. C'è un motivo per cui è così e può essere prevenuto? Grazie!

O forse devo prendere in considerazione non la memoria totale sul server (512M) ma la memoria libera (cioè la memoria disponibile dopo aver caricato tutti i programmi relativi al sistema operativo e altri)?

1
Se hai intenzione di modificare tmp_table_size con l'intenzione di aumentare la dimensione delle tabelle temporanee che possono essere memorizzate nella RAM, ricorda di aumentare anche max_heap_table_size - poiché MySQL usa il minimo dei due ...
Dave Rix

1
@TimothyMilsud - Nessuna formula del genere funziona davvero. E la maggior parte dei server funziona abbastanza bene quando una formula afferma che viene utilizzata troppa RAM.
Rick James

19

mysqld.exe utilizzava 480 MB di RAM. Ho scoperto di aver aggiunto questo parametro a my.ini

table_definition_cache = 400

che ha ridotto l'utilizzo della memoria da oltre 400.000 kb a 105.000 kb


In quale sezione va inserito? L'ho aggiunto al mio e il servizio si è rifiutato di avviarsi.
Errore di sintassi

Non importa, l'ho spostato sotto [wampmysqld] e ha funzionato alla grande e ha ridotto la memoria che stavo usando in modo significativo. Penso che potrebbe aver accelerato anche i miei caricamenti di pagine localhost nel processo, ora sembrano più veloci.
Errore di sintassi

Sebbene il valore predefinito e minimo sia 400, cosa lo ha portato a un valore superiore a 400 nel tuo caso?
Wadih M.

5

in /etc/my.cnf:

[mysqld]
...

performance_schema = 0

table_cache = 0
table_definition_cache = 0
max-connect-errors = 10000

query_cache_size = 0
query_cache_limit = 0

...

Buon lavoro su server con 256 MB di memoria.


Perché è table_definition_cache= 0? Qualche spiegazione sarebbe carina. E fondamentalmente non stai memorizzando nella cache le query ... lo stesso effetto se tu query_cache_type = 0:)
Khom Nazid

0

Se stai cercando di ottimizzare il tuo contenitore mysql docker, il comando seguente potrebbe aiutarti. Sono stato in grado di eseguire il contenitore docker mysql da un valore predefinito di 480 MB a soli 100 MB

docker run -d -p 3306: 3306 -e MYSQL_DATABASE = test -e MYSQL_ROOT_PASSWORD = anche -e MYSQL_USER = test -e MYSQL_PASSWORD = test -v / mysql: / var / lib / mysql --name mysqldb mysql --table_definition_cache = 100 --performance_schema = 0 --default-authentication-plugin = mysql_native_password

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.