Mysql
 sql >> Database >  >> RDS >> Mysql

Cosa controllare se l'utilizzo della memoria MySQL è elevato

Uno dei fattori chiave di un server di database MySQL performante è avere una buona allocazione e utilizzo della memoria, specialmente quando lo si esegue in un ambiente di produzione. Ma come si può determinare se l'utilizzo di MySQL è ottimizzato? È ragionevole avere un elevato utilizzo della memoria o richiede una messa a punto? E se mi imbattessi in una perdita di memoria?

Trattiamo questi argomenti e mostriamo le cose che puoi controllare in MySQL per determinare tracce di utilizzo elevato della memoria.

allocazione della memoria in MySQL

Prima di approfondire il titolo specifico dell'argomento, fornirò solo una breve informazione su come MySQL utilizza la memoria. La memoria svolge una risorsa significativa per la velocità e l'efficienza durante la gestione di transazioni simultanee e l'esecuzione di query di grandi dimensioni. Ogni thread in MySQL richiede memoria che viene utilizzata per gestire le connessioni client e questi thread condividono la stessa memoria di base. Variabili come thread_stack (stack per i thread), net_buffer_length (per il buffer di connessione e il buffer dei risultati) o con max_allowed_packet in cui la connessione e il risultato si ingrandiranno dinamicamente fino a questo valore quando necessario, sono variabili che influiscono sull'utilizzo della memoria. Quando un thread non è più necessario, la memoria allocata ad esso viene rilasciata e restituita al sistema a meno che il thread non torni nella cache del thread. In tal caso, la memoria rimane allocata. Join di query, cache di query, ordinamento, cache di tabelle e definizioni di tabelle richiedono memoria in MySQL, ma sono attribuite a variabili di sistema che puoi configurare e impostare.

Nella maggior parte dei casi, le variabili specifiche della memoria impostate per una configurazione sono destinate a una configurazione specifica basata sullo storage come MyISAM o InnoDB. Quando un'istanza mysqld viene generata all'interno del sistema host, MySQL alloca buffer e cache per migliorare le prestazioni delle operazioni del database in base ai valori impostati su una configurazione specifica. Ad esempio, le variabili più comuni che ogni DBA imposterà in InnoDB sono le variabili innodb_buffer_pool_size e innodb_buffer_pool_instances, entrambe correlate all'allocazione della memoria del pool di buffer che contiene i dati memorizzati nella cache per le tabelle InnoDB. È consigliabile se si dispone di memoria di grandi dimensioni e si prevede di gestire transazioni di grandi dimensioni impostando innodb_buffer_pool_instances per migliorare la concorrenza dividendo il pool di buffer in più istanze di pool di buffer.

Mentre per MyISAM, devi gestire key_buffer_size per gestire la quantità di memoria che gestirà il key buffer. MyISAM alloca anche il buffer per ogni thread simultaneo che contiene una struttura di tabella, strutture di colonna per ogni colonna e un buffer di dimensione 3 * N sono allocati (dove N è la lunghezza massima della riga, senza contare le colonne BLOB). MyISAM mantiene anche un buffer di riga aggiuntivo per uso interno.

MySQL alloca anche memoria per le tabelle temporanee a meno che non diventi troppo grande (determinato da tmp_table_size e max_heap_table_size). Se stai utilizzando tabelle MEMORY e la variabile max_heap_table_size è impostata su un valore molto alto, ciò può richiedere anche una grande quantità di memoria poiché la variabile di sistema max_heap_table_size determina quanto può crescere una tabella e non vi è alcuna conversione in formato su disco.

MySQL ha anche uno schema delle prestazioni che è una funzionalità per monitorare le attività di MySQL a basso livello. Una volta abilitato, alloca in modo dinamico la memoria in modo incrementale, ridimensionando l'utilizzo della memoria in base al carico effettivo del server, invece di allocare la memoria richiesta durante l'avvio del server. Una volta allocata la memoria, non viene liberata fino al riavvio del server.

MySQL può anche essere configurato per allocare grandi aree di memoria per il suo pool di buffer se si utilizza Linux e se il kernel è abilitato per il supporto di pagine di grandi dimensioni, ovvero utilizzando HugePages.

Cosa controllare una volta che la memoria MySQL è alta

Verifica query in esecuzione

È molto comune che i DBA MySQL si mettano in contatto prima con ciò che sta succedendo con il server MySQL in esecuzione. Le procedure di base sono il controllo dell'elenco dei processi, il controllo dello stato del server e il controllo dello stato del motore di archiviazione. Per fare queste cose, in pratica, devi solo eseguire la serie di query accedendo a MySQL. Vedi sotto:

Per visualizzare le query in esecuzione,

mysql> SHOW [FULL] PROCESSLIST;

La visualizzazione dell'elenco di processi corrente rivela le query che sono in esecuzione attivamente o addirittura processi inattivi o inattivi. È molto importante ed è una routine importante avere un record delle query in esecuzione. Come notato su come MySQL alloca la memoria, l'esecuzione delle query utilizzerà l'allocazione della memoria e può causare drasticamente problemi di prestazioni se non monitorata.

Visualizza le variabili di stato del server MySQL,

mysql> SHOW SERVER STATUS\G

o filtra variabili specifiche come

mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);

Le variabili di stato di MySQL servono come informazioni statistiche per acquisire dati metrici per determinare come si comporta il tuo MySQL osservando i contatori dati dai valori di stato. Ci sono alcuni valori qui che ti danno uno sguardo che influisce sull'utilizzo della memoria. Ad esempio, controllando il numero di thread, il numero di cache delle tabelle o l'utilizzo del pool di buffer

...

| Created_tmp_disk_tables                 | 24240 |

| Created_tmp_tables                      | 334999 |

…

| Innodb_buffer_pool_pages_data           | 754         |

| Innodb_buffer_pool_bytes_data           | 12353536         |

...

| Innodb_buffer_pool_pages_dirty          | 6         |

| Innodb_buffer_pool_bytes_dirty          | 98304         |

| Innodb_buffer_pool_pages_flushed        | 30383         |

| Innodb_buffer_pool_pages_free           | 130289         |

…

| Open_table_definitions                  | 540 |

| Open_tables                             | 1024 |

| Opened_table_definitions                | 540 |

| Opened_tables                           | 700887 |

...

| Threads_connected                             | 5 |

...

| Threads_cached    | 2 |

| Threads_connected | 5     |

| Threads_created   | 7 |

| Threads_running   | 1 |

Visualizza lo stato del monitor del motore, ad esempio lo stato di InnoDB

mysql> SHOW ENGINE INNODB STATUS\G

Lo stato di InnoDB rivela anche lo stato corrente delle transazioni che il motore di archiviazione sta elaborando. Ti dà la dimensione dell'heap di una transazione, indici hash adattivi che rivelano il suo utilizzo del buffer o ti mostra le informazioni sul pool di buffer innodb proprio come nell'esempio seguente:

---TRANSACTION 10798819, ACTIVE 0 sec inserting, thread declared inside InnoDB 1201

mysql tables in use 1, locked 1

1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 8801

MySQL thread id 68481, OS thread handle 139953970235136, query id 681821 localhost root copy to tmp table

ALTER TABLE NewAddressCode2_2 ENGINE=INNODB



…

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 528, free list len 43894, seg size 44423, 1773 merges

merged operations:

 insert 63140, delete mark 0, delete 0

discarded operations:

 insert 0, delete mark 0, delete 0

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 637 buffer(s)

Hash table size 553193, node heap has 772 buffer(s)

Hash table size 553193, node heap has 1239 buffer(s)

Hash table size 553193, node heap has 2 buffer(s)

Hash table size 553193, node heap has 0 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

115320.41 hash searches/s, 10292.51 non-hash searches/s

...

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 2235564032

Dictionary memory allocated 3227698

Internal hash tables (constant factor + variable factor)

    Adaptive hash index 78904768        (35404352 + 43500416)

    Page hash           277384 (buffer pool 0 only)

    Dictionary cache    12078786 (8851088 + 3227698)

    File system         1091824 (812272 + 279552)

    Lock system         5322504 (5313416 + 9088)

    Recovery system     0 (0 + 0)

Buffer pool size   131056

Buffer pool size, bytes 2147221504

Free buffers       8303

Database pages     120100

Old database pages 44172

Modified db pages  108784

Pending reads      0

Pending writes: LRU 2, flush list 342, single page 0

Pages made young 533709, not young 181962

3823.06 youngs/s, 1706.01 non-youngs/s

Pages read 4104, created 236572, written 441223

38.09 reads/s, 339.46 creates/s, 1805.87 writes/s

Buffer pool hit rate 1000 / 1000, young-making rate 12 / 1000 not 5 / 1000

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

LRU len: 120100, unzip_LRU len: 0

I/O sum[754560]:cur[8096], unzip sum[0]:cur[0]

…

Un'altra cosa da aggiungere, puoi anche usare Performance Schema e sys schema per monitorare il consumo di memoria e l'utilizzo da parte del tuo server MySQL. Per impostazione predefinita, la maggior parte degli strumenti è disabilitata per impostazione predefinita, quindi ci sono operazioni manuali da fare per usarlo.

Verifica la presenza di Swappiness 

Ad ogni modo, è probabile che MySQL stia scambiando la sua memoria su disco. Questa è spesso una situazione molto comune, specialmente quando il server MySQL e l'hardware sottostante non sono impostati in modo ottimale in parallelo ai requisiti previsti. Ci sono alcuni casi in cui la domanda di traffico non è stata prevista, la memoria potrebbe aumentare sempre di più, specialmente se vengono eseguite query errate che consumano o utilizzano molto spazio di memoria causando un peggioramento delle prestazioni poiché i dati vengono prelevati sul disco anziché nel buffer. Per verificare lo swappiness, esegui il comando freemem o vmstat proprio come di seguito,

[[email protected] ~]# free -m

              total        used free      shared buff/cache available

Mem:           3790 2754         121 202 915         584

Swap:          1535 39        1496

[[email protected] ~]# vmstat 5 5

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

 r  b swpd   free buff  cache si so    bi bo in cs us sy id wa st

 2  0 40232 124100      0 937072 2 3 194  1029 477 313 7 2 91 1  0

 0  0 40232 123912      0 937228 0 0   0 49 1247 704 13 3 84  0 0

 1  0 40232 124184      0 937212 0 0   0 35 751 478 6 1 93  0 0

 0  0 40232 123688      0 937228 0 0   0 15 736 487 5 1 94  0 0

 0  0 40232 123912      0 937220 0 0   3 74 1065 729 8 2 89  0 0

Puoi anche controllare usando procfs e raccogliere informazioni come andare su /proc/vmstat o /proc/meminfo.

Utilizzo di Perf, gdb e Valgrind con Massif

L'uso di strumenti come perf, gdb e valgrind ti aiuta ad approfondire un metodo più avanzato per determinare l'utilizzo della memoria MySQL. Ci sono momenti in cui un risultato interessante diventa un mistero per risolvere il consumo di memoria che porta al tuo sconcerto in MySQL. Ciò si traduce nella necessità di avere più scetticismo e l'utilizzo di questi strumenti consente di indagare su come MySQL utilizza la gestione della memoria dall'allocazione all'utilizzo per l'elaborazione di transazioni o processi. Ciò è utile, ad esempio, se stai osservando che MySQL si comporta in modo anomalo, il che potrebbe causare una configurazione errata o rilevare perdite di memoria.

Ad esempio, l'utilizzo di perf in MySQL rivela più informazioni in un report a livello di sistema:

[[email protected] ~]# perf report --input perf.data --stdio

# To display the perf.data header info, please use --header/--header-only options.

#

#

# Total Lost Samples: 0

#

# Samples: 54K of event 'cpu-clock'

# Event count (approx.): 13702000000

#

# Overhead  Command Shared Object        Symbol                                                                                                                                                                                             

# ........  ....... ...................  ...................................................................................................................................................................................................

#

    60.66%  mysqld [kernel.kallsyms]    [k] _raw_spin_unlock_irqrestore

     2.79%  mysqld   libc-2.17.so         [.] __memcpy_ssse3

     2.54%  mysqld   mysqld             [.] ha_key_cmp

     1.89%  mysqld   [vdso]             [.] __vdso_clock_gettime

     1.05%  mysqld   mysqld             [.] rec_get_offsets_func

     1.03%  mysqld   mysqld             [.] row_sel_field_store_in_mysql_format_func

     0.92%  mysqld   mysqld             [.] _mi_rec_pack

     0.91%  mysqld   [kernel.kallsyms]    [k] finish_task_switch

     0.90%  mysqld   mysqld             [.] row_search_mvcc

     0.86%  mysqld   mysqld             [.] decimal2bin

     0.83%  mysqld   mysqld             [.] _mi_rec_check

….

Dato che questo può essere un argomento speciale su cui approfondire, ti suggeriamo di esaminare questi ottimi blog esterni come riferimenti, perf Nozioni di base per la profilazione MySQL, Trovare problemi di ridimensionamento MySQL usando perf o impara come eseguire il debug usando valgrind con massif.

Modo efficiente per controllare l'utilizzo della memoria MySQL

L'utilizzo di ClusterControl allevia qualsiasi routine di routine come esaminare i runbook o persino creare i propri playbook che forniscano report per te. In ClusterControl, hai Dashboard (usando SCUMM) in cui puoi avere una rapida panoramica dei tuoi nodi MySQL. Ad esempio, visualizzando la dashboard generale di MySQL,

puoi determinare come funziona il nodo MySQL,

Le immagini sopra mostrano variabili che influiscono sull'utilizzo della memoria MySQL. Puoi controllare come le metriche per l'ordinamento di cache, tabelle temporanee, thread connessi, cache di query o storage engine innodb buffer pool o il key buffer di MyISAM.

L'utilizzo di ClusterControl offre uno strumento di utilità completo in cui è anche possibile controllare le query in esecuzione per determinare i processi (query) che possono influire sull'utilizzo elevato della memoria. Vedi sotto per un esempio,

Visualizzare le variabili di stato di MySQL è abbastanza facile,

Puoi anche andare su Performance -> Innodb Status per rivelare il stato attuale di InnoDB dei nodi del database. Inoltre, in ClusterControl viene rilevato un incidente, cercherà di raccogliere l'incidente e mostra la cronologia come un rapporto che fornisce lo stato di InnoDB, come mostrato nel nostro precedente blog su MySQL Freeze Frame.

Riepilogo

La risoluzione dei problemi e la diagnosi del database MySQL quando si sospetta un utilizzo elevato della memoria non è così difficile fintanto che si conoscono le procedure e gli strumenti da utilizzare. L'utilizzo dello strumento giusto offre maggiore flessibilità e produttività più rapida per fornire soluzioni o soluzioni con possibilità di risultati maggiori.