Een van de belangrijkste factoren van een performante MySQL-databaseserver is een goede geheugentoewijzing en -gebruik, vooral wanneer deze in een productieomgeving wordt uitgevoerd. Maar hoe kunt u bepalen of het MySQL-gebruik is geoptimaliseerd? Is het redelijk om een hoog geheugengebruik te hebben of moet het worden afgesteld? Wat als ik een geheugenlek tegenkom?
Laten we deze onderwerpen bespreken en laten zien wat u in MySQL kunt controleren om sporen van hoog geheugengebruik vast te stellen.
Geheugentoewijzing in MySQL
Voordat we ingaan op de specifieke titel van het onderwerp, zal ik een korte informatie geven over hoe MySQL geheugen gebruikt. Geheugen speelt een belangrijke bron voor snelheid en efficiëntie bij het afhandelen van gelijktijdige transacties en het uitvoeren van grote query's. Elke thread in MySQL vereist geheugen dat wordt gebruikt om clientverbindingen te beheren, en deze threads delen hetzelfde basisgeheugen. Variabelen zoals thread_stack (stack voor threads), net_buffer_length (voor verbindingsbuffer en resultaatbuffer), of met max_allowed_packet waarbij verbinding en resultaat dynamisch worden vergroot tot deze waarde wanneer nodig, zijn variabelen die wel van invloed zijn op geheugengebruik. Wanneer een thread niet langer nodig is, wordt het toegewezen geheugen vrijgegeven en teruggegeven aan het systeem, tenzij de thread teruggaat naar de threadcache. In dat geval blijft het geheugen toegewezen. Query-joins, querycaches, sorteren, tabelcache, tabeldefinities vereisen wel geheugen in MySQL, maar deze worden toegeschreven aan systeemvariabelen die u kunt configureren en instellen.
In de meeste gevallen zijn de geheugenspecifieke variabelen die zijn ingesteld voor een configuratie gericht op een op opslag gebaseerde specifieke configuratie zoals MyISAM of InnoDB. Wanneer een mysqld-instantie binnen het hostsysteem verschijnt, wijst MySQL buffers en caches toe om de prestaties van databasebewerkingen te verbeteren op basis van de ingestelde waarden die zijn ingesteld op een specifieke configuratie. De meest voorkomende variabelen die elke DBA in InnoDB instelt, zijn bijvoorbeeld variabelen innodb_buffer_pool_size en innodb_buffer_pool_instances die beide gerelateerd zijn aan bufferpoolgeheugentoewijzing die gegevens in de cache voor InnoDB-tabellen bevat. Het is wenselijk als je veel geheugen hebt en grote transacties verwacht door innodb_buffer_pool_instances in te stellen om de gelijktijdigheid te verbeteren door de bufferpool te verdelen in meerdere bufferpoolinstanties.
Terwijl je voor MyISAM te maken hebt met key_buffer_size om de hoeveelheid geheugen te verwerken die de sleutelbuffer aankan. MyISAM wijst ook een buffer toe voor elke gelijktijdige thread die een tabelstructuur, kolomstructuren voor elke kolom en een buffer van grootte 3 * N bevat (waarbij N de maximale rijlengte is, BLOB-kolommen niet meegerekend). MyISAM houdt ook één extra rijbuffer bij voor intern gebruik.
MySQL wijst ook geheugen toe aan tijdelijke tabellen, tenzij het te groot wordt (bepaald door tmp_table_size en max_heap_table_size). Als u MEMORY-tabellen gebruikt en de variabele max_heap_table_size is erg hoog ingesteld, kan dit ook veel geheugen in beslag nemen, aangezien de systeemvariabele max_heap_table_size bepaalt hoe groot een tabel kan groeien, en er is geen conversie naar indeling op schijf.
MySQL heeft ook een prestatieschema dat een functie is voor het bewaken van MySQL-activiteiten op een laag niveau. Zodra dit is ingeschakeld, wijst het dynamisch geheugen stapsgewijs toe, waarbij het geheugengebruik wordt geschaald naar de werkelijke serverbelasting, in plaats van het vereiste geheugen toe te wijzen tijdens het opstarten van de server. Nadat geheugen is toegewezen, wordt het pas vrijgemaakt als de server opnieuw wordt opgestart.
MySQL kan ook worden geconfigureerd om grote geheugengebieden toe te wijzen aan de bufferpool als Linux wordt gebruikt en als de kernel is ingeschakeld voor ondersteuning van grote pagina's, d.w.z. met behulp van HugePages.
Wat u moet controleren als het MySQL-geheugen vol is
Controleer lopende zoekopdrachten
Het is heel gebruikelijk dat MySQL DBA's eerst de basis raken van wat er aan de hand is met de draaiende MySQL-server. De meest elementaire procedures zijn het controleren van de proceslijst, het controleren van de serverstatus en het controleren van de status van de opslagengine. Om deze dingen te doen, hoeft u in principe alleen de reeks query's uit te voeren door u aan te melden bij MySQL. Zie hieronder:
Om de lopende zoekopdrachten te bekijken,
mysql> SHOW [FULL] PROCESSLIST;
Als u de huidige proceslijst bekijkt, worden query's weergegeven die actief zijn of zelfs inactieve of slapende processen. Het is erg belangrijk en een belangrijke routine om een overzicht te hebben van de query's die worden uitgevoerd. Zoals opgemerkt over de manier waarop MySQL geheugen toewijst, gebruiken bij het uitvoeren van query's geheugentoewijzing en kunnen ze drastische prestatieproblemen veroorzaken als ze niet worden gecontroleerd.
Bekijk de statusvariabelen van de MySQL-server,
mysql> SHOW SERVER STATUS\G
of filter specifieke variabelen zoals
mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);
De statusvariabelen van MySQL dienen als uw statistische informatie om metrische gegevens te verzamelen om te bepalen hoe uw MySQL presteert door de tellers te observeren die door de statuswaarden worden gegeven. Er zijn hier bepaalde waarden die u een blik geven die van invloed is op het geheugengebruik. Bijvoorbeeld het controleren van het aantal threads, het aantal tabelcaches of het gebruik van de bufferpool,
...
| 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 |
Bekijk de monitorstatus van de engine, bijvoorbeeld InnoDB-status
mysql> SHOW ENGINE INNODB STATUS\G
De InnoDB-status onthult ook de huidige status van transacties die de opslagengine verwerkt. Het geeft u de heapgrootte van een transactie, adaptieve hash-indexen die het buffergebruik onthullen, of toont u de innodb-bufferpoolinformatie, net zoals in het onderstaande voorbeeld:
---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]
…
Nog iets om toe te voegen, je kunt ook prestatieschema en sys-schema gebruiken voor het bewaken van het geheugenverbruik en het gebruik door je MySQL-server. Standaard zijn de meeste instrumenten standaard uitgeschakeld, dus er zijn handmatige dingen te doen om dit te gebruiken.
Controleren op Swappiness
Hoe dan ook, het is waarschijnlijk dat MySQL zijn geheugen uitwisselt naar schijf. Dit is vaak een veel voorkomende situatie, vooral wanneer de MySQL-server en de onderliggende hardware niet optimaal parallel aan de verwachte vereisten zijn ingesteld. Er zijn bepaalde gevallen waarin niet is geanticipeerd op de vraag naar verkeer. Het geheugen kan in toenemende mate toenemen, vooral als er slechte query's worden uitgevoerd, waardoor veel geheugenruimte wordt verbruikt of gebruikt, waardoor de prestaties afnemen, omdat gegevens op schijf worden verzameld in plaats van in de buffer. Om te controleren op swappiness, voer je het freemem-commando of vmstat uit zoals hieronder,
[[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
Je kunt ook controleren met procfs en informatie verzamelen, zoals naar /proc/vmstat of /proc/meminfo gaan.
Perf, gdb en Valgrind gebruiken met Massif
Het gebruik van tools zoals perf, gdb en valgrind helpt je om je te verdiepen in een meer geavanceerde methode om MySQL-geheugengebruik te bepalen. Er zijn tijden dat een interessant resultaat een mysterie wordt van het oplossen van geheugengebruik dat leidt tot je verbijstering in MySQL. Dit leidt tot meer scepsis en het gebruik van deze tools helpt je te onderzoeken hoe MySQL geheugen gebruikt, van het toewijzen ervan tot het gebruiken ervan voor het verwerken van transacties of processen. Dit is bijvoorbeeld handig als u merkt dat MySQL zich abnormaal gedraagt, wat een slechte configuratie kan veroorzaken of kan leiden tot geheugenlekken.
Het gebruik van perf in MySQL geeft bijvoorbeeld meer informatie in een rapport op systeemniveau:
[[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
….
Aangezien dit een speciaal onderwerp kan zijn om je in te verdiepen, raden we je aan deze echt goede externe blogs te bekijken als je referenties, Basisprincipes voor MySQL-profilering te leren, MySQL-schaalproblemen te vinden met behulp van perf, of te leren hoe je debug met behulp van valgrind met massif.
Efficiënte manier om MySQL-geheugengebruik te controleren
Het gebruik van ClusterControl verlicht alle gedoe routines zoals het doornemen van uw runbooks of zelfs het maken van uw eigen playbooks die rapporten voor u zouden opleveren. In ClusterControl heb je Dashboards (met SCUMM) waar je snel een overzicht hebt van je MySQL node(s). Als u bijvoorbeeld het MySQL General-dashboard bekijkt,
u kunt bepalen hoe de MySQL-node presteert,
Je ziet dat de bovenstaande afbeeldingen variabelen onthullen die van invloed zijn op het geheugengebruik van MySQL. U kunt controleren hoe de statistieken voor sorteercaches, tijdelijke tabellen, verbonden threads, querycache of opslagengines in de nodb-bufferpool of de sleutelbuffer van MyISAM.
Het gebruik van ClusterControl biedt u een alles-in-één hulpprogramma waarmee u ook de lopende query's kunt controleren om de processen (query's) te bepalen die van invloed kunnen zijn op een hoog geheugengebruik. Zie hieronder voor een voorbeeld,
Het bekijken van de statusvariabelen van MySQL is heel eenvoudig,
Je kunt zelfs naar Prestaties -> Innodb-status gaan om de huidige InnoDB-status van uw databaseknooppunten. Ook wordt in ClusterControl een incident gedetecteerd, het zal proberen het incident te verzamelen en de geschiedenis te tonen als een rapport dat u de InnoDB-status geeft, zoals weergegeven in onze vorige blog over MySQL Freeze Frame.
Samenvatting
Het oplossen van problemen en het diagnosticeren van uw MySQL-database bij het vermoeden van een hoog geheugengebruik is niet zo moeilijk, zolang u de procedures en hulpmiddelen kent die u moet gebruiken. Het gebruik van de juiste tool biedt u meer flexibiliteit en snellere productiviteit om fixes of oplossingen te leveren met kans op meer resultaat.