MySQL er omfattende og har masser af områder at optimere og justere til den ønskede ydeevne. Nogle ændringer kan udføres dynamisk, andre kræver genstart af serveren. Det er ret almindeligt at finde en MySQL-installation med en standardkonfiguration, selvom sidstnævnte måske ikke er passende i sig selv ud fra din arbejdsbyrde og opsætning.
Her er nøgleområderne i MySQL, som jeg har hentet fra forskellige ekspertkilder i MySQL-verdenen, samt vores egne erfaringer her på Severalnines. Denne blog vil fungere som dit snydeark for at justere ydeevnen og gøre din MySQL fantastisk igen :-)
Lad os tage et kig på disse ved at skitsere nøgleområderne i MySQL.
Systemvariabler
MySQL har masser af variabler, som du kan overveje at ændre. Nogle variabler er dynamiske, hvilket betyder, at de kan indstilles ved hjælp af SET-sætningen. Andre kræver en servergenstart, efter at de er indstillet i konfigurationsfilen (f.eks. /etc/my.cnf, etc/mysql/my.cnf). Jeg vil dog gennemgå de almindelige ting, der er ret almindelige at tune for at gøre serveren optimeret.
sort_buffer_size
Denne variabel kontrollerer, hvor stor din filesort buffer er, hvilket betyder, at når en forespørgsel skal sortere rækkerne, bruges værdien af denne variabel til at begrænse den størrelse, der skal allokeres. Bemærk, at denne variabel er pr-forespørgsel, der behandles (eller pr-forbindelse), hvilket betyder, at det ville være en hukommelseskrævende, når du indstiller dette højere, og hvis du har flere forbindelser, der kræver sortering af dine rækker. Du kan dog overvåge dine behov ved at kontrollere den globale statusvariabel Sort_merge_passes. Hvis denne værdi er stor, bør du overveje at øge værdien af systemvariablen sort_buffer_size. Ellers tag det til den moderate grænse, du har brug for. Hvis du indstiller dette for lavt, eller hvis du har store forespørgsler, der skal behandles, kan effekten af at sortere dine rækker være langsommere end forventet, fordi data hentes tilfældigt ved diskdyk. Dette kan forårsage forringelse af ydeevnen. Det er dog bedst at rette dine spørgsmål. Ellers, hvis din applikation er designet til at trække store forespørgsler og kræver sortering, så er det effektivt at bruge værktøjer, der håndterer forespørgselscache som Redis. Som standard, i MySQL 8.0, er den aktuelle værdi indstillet 256 KiB. Indstil kun dette i overensstemmelse hermed, når du har forespørgsler, der bruger meget eller kalder sorteringer.
read_buffer_size
MySQL-dokumentationen nævner, at for hver anmodning, der udfører en sekventiel scanning af en tabel, allokerer den en læsebuffer. Systemvariablen read_buffer_size bestemmer bufferstørrelsen. Det er også nyttigt til MyISAM, men denne variabel påvirker også alle lagringsmotorer. For MEMORY-tabeller bruges den til at bestemme hukommelsesblokstørrelsen.
Grundlæggende tildeler hver tråd, der foretager en sekventiel scanning for en MyISAM-tabel, en buffer af denne størrelse (i bytes) for hver tabel, den scanner. Det gælder også for alle lagermotorer (der inkluderer InnoDB), så det er nyttigt for forespørgsler, der sorterer rækker ved hjælp af ORDER BY og cachelagrer dets indekser i en midlertidig fil. Hvis du laver mange sekventielle scanninger, skal du masseindsætte i partitionstabeller, cache resultater af indlejrede forespørgsler og derefter overveje at øge værdien. Værdien af denne variabel skal være et multiplum af 4KB. Hvis den er sat til en værdi, der ikke er et multiplum af 4KB, vil dens værdi blive rundet ned til nærmeste multiplum af 4KB. Tag i betragtning, at indstilling af dette til en højere værdi vil forbruge en stor del af din servers hukommelse. Jeg foreslår, at du ikke bruger dette uden ordentlig benchmarking og overvågning af dit miljø.
read_rnd_buffer_size
Denne variabel omhandler læsning af rækker fra en MyISAM-tabel i sorteret rækkefølge efter en nøglesorteringsoperation, rækkerne læses gennem denne buffer for at undgå disksøgninger. Dokumentationen siger, at når rækker læses i en vilkårlig rækkefølge eller fra en MyISAM-tabel i sorteret rækkefølge efter en nøglesorteringsoperation, læses rækkerne gennem denne buffer (og bestemmes gennem denne bufferstørrelse) for at undgå disksøgninger. Indstilling af variablen til en stor værdi kan forbedre ORDER BY-ydelsen med en hel del. Dette er dog en buffer tildelt for hver klient, så du bør ikke indstille den globale variabel til en stor værdi. I stedet skal du kun ændre sessionsvariablen fra de klienter, der skal køre store forespørgsler. Du skal dog tage højde for, at dette ikke gælder for MariaDB, især når du udnytter MRR. MariaDB bruger mrr_buffer_size, mens MySQL bruger read_buffer_size read_rnd_buffer_size.
join_buffer_size
Som standard er værdien 256K. Minimumsstørrelsen af bufferen, der bruges til almindelige indeksscanninger, intervalindeksscanninger og joins, der ikke bruger indekser og dermed udfører fulde tabelscanninger. Bruges også af BKA-optimeringen (som er deaktiveret som standard). Forøg dens værdi for at få hurtigere fulde joinforbindelser, når tilføjelse af indekser ikke er muligt. Advarsel kan dog være hukommelsesproblemer, hvis du indstiller dette for højt. Husk, at der er tildelt én joinbuffer for hver fuld join mellem to tabeller. For en kompleks joinforbindelse mellem flere tabeller, som indekser ikke bruges til, kan flere joinbuffere være nødvendige. Bedst venstre lavt globalt og sat højt i sessioner (ved at bruge SET SESSION-syntaks), der kræver store fulde joinforbindelser. På 64-bit platforme trunkerer Windows værdier over 4 GB til 4 GB-1 med en advarsel.
max_heap_table_size
Dette er den maksimale størrelse i bytes for brugeroprettede MEMORY-tabeller, der tillades at vokse. Dette er nyttigt, når din applikation beskæftiger sig med MEMORY-lagringsmotortabeller. Indstilling af variablen, mens serveren er aktiv, har ingen effekt på eksisterende tabeller, medmindre de er genskabt eller ændret. Den mindste af max_heap_table_size og tmp_table_size begrænser også interne tabeller i hukommelsen. Denne variabel er også i forbindelse med tmp_table_size for at begrænse størrelsen af interne tabeller i hukommelsen (dette adskiller sig fra de tabeller, der er oprettet eksplicit som Engine=MEMORY, da den kun anvender max_heap_table_size), alt efter hvad der er mindst, anvendes mellem de to.
tmp_table_size
Den største størrelse for midlertidige tabeller i hukommelsen (ikke MEMORY tabeller), men hvis max_heap_table_size er mindre, vil den nedre grænse gælde. Hvis en midlertidig tabel i hukommelsen overskrider grænsen, konverterer MySQL den automatisk til en midlertidig tabel på disken. Forøg værdien af tmp_table_size (og max_heap_table_size hvis det er nødvendigt), hvis du laver mange avancerede GROUP BY-forespørgsler, og du har stor ledig hukommelsesplads. Du kan sammenligne antallet af interne midlertidige tabeller på disken, der er oprettet, med det samlede antal interne, midlertidige tabeller, der er oprettet ved at sammenligne værdierne for variablerne Created_tmp_disk_tables og Created_tmp_tables. I ClusterControl kan du overvåge dette via Dashboard -> Grafen for midlertidige objekter.
table_open_cache
Du kan øge værdien af denne variabel, hvis du har et stort antal tabeller, der ofte tilgås i dit datasæt. Det vil blive anvendt for alle tråde, hvilket betyder pr. forbindelsesbasis. Værdien angiver det maksimale antal tabeller, serveren kan holde åbne i en tabelcache-forekomst. Selvom en forøgelse af denne værdi øger antallet af fildeskriptorer, som mysqld kræver, så kan du lige så godt overveje at tjekke din open_files_limit værdi eller kontrollere, hvor stor den SOFT og HARD grænse er sat i dit *nix operativsystem. Du kan overvåge dette, om du skal øge tabelcachen ved at kontrollere statusvariablen Opened_tables. Hvis værdien af Opened_tables er stor, og du ikke bruger FLUSH TABLES ofte (hvilket bare tvinger alle tabeller til at blive lukket og genåbnet), så bør du øge værdien af table_open_cache-variablen. Hvis du har en lille værdi for table_open_cache, og et stort antal tabeller tilgås ofte, kan dette påvirke din servers ydeevne. Hvis du bemærker mange poster i MySQL-proceslisten med status "Åbner tabeller" eller "Lukker tabeller", så er det tid til at justere værdien af denne variabel, men noter dig den advarsel, der er nævnt tidligere. I ClusterControl kan du tjekke dette under Dashboards -> Table Open Cache Status eller Dashboards -> Åbne tabeller. Du kan tjekke det her for mere info.
table_open_cache_instances
Indstilling af denne variabel ville hjælpe med at forbedre skalerbarheden og selvfølgelig ydeevnen, hvilket ville reducere stridigheder mellem sessioner. Den værdi, du angiver her, begrænser antallet af åbne tabeller-cache-forekomster. Open tables cache kan opdeles i flere mindre cache-forekomster af størrelsen table_open_cache/table_open_cache_instances. En session skal kun låse én instans for at få adgang til den for DML-sætninger. Dette segmenterer cache-adgang blandt instanser, hvilket tillader højere ydeevne for operationer, der bruger cachen, når der er mange sessioner, der får adgang til tabeller. (DDL-sætninger kræver stadig en låsning på hele cachen, men sådanne sætninger er meget sjældnere end DML-sætninger.) En værdi på 8 eller 16 anbefales på systemer, der rutinemæssigt bruger 16 eller flere kerner.
tabeldefinition_cache
Cache-tabeldefinitioner, dvs. det er her CREATE TABLE cachelagres for at fremskynde åbning af tabeller og kun én indgang pr. tabel. Det ville være rimeligt at øge værdien, hvis du har et stort antal borde. Tabeldefinitionscachen tager mindre plads og bruger ikke filbeskrivelser, i modsætning til den normale tabelcache. Peter Zaitsev fra Percona foreslår, om du kan prøve indstillingen af formlen nedenfor,
The number of user-defined tables + 10% unless 50K+ tables
Men vær opmærksom på, at standardværdien er baseret på følgende formel, der er begrænset til en grænse på 2000.
MIN(400 + table_open_cache / 2, 2000)
Så hvis du har et større antal borde sammenlignet med standarden, er det rimeligt, at du øger dens værdi. Tag i betragtning, at med InnoDB bruges denne variabel som en blød grænse for antallet af åbne tabelforekomster for dataordbogscachen. Den vil anvende LRU-mekanismen, når den overstiger den aktuelle værdi af denne variabel. Grænsen hjælper med at løse situationer, hvor betydelige mængder hukommelse ville blive brugt til at cache sjældent brugte tabelforekomster, indtil den næste servergenstart. Derfor placeres overordnede og underordnede tabelforekomster med fremmednøglerelationer ikke på LRU-listen og kan pålægge en højere grænse end grænsen defineret af table_definition_cache og er ikke genstand for eviction i hukommelsen under LRU. Derudover definerer table_definition_cachen en blød grænse for antallet af InnoDB fil-per-table tablespaces, der kan være åbne på én gang, hvilket også styres af innodb_open_files, og faktisk bruges den højeste indstilling mellem disse variabler, hvis begge er indstillet . Hvis ingen af variablerne er indstillet, bruges table_definition_cache, som har en højere standardværdi. Hvis antallet af åbne tablespace-filhåndtag overstiger grænsen, der er defineret af table_definition_cache eller innodb_open_files, søger LRU-mekanismen i tablespace-filens LRU-liste for filer, der er fuldstændig tømt og ikke i øjeblikket udvides. Denne proces udføres hver gang et nyt tablespace åbnes. Hvis der ikke er nogen "inaktive" tablespaces, lukkes ingen tablespace-filer. Så husk dette.
max_allowed_packet
Dette er den maksimale størrelse pr. forbindelse af en returneret SQL-forespørgsel eller række. Værdien blev sidst øget i MySQL 5.6. Men i MySQL 8.0 (i det mindste på 8.0.3) er den nuværende standardværdi 64 MiB. Du kan overveje at justere dette, hvis du har store BLOB-rækker, der skal trækkes ud (eller læses), ellers kan du lade disse standardindstillinger blive med 8.0, men i ældre versioner er standard 4 MiB, så du kan tage dig af det, hvis du støder på ER_NET_PACKET_TOO_LARGE fejl. Den størst mulige pakke, der kan overføres til eller fra en MySQL 8.0-server eller -klient, er 1 GB.
skip_name_resolve MySQL-serveren håndterer indgående forbindelser ved hjælp af værtsnavnopløsning. Som standard deaktiverer MySQL ikke nogen opløsning af værtsnavne, hvilket betyder, at den vil udføre et DNS-opslag, og tilfældigt, hvis DNS er langsom, kan det være årsagen til en forfærdelig ydeevne til din database. Overvej at slå dette til, hvis du ikke har brug for DNS-opløsning, og drag fordel af at forbedre din MySQL-ydeevne, når dette DNS-opslag er deaktiveret. Tag i betragtning, at denne variabel ikke er dynamisk, derfor er en servergenstart påkrævet, hvis du indstiller dette i din MySQL-konfigurationsfil. Du kan eventuelt starte mysqld-dæmonen ved at sende --skip-name-resolve mulighed for at aktivere dette.max_connections
Dette er antallet af tilladte forbindelser til din MySQL-server. Hvis du finder ud af fejlen i MySQL 'For mange forbindelser', kan du overveje at sætte den højere. Som standard er værdien af 151 ikke nok, især på en produktionsdatabase, og i betragtning af at du har større ressourcer på serveren (spild ikke dine serverressourcer, især hvis det er en dedikeret MySQL-server). Du skal dog have nok filbeskrivelser, ellers løber du tør for dem. Overvej i så fald at justere din SOFT og HARD grænse for dine *nix operativsystemer og indstil en højere værdi af open_files_limit i MySQL (5000 er standardgrænsen). Tag i betragtning, at det er meget hyppigt, at applikationen ikke lukker forbindelser til databasen korrekt, og at indstille en høj max_connections kan resultere i en vis manglende respons eller høj belastning af din server. Brug af en forbindelsespulje på applikationsniveau kan hjælpe med at løse problemet her.
thread_cache_size
Dette er cachen for at forhindre overdreven trådoprettelse. Når en klient afbryder forbindelsen, lægges klientens tråde i cachen, hvis der er færre end thread_cache_size-tråde der. Anmodninger om tråde imødekommes ved at genbruge tråde taget fra cachen, hvis det er muligt, og kun når cachen er tom oprettes en ny tråd. Denne variabel kan øges for at forbedre ydeevnen, hvis du har mange nye forbindelser. Normalt giver dette ikke en nævneværdig forbedring af ydeevnen, hvis du har en god trådimplementering. Men hvis din server ser hundredvis af forbindelser i sekundet, bør du normalt indstille thread_cache_size højt nok, så de fleste nye forbindelser bruger cachelagrede tråde. Ved at undersøge forskellen mellem Connections og Threads_created statusvariablerne kan du se, hvor effektiv trådcachen er. Ved at bruge formlen angivet i dokumentationen er 8 + (max_connections / 100) godt nok.
query_cache_size
For nogle opsætninger er denne variabel deres værste fjende. For nogle systemer, der oplever høj belastning og har travlt med høje læsninger, vil denne variabel fordybe dig. Der har været benchmarks, der var gennemtestede af f.eks. Percona. Denne variabel skal også indstilles til 0 sammen med query_cache_type =0 for at slå den fra. Den gode nyhed i MySQL 8.0 er, at MySQL-teamet er holdt op med at understøtte dette, da denne variabel virkelig kan forårsage præstationsproblemer. Jeg er nødt til at være enig på deres blog, at det er usandsynligt, at det forbedrer forudsigeligheden af præstationer. Hvis du er engageret i at bruge forespørgselscache, foreslår jeg at bruge Redis eller ProxySQL.
Storage Engine - InnoDB
InnoDB er en ACID-kompatibel lagermotor med forskellige funktioner at tilbyde sammen med understøttelse af fremmednøgle (Declarative Referential Integrity). Dette har en masse ting at sige her, men visse variabler at overveje for tuning:
innodb_buffer_pool_size
Denne variabel fungerer som en nøglebuffer for MyISAM, men den har masser af ting at tilbyde. Da InnoDB er stærkt afhængig af bufferpuljen, vil du overveje at indstille denne værdi typisk til 70%-80% af din servers hukommelse. Det er også fordelagtigt, at du har en større hukommelsesplads end dit datasæt, og at du indstiller en højere værdi for din bufferpulje, men ikke for meget. I ClusterControl kan dette overvåges ved hjælp af vores Dashboards -> InnoDB Metrics -> InnoDB Buffer Pool Pages-graf. Du kan også overvåge dette med VIS GLOBAL STATUS ved at bruge variablerne Innodb_buffer_pool_pages*.
innodb_buffer_pool_instances
For din samtidige arbejdsbyrde kan indstilling af denne variabel forbedre samtidighed og reducere stridigheder som forskellige tråde af læse/skrive til cachelagrede sider. Minimum innodb_buffer_pool_instances skal ligge mellem 1 (minimum) og 64 (maksimum). Hver side, der er gemt i eller læst fra bufferpuljen, tildeles tilfældigt til en af bufferpuljenforekomsterne ved hjælp af en hashing-funktion. Hver bufferpulje administrerer sine egne frie lister, flushlister, LRU'er og alle andre datastrukturer, der er forbundet til en bufferpulje, og er beskyttet af sin egen bufferpuljemutex. Bemærk, at denne mulighed kun træder i kraft, når innodb_buffer_pool_size>=1GiB og dens størrelse er opdelt mellem bufferpuljeforekomsterne.
innodb_log_file_size
Denne variabel er logfilen i en loggruppe. Den kombinerede størrelse af logfiler (innodb_log_file_size * innodb_log_files_in_group) må ikke overstige en maksimal værdi, der er lidt mindre end 512 GB. Ifølge Vadim er en større logfilstørrelse bedre for ydeevnen, men den har en ulempe (en betydelig en), som du skal bekymre dig om:genoprettelsestiden efter et nedbrud. Du er nødt til at balancere restitutionstiden i det sjældne tilfælde af en crash recovery versus maksimering af gennemløbet under spidsbelastningsoperationer. Denne begrænsning kan oversættes til en 20 gange længere nedbrudsgendannelsesproces!
For at uddybe det, ville en større værdi være godt for InnoDB-transaktionslogfiler og er afgørende for god og stabil skriveydeevne. Jo større værdien er, desto mindre kontrolpunktsskylleaktivitet kræves der i bufferpuljen, hvilket sparer disk I/O. Gendannelsesprocessen er dog ret langsom, når først din database blev unormalt lukket (nedbrud eller dræbt, enten OOM eller utilsigtet). Ideelt set kan du have 1-2GiB i produktion, men du kan selvfølgelig justere dette. Benchmarking af disse ændringer kan være en stor fordel for at se, hvordan den fungerer, især efter et nedbrud.
innodb_log_buffer_size
For at gemme disk I/O, skriver InnoDB's ændringsdataene ind i lts logbuffer, og den bruger værdien af innodb_log_buffer_size med en standardværdi på 8MiB. Dette er en fordel, især for store transaktioner, da det ikke behøver at skrive loggen over ændringer til disken, før transaktionen foretages. Hvis din skrivetrafik er for høj (indsætter, sletter, opdaterer), sparer du disk I/O ved at gøre bufferen større.
innodb_flush_log_at_trx_commit
Når innodb_flush_log_at_trx_commit er indstillet til 1, tømmes logbufferen ved hver transaktions-commit til logfilen på disken og giver maksimal dataintegritet, men det har også effekt på ydeevnen. Hvis du indstiller det til 2, betyder det, at logbufferen tømmes til OS-filcachen ved hver transaktions-commit. Implikationen af 2 er optimal og forbedrer ydeevnen, hvis du kan slække på dine ACID-krav og har råd til at miste transaktioner i det sidste sekund eller to i tilfælde af OS-nedbrud.
innodb_thread_concurrency
Med forbedringer til InnoDB-motoren anbefales det at lade motoren styre samtidigheden ved at holde den til standardværdien (som er nul). Hvis du ser samtidighedsproblemer, kan du justere denne variabel. En anbefalet værdi er 2 gange antallet af CPU'er plus antallet af diske. Dens dynamiske variabel betyder, at den kan indstilles uden at genstarte MySQL-serveren.
innodb_flush_method
Denne variabel skal dog prøves og testes på, hvilken hardware der passer dig bedst. Hvis du bruger et RAID med batteriunderstøttet cache, hjælper DIRECT_IO med at lette I/O-trykket. Direct I/O cachelagres ikke, så det undgår dobbeltbuffring med bufferpulje og filsystemcache. Hvis din disk er lagret i SAN, kan O_DSYNC være hurtigere for en læsetung arbejdsbyrde med for det meste SELECT-sætninger.
innodb_file_per_table
innodb_file_per_table er som standard TIL fra MySQL 5.6. Dette anbefales normalt, da det undgår at have et stort delt tablespace, og da det giver dig mulighed for at genvinde plads, når du taber eller afkorter et bord. Separat tablespace er også fordelagtigt for Xtrabackup delvis backup-skema.
innodb_stats_on_metadata
Dette forsøger at holde procentdelen af beskidte sider under kontrol, og før Innodb-pluginet var dette virkelig den eneste måde at tune beskidt bufferudskylning på. Jeg har dog set servere med 3% beskidte buffere, og de rammer deres maks. checkpoint-alder. Måden, hvorpå dette øger beskidte bufferskylning, skalerer heller ikke godt på høje io-undersystemer, det fordobler faktisk bare den beskidte bufferskylning pr. sekund, når % beskidte sider overstiger denne mængde.
innodb_io_capacity
Denne indstilling, på trods af alle vores store håb om, at den ville gøre det muligt for Innodb at gøre bedre brug af vores IO i alle operationer, styrer ganske enkelt mængden af beskidte siders skylning pr. sekund (og andre baggrundsopgaver som f.eks. read-ahead). Gør dette større, du skyller mere i sekundet. Dette tilpasser sig ikke, det gør simpelthen så mange iops hvert sekund, hvis der er snavsede buffere at skylle. Det vil effektivt eliminere enhver optimering af IO-konsolidering, hvis du har en lav nok skrive-arbejdsbyrde (det vil sige, snavsede sider bliver skyllet ud næsten øjeblikkeligt, vi kan være bedre stillet uden en transaktionslog i dette tilfælde). Det kan også hurtigt sulte datalæsninger og skrivninger til transaktionsloggen, hvis du indstiller dette for højt.
innodb_write_io_threads
Kontrollerer, hvor mange tråde der skal skrives til disken. Jeg er ikke sikker på, hvorfor dette stadig er nyttigt, hvis du kan bruge Linux native AIO. Disse kan også gøres ubrugelige af filsystemer, der ikke tillader parallel skrivning til den samme fil med mere end én tråd (især hvis du har relativt få tabeller og/eller bruger de globale tablespaces)
innodb_adaptive_flushing
Angiver, om der dynamisk skal justeres hastigheden for skylning af beskidte sider i InnoDB-bufferpuljen baseret på arbejdsbelastningen. Dynamisk justering af skyllehastigheden er beregnet til at undgå udbrud af I/O-aktivitet. Dette er typisk aktiveret som standard. Denne variabel, når den er aktiveret, forsøger at være smartere til at skylle mere aggressivt baseret på antallet af beskidte sider og vækstraten for transaktionslog.
innodb_dedicated_server
Denne variabel er ny i MySQL 8.0, som anvendes globalt og kræver en MySQL-genstart, da den ikke er en dynamisk variabel. Men da dokumentationen siger, at denne variabel kun ønskes aktiveret, hvis din MySQL kører på en dedikeret server. Ellers må du ikke aktivere dette på en delt vært eller dele systemressourcer med andre applikationer. Når dette er aktiveret, vil InnoDB foretage en automatisk konfiguration for mængden af hukommelse, der er fundet for variablerne innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_method. Ulempen er kun, at du ikke kan have mulighed for at anvende dine ønskede værdier på de nævnte detekterede variabler.
MyISAM
key_buffer_size
InnoDB er standardlagringsmotoren i MySQL nu, standarden for key_buffer_size kan sandsynligvis reduceres, medmindre du bruger MyISAM produktivt som en del af din applikation (men hvem bruger MyISAM i produktionen nu?). Jeg vil her foreslå at indstille måske 1 % RAM eller 256 MiB ved start, hvis du har større hukommelse og dedikerer den resterende hukommelse til din OS-cache og InnoDB-bufferpulje.
Andre bestemmelser for ydeevne
slow_query_log
Selvfølgelig hjælper denne variabel ikke med at booste din MySQL-server. Denne variabel kan dog hjælpe dig med at analysere langsomme forespørgsler. Værdien kan indstilles til 0 eller FRA for at deaktivere logning. Indstil den til 1 eller ON for at aktivere dette. Standardværdien afhænger af, om --slow_query_log-indstillingen er givet. Destinationen for logoutput styres af systemvariablen log_output; hvis denne værdi er NONE, skrives ingen logposter, selvom loggen er aktiveret. Du kan angive filnavnet eller destinationen for forespørgselslogfilen ved at indstille variablen slow_query_log_file.
long_query_time
Hvis en forespørgsel tager længere tid end så mange sekunder, øger serveren statusvariablen Slow_queries. Hvis den langsomme forespørgselslog er aktiveret, logges forespørgslen til logfilen for langsomme forespørgsler. Denne værdi måles i realtid, ikke CPU-tid, så en forespørgsel, der er under tærsklen på et let belastet system, kan være over tærsklen på et stærkt belastet. Minimums- og standardværdierne for long_query_time er henholdsvis 0 og 10. Bemærk også, at hvis variablen min_examined_row_limit er sat> 0, vil den ikke logge forespørgsler, selvom det tager for lang tid, hvis antallet af returnerede rækker er mindre end værdien angivet i min_examined_row_limit.
For mere information om justering af din langsomme forespørgselslogning, se dokumentationen her.
sync_binlog
Denne variabel kontrollerer, hvor ofte MySQL vil synkronisere binlogs til disken. Som standard (>=5.7.7) er dette sat til 1, hvilket betyder, at det synkroniseres til disken, før transaktioner udføres. Dette medfører dog en negativ indvirkning på ydeevnen på grund af øget antal skrivninger. Men dette er den sikreste indstilling, hvis du ønsker strengt ACID-kompatibel sammen med dine slaver. Alternativt kan du indstille dette til 0, hvis du vil deaktivere disksynkronisering og blot stole på, at operativsystemet tømmer den binære log til disk fra tid til anden. Hvis den indstilles højere end 1, betyder det, at binlog synkroniseres til disk, efter at N binære log-commit-grupper er blevet indsamlet, hvor N er> 1.
Dump/gendan bufferpulje
Det er ret almindeligt, at din produktionsdatabase skal varmes op fra en kold start/genstart. Ved at dumpe den aktuelle bufferpulje før en genstart, ville den gemme indholdet fra bufferpuljen, og når den først er oppe, vil den indlæse indholdet tilbage i bufferpuljen. Dermed undgår dette behovet for at varme din database op tilbage til cachen. Bemærk, at denne version siden blev introduceret i 5.6, men Percona Server 5.5 har den allerede tilgængelig, bare hvis du undrer dig. For at aktivere denne funktion skal du indstille begge variabler innodb_buffer_pool_dump_at_shutdown =TIL og innodb_buffer_pool_load_at_startup =TIL.
Hardware
Vi er nu i 2019, der har været en masse nye hardwareforbedringer. Typisk er der ikke noget hårdt krav om, at MySQL kræver en specifik hardware, men dette afhænger af, hvad du skal bruge databasen til at gøre. Jeg ville forvente, at du ikke læser denne blog, fordi du laver en test, om den kører på en Intel Pentium 200 MHz.
For CPU vil hurtigere processorer med flere kerner være optimale til MySQL i de seneste versioner i hvert fald siden 5.6. Intels Xeon/Itanium-processorer kan være dyre, men testet for skalerbare og pålidelige computerplatforme. Amazon har sendt deres EC2-instanser, der kører på ARM-arkitektur. Selvom jeg personligt ikke har prøvet at køre eller huske at køre MySQL på ARM-arkitektur, er der benchmarks, der var blevet lavet for år siden. Moderne CPU'er kan skalere deres frekvenser op og ned baseret på temperatur, belastning og OS strømbesparende politikker. Der er dog en chance for, at dine CPU-indstillinger i dit Linux OS er indstillet til en anden guvernør. Du kan tjekke det ud eller indstille med "performance" guvernør ved at gøre følgende:
echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor
For Hukommelse er det meget vigtigt, at din hukommelse er stor og kan sidestille størrelsen af dit datasæt. Sørg for at du har swappiness =1. Du kan tjekke det ud ved at tjekke sysctl eller tjekke filen i procfs. Dette opnås ved at gøre følgende:
$ sysctl -e vm.swappiness
vm.swappiness = 1
Eller indstil den til en værdi på 1 som følger
$ sudo sysctl vm.swappiness=1
vm.swappiness = 1
En anden god ting at overveje til din hukommelsesstyring er at overveje at slå THP (Transparrent Huge Pages) fra. Tidligere kan jeg huske, at vi har nogle mærkelige problemer med CPU-udnyttelse og troede, at det skyldtes disk I/O. Det viste sig, at problemet var med kernel khugepaged tråd, som tildeler hukommelse dynamisk under kørsel. Ikke kun dette, mens kernen går til defragmentering, vil din hukommelse hurtigt blive allokeret, når den overfører den til THP. Standard HugePages-hukommelse er forhåndstildelt ved opstart og ændres ikke under kørsel. Du kan bekræfte og deaktivere dette ved at gøre følgende:
$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
For Disk er det vigtigt, at du har et godt gennemløb. Brug af RAID10 er den bedste opsætning til en database med en batteri backup enhed. Med fremkomsten af flashdrev, der tilbyder høj diskgennemstrømning og høj disk I/O til læsning/skrivning, er det vigtigt, at det kan styre den høje diskudnyttelse og disk I/O.
Operativsystem
De fleste produktionssystemer, der kører på MySQL, kører på Linux. Det er fordi MySQL var blevet testet og benchmarked på Linux, og det lyder, at det er de facto-standarden for en MySQL-installation. Men der er selvfølgelig intet, der forhindrer dig i at bruge det på Unix- eller Windows-platformen. Det ville være nemmere, hvis din platform er blevet testet, og der er et bredt fællesskab til at hjælpe, hvis du oplever problemer. De fleste opsætninger kører på RHEL/Centos/Fedora og Debian/Ubuntu-systemer. I AWS har Amazon deres Amazon Linux, som jeg ser som godt brugt i produktionen af nogle.
Det vigtigste at overveje med din opsætning er, at dit filsystem bruger enten XFS eller Ext4. Der er helt sikkert fordele og ulemper mellem disse to filsystemer, men jeg vil ikke gå til detaljerne her. Nogle siger, at XFS overgår Ext4, men der er også rapporter om, at Ext4 overgår XFS. ZFS kommer også ud af billedet som en god kandidat til et alternativt filsystem. Jervin Real (fra Percona) har en stor ressource på denne, du kan tjekke denne præsentation under ZFS-konferencen.
Eksterne 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/da/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA