MySQL is uitgebreid en heeft veel gebieden om te optimaliseren en aan te passen voor de gewenste prestaties. Sommige wijzigingen kunnen dynamisch worden uitgevoerd, voor andere moet de server opnieuw worden opgestart. Het is vrij gebruikelijk om een MySQL-installatie te vinden met een standaardconfiguratie, hoewel de laatste mogelijk niet per se geschikt is vanwege uw werkbelasting en configuratie.
Dit zijn de belangrijkste gebieden in MySQL die ik heb overgenomen van verschillende deskundige bronnen in de MySQL-wereld, evenals onze eigen ervaringen hier bij Verschillend. Deze blog zou dienen als je spiekbriefje om de prestaties af te stemmen en je MySQL weer geweldig te maken :-)
Laten we hier eens naar kijken door de belangrijkste gebieden in MySQL te schetsen.
Systeemvariabelen
MySQL heeft veel variabelen die u kunt wijzigen. Sommige variabelen zijn dynamisch, wat betekent dat ze kunnen worden ingesteld met het SET-statement. Andere vereisen een herstart van de server, nadat ze zijn ingesteld in het configuratiebestand (bijv. /etc/my.cnf, etc/mysql/my.cnf). Ik zal echter de algemene dingen bespreken die vrij gebruikelijk zijn om af te stemmen om de server te optimaliseren.
sort_buffer_size
Deze variabele bepaalt hoe groot uw filesort-buffer is, wat betekent dat wanneer een query de rijen moet sorteren, de waarde van deze variabele wordt gebruikt om de grootte te beperken die moet worden toegewezen. Houd er rekening mee dat deze variabele per query is die wordt verwerkt (of per verbinding), wat betekent dat het geheugen hongerig zou zijn als u dit hoger instelt en als u meerdere verbindingen heeft waarvoor u uw rijen moet sorteren. U kunt uw behoeften echter controleren door de algemene statusvariabele Sort_merge_passes te controleren. Als deze waarde groot is, kunt u overwegen de waarde van de systeemvariabele sort_buffer_size te verhogen. Ga anders naar de gematigde limiet die je nodig hebt. Als u dit te laag instelt of als u grote query's moet verwerken, kan het effect van het sorteren van uw rijen langzamer zijn dan verwacht, omdat gegevens willekeurig worden opgehaald tijdens schijfduiken. Dit kan prestatievermindering veroorzaken. Het is echter het beste om uw vragen op te lossen. Anders, als uw toepassing is ontworpen om grote query's op te halen en moet worden gesorteerd, is het efficiënt om hulpprogramma's te gebruiken die querycaching afhandelen, zoals Redis. Standaard is in MySQL 8.0 de huidige waardeset 256 KiB. Stel dit alleen dienovereenkomstig in als u zoekopdrachten hebt die veel worden gebruikt of sorteringen aanroepen.
read_buffer_size
MySQL-documentatie vermeldt dat voor elk verzoek dat een sequentiële scan van een tabel uitvoert, het een leesbuffer toewijst. De systeemvariabele read_buffer_size bepaalt de buffergrootte. Het is ook handig voor MyISAM, maar deze variabele is ook van invloed op alle storage-engines. Voor MEMORY-tabellen wordt het gebruikt om de grootte van het geheugenblok te bepalen.
In principe wijst elke thread die een sequentiële scan uitvoert voor een MyISAM-tabel een buffer van deze grootte (in bytes) toe voor elke tabel die wordt gescand. Het is ook van toepassing op alle opslag-engines (inclusief InnoDB), dus het is handig voor query's die rijen sorteren met ORDER BY en de indexen in een tijdelijk bestand cachen. Als u veel opeenvolgende scans uitvoert, bulksgewijs invoegt in partitietabellen, resultaten van geneste query's in de cache opslaat, kunt u overwegen de waarde ervan te verhogen. De waarde van deze variabele moet een veelvoud van 4 KB zijn. Als het is ingesteld op een waarde die geen veelvoud van 4 KB is, wordt de waarde naar beneden afgerond op het dichtstbijzijnde veelvoud van 4 KB. Houd er rekening mee dat het instellen van een hogere waarde een groot deel van het geheugen van uw server in beslag neemt. Ik raad aan om dit niet te gebruiken zonder de juiste benchmarking en monitoring van uw omgeving.
read_rnd_buffer_size
Deze variabele behandelt het lezen van rijen uit een MyISAM-tabel in gesorteerde volgorde na een sleutelsortering, de rijen worden door deze buffer gelezen om het zoeken naar schijven te voorkomen. De documentatie zegt dat bij het lezen van rijen in een willekeurige volgorde of van een MyISAM-tabel in gesorteerde volgorde na een sleutelsorteeroperatie, de rijen door deze buffer worden gelezen (en bepaald door deze buffergrootte) om het zoeken naar schijven te voorkomen. Het instellen van de variabele op een hoge waarde kan de ORDER BY-prestaties aanzienlijk verbeteren. Dit is echter een buffer die aan elke client wordt toegewezen, dus u moet de globale variabele niet op een hoge waarde instellen. Wijzig in plaats daarvan de sessievariabele alleen vanuit die clients die grote query's moeten uitvoeren. Houd er echter rekening mee dat dit niet van toepassing is op MariaDB, vooral niet wanneer u gebruikmaakt van MRR. MariaDB gebruikt mrr_buffer_size terwijl MySQL read_buffer_size read_rnd_buffer_size gebruikt.
join_buffer_size
Standaard is de waarde 256K. De minimumgrootte van de buffer die wordt gebruikt voor gewone indexscans, bereikindexscans en joins die geen indexen gebruiken en dus volledige tabelscans uitvoeren. Wordt ook gebruikt door de BKA-optimalisatie (die standaard is uitgeschakeld). Verhoog de waarde om snellere volledige joins te krijgen wanneer het toevoegen van indexen niet mogelijk is. Voorbehoud kan echter geheugenproblemen zijn als u dit te hoog instelt. Onthoud dat er één join-buffer wordt toegewezen voor elke volledige join tussen twee tabellen. Voor een complexe join tussen verschillende tabellen waarvoor geen indexen worden gebruikt, kunnen meerdere joinbuffers nodig zijn. Het beste is om wereldwijd laag te houden en hoog in te stellen in sessies (met behulp van de syntaxis SET SESSION) waarvoor grote volledige joins nodig zijn. Op 64-bits platforms kapt Windows waarden boven 4GB af tot 4GB-1 met een waarschuwing.
max_heap_table_size
Dit is de maximale grootte in bytes voor door de gebruiker gemaakte MEMORY-tabellen die mogen groeien. Dit is handig wanneer uw toepassing te maken heeft met MEMORY storage engine-tabellen. Het instellen van de variabele terwijl de server actief is, heeft geen effect op bestaande tabellen, tenzij ze opnieuw worden gemaakt of gewijzigd. De kleinste van max_heap_table_size en tmp_table_size beperkt ook interne tabellen in het geheugen. Deze variabele is ook in combinatie met tmp_table_size om de grootte van interne tabellen in het geheugen te beperken (dit verschilt van de tabellen die expliciet zijn gemaakt als Engine=MEMORY omdat deze alleen max_heap_table_size van toepassing is), waarbij de kleinste tussen de twee wordt toegepast.
tmp_table_size
De grootste grootte voor tijdelijke tabellen in het geheugen (niet MEMORY-tabellen), hoewel als max_heap_table_size kleiner is, de ondergrens van toepassing is. Als een tijdelijke tabel in het geheugen de limiet overschrijdt, converteert MySQL deze automatisch naar een tijdelijke tabel op schijf. Verhoog de waarde van tmp_table_size (en max_heap_table_size indien nodig) als u veel geavanceerde GROUP BY-query's uitvoert en u over veel beschikbare geheugenruimte beschikt. U kunt het aantal gemaakte interne tijdelijke tabellen op schijf vergelijken met het totale aantal interne tijdelijke tabellen dat is gemaakt door de waarden van de variabelen Created_tmp_disk_tables en Created_tmp_tables te vergelijken. In ClusterControl kunt u dit volgen via Dashboard -> grafiek Tijdelijke objecten.
table_open_cache
U kunt de waarde van deze variabele verhogen als u een groot aantal tabellen in uw gegevensset hebt die vaak worden geopend. Het wordt toegepast voor alle threads, dus per verbindingsbasis. De waarde geeft het maximum aantal tabellen aan dat de server open kan houden in een tabelcache-instantie. Hoewel het verhogen van deze waarde het aantal bestandsdescriptors dat mysqld nodig heeft, vergroot, kunt u dus net zo goed overwegen uw open_files_limit-waarde te controleren of te controleren hoe groot de SOFT- en HARD-limiet is die is ingesteld in uw *nix-besturingssysteem. U kunt dit controleren of u de tabelcache moet vergroten door de statusvariabele Opened_tables te controleren. Als de waarde van Opened_tables groot is en u FLUSH TABLES niet vaak gebruikt (waardoor alleen alle tabellen moeten worden gesloten en opnieuw moeten worden geopend), moet u de waarde van de variabele table_open_cache verhogen. Als je een kleine waarde hebt voor table_open_cache, en een groot aantal tabellen wordt vaak gebruikt, kan dit de prestaties van je server beïnvloeden. Als u veel vermeldingen in de MySQL-proceslijst ziet met de status "Tabellen openen" of "Tabellen sluiten", dan is het tijd om de waarde van deze variabele aan te passen, maar let op het eerder genoemde voorbehoud. In ClusterControl kunt u dit controleren onder Dashboards -> Table Open Cache Status of Dashboards -> Open Tables. Je kunt het hier bekijken voor meer informatie.
table_open_cache_instances
Het instellen van deze variabele zou de schaalbaarheid helpen verbeteren, en natuurlijk de prestaties, wat de twist tussen sessies zou verminderen. De waarde die u hier instelt, beperkt het aantal cache-instanties van geopende tabellen. De cache met open tabellen kan worden gepartitioneerd in verschillende kleinere cache-instanties van de grootte table_open_cache/table_open_cache_instances. Een sessie hoeft slechts één instantie te vergrendelen om er toegang toe te krijgen voor DML-instructies. Dit verdeelt cachetoegang tussen instanties, waardoor hogere prestaties mogelijk zijn voor bewerkingen die de cache gebruiken wanneer er veel sessies zijn die toegang hebben tot tabellen. (DDL-instructies vereisen nog steeds een vergrendeling van de hele cache, maar dergelijke instructies komen veel minder vaak voor dan DML-instructies.) Een waarde van 8 of 16 wordt aanbevolen op systemen die routinematig 16 of meer cores gebruiken.
table_definition_cache
Cachetabeldefinities, d.w.z. dit is waar de CREATE TABLE in de cache wordt opgeslagen om het openen van tabellen te versnellen en slechts één invoer per tabel. Het zou redelijk zijn om de waarde te verhogen als u een groot aantal tabellen heeft. De tabeldefinitiecache neemt minder ruimte in beslag en gebruikt geen bestandsdescriptors, in tegenstelling tot de normale tabelcache. Peter Zaitsev van Percona stelt voor dat je de instelling van de onderstaande formule kunt proberen,
The number of user-defined tables + 10% unless 50K+ tables
Houd er echter rekening mee dat de standaardwaarde is gebaseerd op de volgende formule met een limiet van 2000.
MIN(400 + table_open_cache / 2, 2000)
Dus als u een groter aantal tabellen heeft in vergelijking met de standaard, dan is het redelijk dat u de waarde ervan verhoogt. Houd er rekening mee dat bij InnoDB deze variabele wordt gebruikt als een zachte limiet van het aantal open-tabelinstanties voor de datadictionary-cache. Het zal het LRU-mechanisme toepassen zodra het de huidige waarde van deze variabele overschrijdt. De limiet helpt situaties aan te pakken waarin aanzienlijke hoeveelheden geheugen zouden worden gebruikt voor het cachen van zelden gebruikte tabelinstanties tot de volgende herstart van de server. Daarom worden bovenliggende en onderliggende tabelinstanties met externe-sleutelrelaties niet op de LRU-lijst geplaatst en kunnen ze een hogere limiet opleggen dan de limiet die is gedefinieerd door table_definition_cache en zijn ze niet onderhevig aan verwijdering in het geheugen tijdens LRU. Bovendien definieert de table_definition_cache een zachte limiet voor het aantal InnoDB-bestand-per-tabel-tabelruimten dat tegelijkertijd open kan zijn, wat ook wordt beheerd door innodb_open_files en in feite wordt de hoogste instelling tussen deze variabelen gebruikt, als beide zijn ingesteld . Als geen van beide variabelen is ingesteld, wordt table_definition_cache, die een hogere standaardwaarde heeft, gebruikt. Als het aantal geopende tablespace-bestandshandles de limiet overschrijdt die is gedefinieerd door table_definition_cache of innodb_open_files, doorzoekt het LRU-mechanisme de LRU-lijst van het tablespace-bestand op bestanden die volledig zijn leeggemaakt en die momenteel niet worden uitgebreid. Dit proces wordt uitgevoerd telkens wanneer een nieuwe tabelruimte wordt geopend. Als er geen "inactieve" tablespaces zijn, worden er geen tablespace-bestanden gesloten. Houd hier dus rekening mee.
max_allowed_packet
Dit is de maximale grootte per verbinding van een geretourneerde SQL-query of rij. De waarde is voor het laatst verhoogd in MySQL 5.6. In MySQL 8.0 (tenminste op 8.0.3) is de huidige standaardwaarde 64 MiB. U kunt overwegen dit aan te passen als u grote BLOB-rijen heeft die moeten worden uitgetrokken (of gelezen), anders kunt u deze standaardinstellingen op 8.0 laten staan, maar in oudere versies is de standaard 4 MiB, dus u kunt daar voor zorgen als u ER_NET_PACKET_TOO_LARGE fout tegenkomen. Het grootst mogelijke pakket dat van of naar een MySQL 8.0-server of -client kan worden verzonden, is 1 GB.
skip_name_resolve MySQL-server verwerkt inkomende verbindingen door hostnaamomzetting. Standaard schakelt MySQL geen hostnaamomzetting uit, wat betekent dat het DNS-lookups zal uitvoeren, en als DNS traag is, kan dit de oorzaak zijn van vreselijke prestaties van uw database. Overweeg om dit in te schakelen als u geen DNS-omzetting nodig hebt en profiteer van het verbeteren van uw MySQL-prestaties wanneer deze DNS-lookup is uitgeschakeld. Houd er rekening mee dat deze variabele niet dynamisch is, daarom is een herstart van de server vereist als u dit instelt in uw MySQL-configuratiebestand. U kunt optioneel mysqld-daemon starten, waarbij u de optie --skip-name-resolve doorgeeft om dit in te schakelen.max_connections
Dit is het aantal toegestane verbindingen voor uw MySQL-server. Als u de fout in MySQL 'Te veel verbindingen' ontdekt, kunt u overwegen deze hoger in te stellen. Standaard is de waarde van 151 niet genoeg, vooral niet in een productiedatabase, en aangezien u meer bronnen van de server hebt (verspil uw serverbronnen niet, vooral niet als het een speciale MySQL-server is). U moet echter voldoende bestandsdescriptors hebben, anders raakt u ze kwijt. Overweeg in dat geval om uw SOFT- en HARD-limiet van uw *nix-besturingssystemen aan te passen en een hogere waarde van open_files_limit in MySQL in te stellen (5000 is de standaardlimiet). Houd er rekening mee dat het zeer vaak voorkomt dat de toepassing de verbindingen met de database niet correct sluit, en het instellen van een hoge max_connections kan leiden tot een niet-reagerende of hoge belasting van uw server. Het gebruik van een verbindingspool op applicatieniveau kan het probleem hier helpen oplossen.
thread_cache_size
Dit is de cache om overmatige creatie van threads te voorkomen. Wanneer een client de verbinding verbreekt, worden de threads van de client in de cache geplaatst als er minder dan thread_cache_size threads zijn. Aan verzoeken om threads wordt voldaan door indien mogelijk threads uit de cache te hergebruiken, en alleen wanneer de cache leeg is, wordt een nieuwe thread gemaakt. Deze variabele kan worden verhoogd om de prestaties te verbeteren als u veel nieuwe verbindingen hebt. Normaal gesproken levert dit geen noemenswaardige prestatieverbetering op als je een goede thread-implementatie hebt. Als uw server echter honderden verbindingen per seconde ziet, moet u thread_cache_size normaal gesproken hoog genoeg instellen zodat de meeste nieuwe verbindingen gecachte threads gebruiken. Door het verschil tussen de statusvariabelen Connections en Threads_created te onderzoeken, kunt u zien hoe efficiënt de threadcache is. Met de formule die in de documentatie wordt vermeld, is 8 + (max_connections / 100) goed genoeg.
query_cache_size
Voor sommige instellingen is deze variabele hun ergste vijand. Voor sommige systemen die een hoge belasting ervaren en bezig zijn met hoge uitlezingen, zal deze variabele u vastlopen. Er zijn benchmarks geweest die goed zijn getest door bijvoorbeeld Percona. Deze variabele moet ook worden ingesteld op 0 samen met query_cache_type =0 om deze uit te schakelen. Het goede nieuws in MySQL 8.0 is dat het MySQL-team dit niet meer ondersteunt, omdat deze variabele echt prestatieproblemen kan veroorzaken. Ik moet het met hun blog eens zijn dat het onwaarschijnlijk is dat het de voorspelbaarheid van de prestaties zal verbeteren. Als u zich bezighoudt met het cachen van query's, raad ik u aan Redis of ProxySQL te gebruiken.
Opslagengine - InnoDB
InnoDB is een ACID-compatibele opslagengine met verschillende functies, samen met ondersteuning voor externe sleutels (Declarative Referential Integrity). Dit heeft hier veel te zeggen, maar bepaalde variabelen waarmee u rekening moet houden bij het afstemmen:
innodb_buffer_pool_size
Deze variabele fungeert als een sleutelbuffer van MyISAM, maar heeft veel te bieden. Aangezien InnoDB sterk afhankelijk is van de bufferpool, kunt u overwegen deze waarde in te stellen op 70%-80% van het geheugen van uw server. Het is ook gunstig dat u een grotere geheugenruimte heeft dan uw dataset en een hogere waarde voor uw bufferpool instelt, maar niet te veel. In ClusterControl kan dit worden gecontroleerd met behulp van onze Dashboards -> InnoDB Metrics -> InnoDB Buffer Pool Pages-grafiek. U kunt dit ook controleren met SHOW GLOBAL STATUS met behulp van de variabelen Innodb_buffer_pool_pages*.
innodb_buffer_pool_instances
Voor uw gelijktijdigheidswerkbelasting kan het instellen van deze variabele de gelijktijdigheid verbeteren en de strijd verminderen als verschillende threads van lezen/schrijven naar gecachte pagina's. Minimum innodb_buffer_pool_instances moet tussen 1 (minimum) &64 (maximum) liggen. Elke pagina die is opgeslagen in of gelezen uit de bufferpool wordt willekeurig toegewezen aan een van de bufferpoolinstanties met behulp van een hash-functie. Elke bufferpool beheert zijn eigen vrije lijsten, flushlijsten, LRU's en alle andere gegevensstructuren die zijn verbonden met een bufferpool en wordt beschermd door zijn eigen bufferpoolmutex. Houd er rekening mee dat deze optie alleen van kracht wordt wanneer innodb_buffer_pool_size>=1GiB en de grootte ervan is verdeeld over de bufferpoolinstanties.
innodb_log_file_size
Deze variabele is het logbestand in een loggroep. De gecombineerde grootte van logbestanden (innodb_log_file_size * innodb_log_files_in_group) mag een maximale waarde van iets minder dan 512 GB niet overschrijden. Volgens Vadim is een groter logbestand beter voor de prestaties, maar het heeft een (belangrijk) nadeel waar je je zorgen over moet maken:de hersteltijd na een crash. U moet de hersteltijd in het zeldzame geval van een crashherstel afwegen tegen het maximaliseren van de doorvoer tijdens piekactiviteiten. Deze beperking kan zich vertalen in een 20x langer crashherstelproces!
Om het uit te werken, zou een grotere waarde goed zijn voor InnoDB-transactielogboeken en cruciaal zijn voor goede en stabiele schrijfprestaties. Hoe groter de waarde, hoe minder checkpoint flush-activiteit nodig is in de bufferpool, waardoor schijf-I/O wordt bespaard. Het herstelproces is echter vrij traag zodra uw database abnormaal is afgesloten (crash of dood, OOM of per ongeluk). Idealiter zou je 1-2GiB in productie kunnen hebben maar dit kan je natuurlijk aanpassen. Het benchmarken van deze veranderingen kan een groot voordeel zijn om te zien hoe het presteert, vooral na een crash.
innodb_log_buffer_size
Om schijf-I/O op te slaan, schrijft InnoDB's de wijzigingsgegevens naar de logbuffer en gebruikt het de waarde van innodb_log_buffer_size met een standaardwaarde van 8MiB. Dit is vooral gunstig voor grote transacties, omdat het niet nodig is om het logboek met wijzigingen naar schijf te schrijven voordat de transactie wordt vastgelegd. Als uw schrijfverkeer te hoog is (invoegen, verwijderen, bijwerken), bespaart u schijf-I/O door de buffer groter te maken.
innodb_flush_log_at_trx_commit
Wanneer innodb_flush_log_at_trx_commit is ingesteld op 1 wordt de logbuffer leeggemaakt bij elke transactie die wordt vastgelegd in het logbestand op schijf en biedt maximale gegevensintegriteit, maar het heeft ook invloed op de prestaties. Als u dit instelt op 2, betekent dit dat de logbuffer bij elke transactie wordt weggespoeld naar de cache van het besturingssysteem. De implicatie van 2 is optimaal en verbetert de prestaties als u uw ACID-vereisten kunt versoepelen en het zich kunt veroorloven om transacties voor de laatste seconde of twee te verliezen in het geval van OS-crashes.
innodb_thread_concurrency
Met verbeteringen aan de InnoDB-engine wordt aanbevolen om de engine de gelijktijdigheid te laten regelen door deze op de standaardwaarde te houden (die nul is). Als u gelijktijdigheidsproblemen ziet, kunt u deze variabele afstemmen. Een aanbevolen waarde is 2 keer het aantal CPU's plus het aantal schijven. Het is een dynamische variabele, wat betekent dat het kan worden ingesteld zonder de MySQL-server opnieuw te hoeven starten.
innodb_flush_methode
Deze variabele moet echter worden uitgeprobeerd en getest op welke hardware het beste bij u past. Als u een RAID gebruikt met cache met batterijvoeding, helpt DIRECT_IO de I/O-druk te verlichten. Directe I/O wordt niet in de cache opgeslagen, dus dubbele buffering met bufferpool en bestandssysteemcache wordt vermeden. Als uw schijf is opgeslagen in SAN, is O_DSYNC mogelijk sneller voor een leeszware werklast met voornamelijk SELECT-instructies.
innodb_file_per_table
innodb_file_per_table is standaard AAN vanaf MySQL 5.6. Dit wordt meestal aanbevolen omdat het een enorme gedeelde tabelruimte vermijdt en omdat het je in staat stelt ruimte terug te winnen wanneer je een tabel laat vallen of afkapt. Aparte tablespace voordelen ook voor Xtrabackup gedeeltelijk back-upschema.
innodb_stats_on_metadata
Dit probeert het percentage vuile pagina's onder controle te houden, en vóór de Innodb-plug-in was dit echt de enige manier om het doorspoelen van vuile buffers af te stemmen. Ik heb echter servers gezien met 3% vuile buffers en ze bereiken hun maximale controlepuntleeftijd. De manier waarop dit het spoelen van de vuile buffer verhoogt, schaalt ook niet goed op subsystemen met een hoog io-niveau, het verdubbelt in feite gewoon het spoelen van de vuile buffer per seconde wanneer het % vuile pagina's dit aantal overschrijdt.
innodb_io_capacity
Deze instelling, ondanks al onze grote hoop dat het Innodb in staat zou stellen om onze IO beter te gebruiken bij alle bewerkingen, regelt eenvoudig de hoeveelheid vuile pagina's die per seconde worden doorgespoeld (en andere achtergrondtaken zoals vooruit lezen). Maak deze groter, je spoelt meer per seconde. Dit past zich niet aan, het doet gewoon zoveel iops per seconde als er vuile buffers zijn om door te spoelen. Het zal elke optimalisatie van IO-consolidatie effectief elimineren als u een voldoende lage schrijfbelasting heeft (dat wil zeggen, vuile pagina's worden bijna onmiddellijk gewist, in dit geval zijn we misschien beter af zonder een transactielogboek). Het kan ook het lezen en schrijven van gegevens naar het transactielogboek snel uithongeren als u dit te hoog instelt.
innodb_write_io_threads
Bepaalt hoeveel threads er naar de schijf worden geschreven. Ik weet niet zeker waarom dit nog steeds handig is als je Linux native AIO kunt gebruiken. Deze kunnen ook onbruikbaar worden gemaakt door bestandssystemen die parallel schrijven naar hetzelfde bestand door meer dan één thread niet toestaan (vooral als je relatief weinig tabellen hebt en/of de globale tablespaces gebruikt)
innodb_adaptive_flushing
Geeft aan of de snelheid waarmee vuile pagina's in de InnoDB-bufferpool worden gewist, dynamisch moet worden aangepast op basis van de werkbelasting. Het dynamisch aanpassen van de spoelsnelheid is bedoeld om bursts van I/O-activiteit te voorkomen. Meestal is dit standaard ingeschakeld. Deze variabele probeert, indien ingeschakeld, slimmer te zijn in het agressiever doorspoelen op basis van het aantal vuile pagina's en de snelheid van de groei van het transactielogboek.
innodb_dedicated_server
Deze variabele is nieuw in MySQL 8.0 die wereldwijd wordt toegepast en vereist een MySQL-herstart omdat het geen dynamische variabele is. In de documentatie staat echter dat deze variabele alleen moet worden ingeschakeld als uw MySQL op een speciale server draait. Schakel dit anders niet in op een gedeelde host of deel systeembronnen met andere toepassingen. Wanneer dit is ingeschakeld, zal InnoDB een automatische configuratie uitvoeren voor de hoeveelheid geheugen die is gedetecteerd voor de variabelen innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_method. Het nadeel is alleen dat u niet de haalbaarheid kunt hebben om uw gewenste waarden toe te passen op de genoemde gedetecteerde variabelen.
MijnISAM
key_buffer_size
InnoDB is nu de standaard opslagengine van MySQL, de standaardwaarde voor key_buffer_size kan waarschijnlijk worden verlaagd, tenzij u MyISAM productief gebruikt als onderdeel van uw toepassing (maar wie gebruikt MyISAM nu in productie?). Ik zou hier aanraden om bij het begin misschien 1% RAM of 256 MiB in te stellen als je meer geheugen hebt en het resterende geheugen te besteden aan je OS-cache en InnoDB-bufferpool.
Andere bepalingen voor prestaties
slow_query_log
Natuurlijk helpt deze variabele niet om uw MySQL-server een boost te geven. Deze variabele kan u echter helpen bij het analyseren van traag presterende query's. De waarde kan worden ingesteld op 0 of UIT om logboekregistratie uit te schakelen. Zet het op 1 of AAN om dit in te schakelen. De standaardwaarde hangt af van het feit of de optie --slow_query_log is opgegeven. De bestemming voor loguitvoer wordt bepaald door de systeemvariabele log_output; als die waarde NONE is, worden er geen logboekvermeldingen geschreven, zelfs niet als het logboek is ingeschakeld. U kunt de bestandsnaam of bestemming van het querylogbestand instellen door de variabele slow_query_log_file in te stellen.
long_query_time
Als een query langer duurt dan dit aantal seconden, verhoogt de server de statusvariabele Slow_queries. Als het logbestand voor langzame query's is ingeschakeld, wordt de query vastgelegd in het logbestand voor langzame query's. Deze waarde wordt in realtime gemeten, niet in CPU-tijd, dus een query die onder de drempel valt op een licht belast systeem kan boven de drempel liggen op een zwaar belast systeem. De minimum- en standaardwaarden van long_query_time zijn respectievelijk 0 en 10. Houd er ook rekening mee dat als de variabele min_examined_row_limit is ingesteld> 0, deze geen query's zal loggen, zelfs als het te lang duurt als het aantal geretourneerde rijen kleiner is dan de waarde die is ingesteld in min_examined_row_limit.
Raadpleeg de documentatie hier voor meer informatie over het afstemmen van uw trage registratie van zoekopdrachten.
sync_binlog
Deze variabele bepaalt hoe vaak MySQL binlogs naar de schijf synchroniseert. Standaard (>=5.7.7) is dit ingesteld op 1, wat betekent dat het naar schijf wordt gesynchroniseerd voordat transacties worden vastgelegd. Dit heeft echter een negatieve invloed op de prestaties vanwege het toegenomen aantal schrijfbewerkingen. Maar dit is de veiligste instelling als u samen met uw slaven strikt ACID-compatibel wilt zijn. Als alternatief kunt u dit op 0 zetten als u schijfsynchronisatie wilt uitschakelen en gewoon op het besturingssysteem wilt vertrouwen om het binaire logboek van tijd tot tijd naar schijf te spoelen. Als u dit hoger instelt dan 1, betekent dit dat de binlog wordt gesynchroniseerd met schijf nadat N binaire log-commit-groepen zijn verzameld, waarbij N> 1 is.
Bufferpool dumpen/herstellen
Het is vrij normaal dat uw productiedatabase moet opwarmen na een koude start/herstart. Door de huidige bufferpool te dumpen vóór een herstart, zou het de inhoud van de bufferpool opslaan en als deze eenmaal klaar is, wordt de inhoud weer in de bufferpool geladen. Dit vermijdt dus de noodzaak om uw database weer op te warmen naar de cache. Houd er rekening mee dat deze versie sindsdien is geïntroduceerd in 5.6, maar Percona Server 5.5 heeft deze al beschikbaar, voor het geval je je afvraagt. Om deze functie in te schakelen, stelt u beide variabelen innodb_buffer_pool_dump_at_shutdown =ON en innodb_buffer_pool_load_at_startup =ON in.
Hardware
We zijn nu in 2019, er zijn veel nieuwe hardwareverbeteringen geweest. Meestal is er geen harde vereiste dat MySQL een specifieke hardware vereist, maar dit hangt af van wat u met de database moet doen. Ik zou verwachten dat je deze blog niet leest omdat je een test doet of deze op een Intel Pentium 200 MHz draait.
Voor CPU zullen snellere processors met meerdere kernen optimaal zijn voor MySQL in de meest recente versies, ten minste sinds 5.6. Intel's Xeon/Itanium-processors kunnen duur zijn, maar getest op schaalbare en betrouwbare computerplatforms. Amazon heeft hun EC2-instanties verzonden die op ARM-architectuur draaien. Hoewel ik persoonlijk niet heb geprobeerd MySQL op ARM-architectuur te gebruiken of me deze te herinneren, zijn er benchmarks die jaren geleden zijn gemaakt. Moderne CPU's kunnen hun frequenties op en neer schalen op basis van temperatuur, belasting en energiebesparingsbeleid van het besturingssysteem. Er is echter een kans dat uw CPU-instellingen in uw Linux-besturingssysteem op een andere gouverneur zijn ingesteld. U kunt dat controleren of instellen met de "performance" -regelaar door het volgende te doen:
echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor
Voor geheugen is het erg belangrijk dat uw geheugen groot is en de grootte van uw dataset kan evenaren. Zorg ervoor dat je swappiness =1 hebt. Je kunt het controleren door sysctl te controleren of het bestand in procfs te controleren. Dit wordt bereikt door het volgende te doen:
$ sysctl -e vm.swappiness
vm.swappiness = 1
Of stel het als volgt in op een waarde van 1
$ sudo sysctl vm.swappiness=1
vm.swappiness = 1
Een ander goed ding om te overwegen voor uw geheugenbeheer is om THP (Transparrent Huge Pages) uit te schakelen. Ik herinner me dat we in het verleden een aantal rare problemen hadden met het CPU-gebruik en dachten dat dit te wijten was aan schijf-I/O. Het bleek dat het probleem zat in de kernel-khugepaged-thread die geheugen dynamisch toewijst tijdens runtime. Niet alleen dit, terwijl de kernel voor defragmentatie gaat, zal je geheugen snel worden toegewezen als het wordt doorgegeven aan THP. Standaard HugePages-geheugen wordt vooraf toegewezen bij het opstarten en verandert niet tijdens runtime. U kunt dit controleren en uitschakelen door het volgende te doen:
$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
Voor Disk is het belangrijk dat je een goede doorvoer hebt. Het gebruik van RAID10 is de beste setup voor een database met een batterijback-upeenheid. Met de komst van flashdrives die een hoge schijfdoorvoer en een hoge schijf-I/O voor lezen/schrijven bieden, is het belangrijk dat ze het hoge schijfgebruik en de schijf-I/O kunnen beheren.
Besturingssysteem
De meeste productiesystemen die op MySQL draaien, draaien op Linux. Het is omdat MySQL is getest en gebenchmarkt op Linux, en het klinkt alsof het de de facto standaard is voor een MySQL-installatie. Er is echter niets dat u ervan weerhoudt om het op Unix- of Windows-platform te gebruiken. Het zou gemakkelijker zijn als uw platform is getest en er een brede community is om te helpen, mocht u problemen ondervinden. De meeste setups draaien op RHEL/Centos/Fedora en Debian/Ubuntu-systemen. In AWS heeft Amazon hun Amazon Linux waarvan ik zie dat het door sommigen ook in productie wordt gebruikt.
Het belangrijkste om te overwegen bij uw installatie is dat uw bestandssysteem XFS of Ext4 gebruikt. Er zijn zeker voor- en nadelen tussen deze twee bestandssystemen, maar ik zal hier niet ingaan op de details. Sommigen zeggen dat XFS beter presteert dan Ext4, maar er zijn ook berichten dat Ext4 beter presteert dan XFS. ZFS komt ook uit beeld als een goede kandidaat voor een alternatief bestandssysteem. Jervin Real (van Percona) heeft hier een geweldige bron van, je kunt deze presentatie bekijken tijdens de ZFS-conferentie.
Externe links
https://developer.okta.com/blog/2015/05/22/tcmalloc
https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/
https://www.percona.com/live/18/sessions/benchmark-noise-reduction-how-to-configure-your-machines-for-stable-results
https://zfs.datto.com/2018_slides/real.pdf
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA