MySQL non rilascia memoria


8

MySQL sembra voler mantenere un'intera tabella nella cache (dimensioni della tabella = ~ 20 GB) dopo l'esecuzione di inserimenti di grandi dimensioni o istruzioni select. In questo momento il mio pool di buffer innodb è di 20 GB. La RAM totale è di 32 GB. Fornirò l'utilizzo della memoria e l'output dallo stato innodb, nonché l'output da mysqltuner. Mi ha fatto impazzire negli ultimi giorni. Per favore aiuto! Apprezzo qualsiasi feedback e per favore fatemi sapere se avete bisogno di ulteriori informazioni.

Inoltre, l'esecuzione di un "FLUSH TABLES" li chiude e li riapre in memoria. Almeno penso che sia quello che sta succedendo. Ecco lo stato di memoria corrente di innodb prima di eseguire un sacco di inserti:

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 21978152960; in additional pool allocated 0
Dictionary memory allocated 6006471
Buffer pool size   1310719
Free buffers       347984
Database pages     936740
Old database pages 345808
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 78031, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 551887, created 384853, written 4733512
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 936740, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

mysqld percent utilizzo di memoria: 60,9%

mysqld percento utilizzo di memoria dopo inserti (record da 1 mil): 63,3%

e poi dopo più inserti (3 mil record): 70,2%

non dovrebbe superare il 62,5% circa ? (20 / 32GB) RAM totale?

output dall'alto ordinamento del mio utilizzo MEM:

top - 14:30:56 up 23:25,  3 users,  load average: 3.63, 2.31, 1.91
Tasks: 208 total,   4 running, 204 sleeping,   0 stopped,   0 zombie
Cpu(s): 96.0%us,  3.0%sy,  0.0%ni,  0.0%id,  1.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  28821396k total, 28609868k used,   211528k free,   138696k buffers
Swap: 33554428k total,    30256k used, 33524172k free,  1208184k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 1228 mysql     20   0 25.1g  19g 5512 S   31 70.2  62:01.10 mysqld

ecco l'output della memoria innodb dopo l'esecuzione di questi inserimenti:

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 21978152960; in additional pool allocated 0
Dictionary memory allocated 6006471
Buffer pool size   1310719
Free buffers       271419
Database pages     1011886
Old database pages 373510
Modified db pages  4262
Pending reads 1
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 82521, not young 0
7.08 youngs/s, 0.00 non-youngs/s
Pages read 585218, created 426667, written 5192189
24.08 reads/s, 53.08 creates/s, 1135.07 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1011886, unzip_LRU len: 0
I/O sum[0]:cur[266], unzip sum[0]:cur[0]

Secondo lo stato di innodb, la memoria totale allocata è la stessa, eppure il mio sistema operativo (Virtual Ubuntu Server 12.04) sta segnalando un uso di memoria maggiore di quello. L'uso della memoria rimane lo stesso e qui lo sto definendo il servizio MySQL che non "rilascia" la memoria. Eventuali suggerimenti?

uscita da mysqltuner.pl:

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM
[--] Data in MyISAM tables: 226M (Tables: 287)
[--] Data in InnoDB tables: 33G (Tables: 1000)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
[--] Data in MEMORY tables: 0B (Tables: 1)
[!!] Total fragmented tables: 959

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 23h 14m 27s (1M q [14.603 qps], 6K conn, TX: 16B, RX: 1B)
[--] Reads / Writes: 46% / 54%
[--] Total buffers: 22.2G global + 2.7M per thread (151 max threads)
[OK] Maximum possible memory usage: 22.6G (82% of installed RAM)
[OK] Slow queries: 0% (6/1M)
[OK] Highest usage of available connections: 6% (10/151)
[OK] Key buffer size / total MyISAM indexes: 2.0G/58.7M
[OK] Key buffer hit rate: 100.0% (216M cached / 38K reads)
[OK] Query cache efficiency: 81.2% (799K cached / 984K selects)
[!!] Query cache prunes per day: 5561
[OK] Sorts requiring temporary tables: 4% (819 temp sorts / 16K sorts)
[!!] Temporary tables created on disk: 27% (6K on disk / 22K total)
[OK] Thread cache hit rate: 99% (11 created / 6K connections)
[!!] Table cache hit rate: 0% (97 open / 10K opened)
[OK] Open file limit used: 12% (129/1K)
[OK] Table locks acquired immediately: 99% (433K immediate / 433K locks)
[!!] InnoDB  buffer pool / data size: 20.0G/33.6G
[OK] InnoDB log waits: 0
-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
    Enable the slow query log to troubleshoot bad queries
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_cache gradually to avoid file descriptor limits
    Read this before increasing table_cache over 64: http://bit.ly/1mi7c4C
Variables to adjust:
    query_cache_size (> 128M)
    tmp_table_size (> 128M)
    max_heap_table_size (> 16M)
    table_cache (> 431)
    innodb_buffer_pool_size (>= 33G)

Risposte:


8

Innanzitutto, dai un'occhiata all'architettura InnoDB (per gentile concessione di Percona CTP Vadim Tkachenko)

Architettura di InnoDB

InnoDB

Il tuo stato per il pool di buffer dice

Dimensione pool buffer 1310719

Questa è la dimensione del buffer in Pages. Ogni pagina è 16K . Quello risulta 20G - 16K.

Si noti quanto segue: I dati sono stati inseriti nel pool di buffer InnoDB. Che cosa è cambiato?

Buffer pool size   1310719 
Free buffers       271419 (It was 347984)
Database pages     1011886 (Is was 936740)
Old database pages 373510 (It was 345808)
Modified db pages  4262 (It was 0)

Inoltre, notare la differenza tra le dimensioni del pool di buffer in Pages.

1310719 (dimensione pool buffer) - 1011886 (pagine del database) = 298833

Sono 298833 pagine InnoDB. Quanto spazio è ???

mysql> select FORMAT(((1310719  - 1011886) * 16384) / power(1024,3),3) SpaceUsed;
+-----------+
| SpaceUsed |
+-----------+
| 4.560     |
+-----------+

Sono 4,56 GB. Quello spazio viene utilizzato per la sezione Inserisci buffer del pool di buffer InnoDB (aka Change Buffer) . Questo è usato per mitigare le modifiche agli indici non unici nel file del tablespace di sistema (che tutti sono venuti a conoscenza come ibdata1).

Il motore di archiviazione InnoDB gestisce gli interni del pool di buffer. Pertanto, InnoDB non supererà mai il 62,5% di RAM. Inoltre, la RAM per il pool di buffer non viene mai restituita.

DA DOVE VIENE IL 70,2% DI RAM ???

Guarda indietro all'output di mysqltuner.plqueste righe

[OK] Maximum possible memory usage: 22.6G (82% of installed RAM)
Key buffer size / total MyISAM indexes: 2.0G/58.7M
[--] Total buffers: 22.2G global + 2.7M per thread (151 max threads)

mysqld ha tre modi principali di allocare RAM

Qualsiasi piccolo picco in DB Connections aumenterà la RAM oltre la soglia del 62,5% che vedi per InnoDB.

MyISAM (nota a margine)

Ciò che attira la mia attenzione è

Key buffer size / total MyISAM indexes: 2.0G/58.7M

Dal momento che hai così pochi indici per MyISAM. È possibile impostare key_buffer_size su 64M.

Non è necessario riavviare mysql per questo. Corri

SET GLOBAL ket_buffer_size = 1024 * 1024 * 64;

Quindi, modificalo in my.cnf

[mysqld]
key_Buffer_size = 64M

Questo darà al sistema operativo 2 GB di RAM. La tua VM ti adorerà semplicemente per questo !!!

Provaci !!!

AVVERTIMENTO

L'esecuzione FLUSH TABLESsu tabelle InnoDB semplicemente chiude i file rispetto ai .ibdfile. Questo non spingerà direttamente i cambiamenti direttamente. Le modifiche devono migrare attraverso le pipe di InnoDB. Questo è il motivo per cui vedi il picco Modified db pages. Le 4262 pagine modificate (66,59 MB) vengono scaricate quando InnoDB ne pianifica lo scaricamento.


grazie mille per l'analisi approfondita. Ora ha molto più senso-- quindi è vero che il pool di buffer innodb rimarrà al massimo utilizzo della memoria nel tempo (20 GB)? E la memoria totale che mysqld userà mai è dell'82% ??
Cherner,

Questo è un sì per entrambe le domande
RolandoMySQLDBA

@RolandoMySQLDBA, Se ho capito bene, MySQL non rilascia la memoria e questo è quello che è. No?
Malus,

1
@MalusJan La mia risposta non riguarda il rilascio della memoria. La mia risposta riguarda la quantità di RAM utilizzata per StorageEngines e DB Connections. A volte, connessioni DB persistenti non correttamente chiuse possono contenere RAM allocata. Le cache per i buffer del motore di archiviazione possono essere ridimensionate dinamicamente per MyISAM (MySQL 5.x +) e InnoDB (MySQL 5.7+). Le cache per le connessioni DB possono essere ridimensionate dinamicamente per le nuove connessioni in entrata (non le connessioni attualmente aperte). La memoria non viene rilasciata a causa di bug di perdita di memoria in mysqld.
RolandoMySQLDBA

@RolandoMySQLDBA. Sul server abbiamo più di 10 database e dobbiamo creare un dump ogni giorno e ognuno mysqldumpprende un po 'di memoria e non li rilascia. Quindi, dopo tutto il dump, abbiamo circa l'80% di RAM occupata dal processo mysql. Hai qualche soluzione per questo? Grazie
Malus

0

Ho affrontato un simile tipo di problema. Domanda: stai usando la configurazione della memoria divisa? (THP e condivisi) Se sì, disabilitare gli hugepage e lasciare che MySQL gestisca la memoria e continui a monitorarla. Controlla anche quanti processi paralleli sono in esecuzione sul server, inclusi i processi in modalità Sospensione. Se si utilizza la configurazione della memoria condivisa, è necessaria più memoria per questo server.

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.