...

Effektiv anvendelse af MySQL Performance Schema for at opnå bedre ydeevne

For bedre MySQL-ydeevne bruger jeg Performance-skemaet til at analysere kørselstidsdata, ventetider, låse, hukommelse og I/O direkte med SQL. På den måde kan jeg hurtigere finde årsagerne til langsomme sætninger og iværksætte målrettede tiltag for Indstilling og overvågning fra [2][3][15].

Centrale punkter

Følgende fokusområder hjælper mig med at anvende Performance Schema effektivt.

  • Aktivering og en strømlinet konfiguration med passende instrumenter og forbrugsenheder
  • Statement-digests bruge til at identificere dyre mønstre og hotspots
  • Vent-begivenheder, analysere Locks og I/O samlet for at finde de reelle flaskehalse
  • Sys-skema som en forkortelse for hurtige, handlingsrettede indblik
  • Iterativ Arbejdsgang: måle, isolere, ændre, måle igen

Aktivér og konfigurer Performance-skemaet hensigtsmæssigt

Jeg tjekker først, om performance_schema er aktiv, da de nyeste MySQL-versioner som regel leveres med denne funktion aktiveret [1][12]. Hvis den mangler, indstiller jeg i [mysqld]-blokken af my.cnf variablen performance_schema=ON og genstarter serveren. Derefter indstiller jeg instrumenter og forbrugere målrettet, i stedet for at skrue alt op permanent. Jeg koncentrerer mig om statement/%, wait/% og relevante I/O-stier, så jeg kan indsamle meningsfulde data uden unødvendig overhead [6]. Før en ny måleserie tømmer jeg de relevante historiktabeller og starter med en ren Basis.

Hurtige resultater med Sys-skemaet

For at få et hurtigt overblik bruger jeg ofte sys-skemaet, fordi det på en fornuftig måde sammenfatter rådataene fra Performance-skemaet [13]. På den måde kan jeg på få minutter finde de forespørgsler, der tegner sig for den største andel af køretiden. Jeg starter med de vigtigste sætninger, tjekker fil-I/O-visninger og ser på ventetidsoversigter for tråde. Så snart jeg har identificeret et hotspot, går jeg tilbage til råtabellerne og forfiner analysen. Hvis man gennemgår forespørgselsplaner, kan man med passende Tips til Optimizer ofte mærkbar allerede efter kort tid Gevinster opnå.

Vælg de rigtige instrumenter og forbrugere

Jeg starter bredt, men holder overblikket under kontrol: Først aktiverer jeg de vigtigste Instrumenter til statements, waits og I/O; derefter slår jeg alt fra, der ikke giver noget signal [6]. Forbrugere som event-history og summary-tabeller skal understøtte de spørgsmål, jeg ønsker at besvare. Hvis det f.eks. drejer sig om latenstoppe, kigger jeg i oversigt_over_ventetider_globalt_efter_begivenhedsnavn og sammenlign det med oversigt_over_begivenheder_og_erklæringer_efter_digest. Hvis der opstår I/O-ventetider, kontrollerer jeg filoversigt_efter_begivenhedsnavn og table_io_waits_summary_by_table. Dette målrettede udvalg holder omkostningerne nede og leverer alligevel pålidelige Data.

Statement-Digests: Genkende mønstre, reducere belastningen

Ved hjælp af statement-digests kan jeg se, hvilke mønstre der er dyre på lang sigt, selvom de enkelte forespørgsler indeholder forskellige literaler [17]. Jeg sorterer efter samlet tid, antal udførelser og gennemsnitlig latenstid for at fastlægge prioriteter. I den forbindelse benytter jeg desuden Analyse af loggen over langsomme forespørgsler tilbage, for ikke at overse sjældne afvigelser. Når oversigterne viser spidser, tjekker jeg indekser, JOIN-strategier og filterrækkefølger med FORKLAR. Derefter bekræfter jeg effekten ved at foretage nye målinger i Performance-skemaet, så optimeringerne fortsat kan måles.

Fortolkning af ventebegivenheder, låse og I/O

Når forespørgsler hænger fast, tjekker jeg »Wait«- og »Lock«-tabellerne for at finde den egentlige Årsag kan findes [3]. Hvis der kører mange tråde på de samme tabeller, tyder det på table_lock-Venter på konkurrence. Hvis fil-I/O-hændelser viser høje ventetider, tjekker jeg lagring og caching samt forespørgselsmønstre ved hjælp af omfattende scanninger. Hvis jeg ser InnoDB-rækkelåse, analyserer jeg hot-records, transaktionsvarighed og indeksdækning. Først når disse puslespilsbrikker passer sammen, tager jeg fat på serverparametre, skemaet eller koden.

Overvågning af hukommelse: Hukommelse og bufferpool

Jeg afhjælper hukommelsesproblemer ved at sammenholde data fra hukommelsestabellerne og InnoDB-bufferudnyttelsen. Hvis hukommelsesbehovet for enkelte komponenter stiger, justerer jeg grænserne og kontrollerer, om cacherne binder de forkerte data. Hvis InnoDB-cachen ikke er tilstrækkelig, øger jeg andelen eller forbedrer forespørgselslokaliteten. Hvis man vil gå mere i dybden, kan man via Optimering af bufferpoolen opnå betydelige forbedringer i latenstiden. Jeg bekræfter effekten med de Resumé-Tabeller og hold øje med, om LRU-hits og I/O-ventetider udvikler sig i den rigtige retning.

Iterativt diagnoseforløb til daglig brug

Jeg arbejder altid i klare cyklusser, så jeg ikke spilder tid, og ændringerne forbliver målbare [3]. Først genskaber jeg problemet under kontrolleret belastning. Derefter samler jeg måleværdier i nogle få, målrettede tabeller og udvælger de mest iøjnefaldende kandidater. Derefter ændrer jeg det, der lover den største gevinst: indeks, forespørgsel, parameter eller kode. Til sidst måler jeg igen og dokumenterer kort Før/efter-tabeller, så teamet straks kan se effekten.

Eksempler på forespørgsler: Fra rådata til beslutninger

Til typiske spørgsmål har jeg noteret nogle korte SQL-kodestykker, som jeg bruger direkte i min dagligdag. Tabellen viser eksempler, som jeg ofte bruger, og hvad de står for. Jeg tilpasser filtre som LIMIT eller ORDER BY afhængigt af den konkrete situation. Det vigtige er: først en hypotese, derefter en målrettet analyse og en klar beslutning. På den måde holder jeg analysen fokuseret og undgår overflødige Belastning.

Performance-skema-tabeller Mål Vigtige kolonner Eksempel på en forespørgsel
oversigt_over_begivenheder_og_erklæringer_efter_digest Find dyre mønstre digest_text, count_star, sum_timer_wait SELECT digest_text, count_star, sum_timer_wait/1e12 AS sec_total FROM performance_schema.events_statements_summary_by_digest ORDER BY sec_total DESC LIMIT 10;
oversigt_over_ventetider_globalt_efter_begivenhedsnavn Ventetids-hotspots event_name, sum_timer_wait SELECT event_name, sum_timer_wait/1e12 AS sec_total FROM performance_schema.events_waits_summary_global_by_event_name ORDER BY sec_total DESC LIMIT 10;
table_io_waits_summary_by_table Kontroller tabel-I/O object_schema, object_name, read_timer_wait SELECT object_schema, object_name, (read_timer_wait+write_timer_wait)/1e12 AS sec_total FROM performance_schema.table_io_waits_summary_by_table ORDER BY sec_total DESC LIMIT 10;
memory_summary_global_efter_hændelsesnavn Find programmer, der bruger meget hukommelse event_name, current_alloc SELECT event_name, current_alloc/1024/1024 AS mb FROM performance_schema.memory_summary_global_by_event_name ORDER BY mb DESC LIMIT 10;

Produktionsvirksomhed: Minimér omkostningerne, maksimér effekten

Under live-drift tænder jeg ikke instrumenter i blinde, men vælger kun det, der besvarer mit spørgsmål [6]. Begivenheder med høj frekvens behandler jeg med forsigtighed og holder historikvinduet kort. Til længerevarende observationer foretrækker jeg komprimerede oversigter og gemmer øjebliksbilleder eksternt. Jeg er opmærksom på indtastningen i performance_schema_setup_consumers, så jeg kan styre samlingerne i stedet for bare at lade dem køre. Dette fokus holder analysen effektiv og beskytter serveren.

Finjustering: Setup-instrumenter og -brugere i praksis

For hurtigt at opnå pålidelige resultater konfigurerer jeg instrumenter og forbrugere målrettet. Særligt vigtigt er statement/%, wait/%, wait/io/% og – om nødvendigt – udvalgte memory/%-stier. Jeg aktiverer først kun det allermest nødvendige og udvider derefter, hvis jeg stadig har konkrete spørgsmål, der ikke er besvaret. Timerne i Performance-skemaet måler i pikosekunder; for at få sekunder dividerer jeg latenstidssøjlerne med 1e12.

Typisk startpunkt under kørsel:

-- Aktiver nøgleinstrumenter
UPDATE performance_schema.setup_instruments
  SET ENABLED='YES', TIMED='YES'
  WHERE NAME LIKE 'statement/%'
 OR NAME LIKE 'wait/io/%'
 OR NAME LIKE 'wait/lock/%';

-- Vælg vigtige forbrugere
UPDATE performance_schema.setup_consumers
  SET ENABLED='YES'
  WHERE NAME IN ('global_instrumentation',
 'thread_instrumentation',
 'statements_digest',
 'events_statements_current',
                 'events_statements_history',
 'events_waits_current',
 'events_waits_history');

-- Tøm oversigter for at få en ny måleserie
TRUNCATE TABLE performance_schema.events_statements_summary_by_digest;
TRUNCATE TABLE performance_schema.events_waits_summary_global_by_event_name;
TRUNCATE TABLE performance_schema.table_io_waits_summary_by_table;

Når jeg har brug for hukommelsesanalyser, aktiverer jeg dem selektivt memory/%-værktøjer. Det medfører større omkostninger, men er det værd i tilfælde af lækager eller stor belastning af allokatoren.

Dimensioner: Forståelse af bruger, vært og skema

Spidsbelastninger er ofte ikke generelle, men begrænset til bestemte Bruger, Værter eller en Ordning begrænset. Performance-skemaet leverer i den forbindelse oversigter pr. konto og vært. Derudover indeholder oversigten kolonnen skema_navn, for at indsnævre antallet af hotspots pr. database.

Eksempler, som jeg ofte bruger:

  • De mest anvendte skemaer efter samlet varighed: SELECT schema_name, SUM(sum_timer_wait)/1e12 AS sec_total FROM performance_schema.events_statements_summary_by_digest GROUP BY schema_name ORDER BY sec_total DESC LIMIT 10;
  • Brugere/værter, der forårsager den største forsinkelse (via konti): SELECT user, host, SUM(sum_timer_wait)/1e12 AS sec_total FROM performance_schema.events_statements_summary_by_account_by_event_name GROUP BY bruger, vært ORDER BY sec_total DESC LIMIT 10;
  • Tråde med længst ventetid: SELECT thread_id, SUM(sum_timer_wait)/1e12 AS sec_total FROM performance_schema.events_waits_summary_by_thread_by_event_name GROUP BY thread_id ORDER BY sec_total DESC LIMIT 10;

Med disse visninger kan jeg målrettet opdele trafiksegmenter og dermed begrænse, cache eller indføre forskellige forespørgselsvarianter for hver klient.

Gør lange transaktioner og metadata-låse synlige

Transaktioner, der kører i lang tid eller er inaktive, blokerer checkpoints, purge og konkurrerende DML. Derfor tjekker jeg regelmæssigt transaktionsoversigten og MDL-ventetiderne:

  • Aktive transaktioner: SELECT thread_id, timer_wait/1e12 AS sec_running, state FROM performance_schema.events_transactions_current ORDER BY sec_running DESC LIMIT 10;
  • Identificering af metadatablokeringer (DDL/DML-konkurrence): SELECT event_name, SUM(sum_timer_wait)/1e12 AS sec_total FROM performance_schema.events_waits_summary_global_by_event_name WHERE event_name LIKE 'wait/lock/metadata/sql/mdl%' GROUP BY event_name ORDER BY sec_total DESC;

Hvis MDL dominerer, omlægger jeg DDL-vinduerne, minimerer låsetiderne i koden (kortere transaktioner) og tjekker, om der er overflødige AUTOCOMMIT=0- at lade sessioner køre unødigt længe.

Replikering, sikkerhedskopier og bivirkninger i fokus

Replikations- og backup-processer vises i ventetids- og I/O-oversigter. Forsinkelser kan indkredses via worker-status og filventetider. Jeg ser på Applier-Worker, SQL-tråd og fil-I/O-hændelser:

  • Applier-Worker med høj latenstid: SELECT worker_id, THREAD_ID, APPLYING_TRANSACTION, APPLYING_STATE FROM performance_schema.replication_applier_status_by_worker;
  • Fil-I/O-hotspots under sikkerhedskopieringer: SELECT event_name, (sum_timer_read+sum_timer_write)/1e12 AS sec_total FROM performance_schema.file_summary_by_event_name ORDER BY sec_total DESC LIMIT 10;

Hvis jeg ser flaskehalse her, adskiller jeg I/O-faser (f.eks. windowing, I/O-scheduler, backup-throttling) eller øger antallet af parallelle applier-workere, forudsat at arbejdsbyrden kan skaleres.

Tidsvinduer, øjebliksbilleder og nulstillingsstrategier

Målinger kræver klare tidsrammer. Til „før/efter“-analyser arbejder jeg med målrettede nulstillinger og øjebliksbilleder:

  • Nulstil oversigterne for at få nye intervaller: TRUNCATE TABLE performance_schema.events_statements_summary_by_digest;
  • Sikkerhedskopiere øjebliksbillede eksternt: CREATE TABLE IF NOT EXISTS perf_snapshot_digest AS SELECT NOW() AS captured_at, * FROM performance_schema.events_statements_summary_by_digest;
  • Gem korte historikvinduer (forbruger), indsaml lange tendenser eksternt.

På den måde kan jeg sikkert sammenligne og dokumentere optimeringer på tværs af implementeringer, parameterændringer eller skemaændringer.

Styring af overhead og lagerbehov

En udbredt fordom er, at Performance Schema er „for dyrt“. I praksis holder jeg overheadet på et lavt niveau ved hjælp af tre tiltag: kun at aktivere relevante instrumenter, holde hyppigt anvendte historikforbrugere korte og vælge de rette lagerparametre. Ved stor varians i digest-intervallerne øger jeg målrettet performance_schema_digests_size samt – hvis det er nødvendigt – performance_schema_max_sql_text_length, så identiteterne forbliver stabile. Hvis der er behov for Memory-instrumenter, begrænser jeg dem til problematiske delsystemer.

Typiske justeringsskruer i my.cnf:

[mysqld]
performance_schema=ON
performance-schema-instrument='statement/%=ON'
performance-schema-instrument='wait/io/%=ON'
performance-schema-instrument='wait/lock/%=ON'
performance-schema-consumer-events-statements-history=ON
performance-schema-consumer-events-waits-history=ON
# Valgfrit, hvis der er mange mønstre:
performance_schema_digests_size=10000
performance_schema_max_sql_text_length=4096

Hver gang jeg foretager en ændring, kontrollerer jeg, om CPU, latenstid og hukommelsesforbrug forbliver stabile. Så snart diagnosen er afsluttet, nulstiller jeg konfigurationen til det „minimale driftsniveau“.

Almindelige mønstre og hurtige løsninger

  • Et stort beløb i oversigt_over_begivenheder_og_erklæringer_efter_digest, mange scanninger: Kontroller indekser, filterrækkefølge og sargability; bekræft med FORKLAR og gentag målingen (digest-tiden skal synligt falde).
  • Dominant table_io_waits i nogle få tabeller: Forbedre I/O-lokalisering (adgang via klyngeindekser, dækkende indekser), reducer datamængden pr. sætning, og anvend om nødvendigt batchbehandling i stedet for fuld tabelbehandling.
  • Ventetider på wait/lock/innodb/%: Identificere »hot records« og afbøde skrivekonflikter ved hjælp af mindre transaktioner, passende indekser eller køhåndtering.
  • Mange wait/lock/metadata/sql/mdl: Planlægge DDL-vinduer, ONLINE-foretrække operationer, der understøtter dette, og afkoble læser/skriver ved hjælp af kortere transaktioner.
  • Stigning i lagerbeholdningen i memory_summary_global_efter_hændelsesnavn: Skærpe grænserne, målrettet begrænse query-caches, problemkomponenter med memory/% opdele i detaljer.
  • „Spiky“-latens ved ellers upåfaldende gennemsnitsværdier: Brug Sys-visninger med percentiler, og mål om nødvendigt belastningstoppe separat (snævrere vindue, kort historik, målrettede instrumenter).

Korrelere: Fra tråd til statement og ventetid

For hurtigt at kunne finde sammenhæng mellem årsagerne, sammenkæder jeg performance_schema.threads med tabellerne »Current« og »History« for statements og waits. På den måde kan jeg se, hvad en pågældende tråd senest har foretaget sig, og hvad den venter på. En kortfattet gennemgang:

  1. Berørte personer PROCESSLIST_ID hhv. THREAD_ID fra performance_schema.threads hente.
  2. Seneste udtalelse via begivenheder_udtalelser_historik beregne (efter THREAD_ID og sortere efter tid).
  3. Parallelle ventetider fra events_waits_history Kontroller for at se, om der er lock- eller I/O-ventetidsårsager.

Dette „Drilldown & Join“-mønster er min standard, når enkelte sessioner eller webforespørgsler kommer ud af takt.

Kvalitetskontrolpunkter og løbende præstation

For at sikre, at optimeringerne ikke går til spilde, indfører jeg enkle kvalitetskontrolpunkter: definerede forespørgsler fra Performance Schema køres før og efter hver udgivelse. Jeg gemmer snapshots, sammenligner nøgletal (Top-Digests, Top-Waits, I/O pr. tabel) og dokumenterer afvigelser. I CI/CD tilføjer jeg repræsentative belastningsprofiler og grænseværdier for 95. percentilen. Hvis en måling falder uden for rammerne, er der en klar tilbagemeldingskanal: Tjek hypotesen, fokuser på værktøjerne, implementer rettelsen, mål igen.

Undgå fejlkilder

  • For mange instrumenter på lang sigt: Diagnosen er midlertidig; i normal drift skal kun minimalsættet være aktivt.
  • Blandede måleperioder: Tøm oversigterne inden nye tests, ellers forringer gamle data resultaternes pålidelighed.
  • Forkert tidsenhed: Timer angives i pikosekunder; konsekvent gennem hele teksten 1e12 dele.
  • En strøm af sammendrag: Variable literaler kan bryde mønstre; normaliser SQL og performance_schema_max_sql_text_length Tjek.
  • Historikken er for lang: Hyppige begivenheder + lang historik skaber pres; hold historikvinduet kort, og gem øjebliksbilleder eksternt.

Praksis-tjekliste

  • Definer spørgsmålet, formuler hypotesen.
  • Aktiver relevante værktøjer/forbrugere, hold omkostningerne nede.
  • Tøm oversigterne, vælg et kort målevindue.
  • Kontroller Top-Digests, ventetider og I/O; bekræft hotspots.
  • Tilpas indeks/forespørgsel/kode/parametre målrettet.
  • Mål igen, tag snapshots, dokumenter beslutningen.
  • Reducer konfigurationen til det absolutte minimum.

Kort sagt: Min fremgangsmåde i praksis

Jeg aktiverer Performance-skemaet målrettet, starter bredt og indsnævrer derefter til de mest nyttige Instrumenter [1][2][12]. For at få et hurtigt overblik bruger jeg Sys-skemaet og går om nødvendigt ned i rådataene [13]. Jeg adresserer først hotspots i digests og wait-events, før jeg justerer parametrene [3][15][17]. Derefter bekræfter jeg hver ændring med nye målinger, så fremskridtene forbliver synlige og reproducerbare. På den måde sikrer jeg vedvarende pålidelige Svartider og spar unødvendigt arbejde.

Aktuelle artikler