MySQL-timeouts i hosting opstår ofte netop, når forespørgsler venter, eller forbindelser forbliver åbne for længe. Jeg vil vise dig, hvordan du genkender årsagerne, indstiller timeouts på en målrettet måde og dermed Fejl og mangler og Fejlmeddelelser reducere.
Centrale punkter
- ÅrsagerInaktive forbindelser, langsomme forespørgsler, ventetid
- DiagnoseLangsom forespørgselslog, EXPLAIN, Logs
- Indstillingerwait_timeout, connect_timeout, Pool
- OptimeringIndekser, sammenføjninger, max_udførelsestid
- HostingForbindelsesgrænser, DoS-beskyttelse
Hvorfor opstår der timeouts for MySQL-forbindelser i hosting?
I hostingmiljøer kører mange apps parallelt, deler ressourcer og genererer dermed Ventetider og Spidsbelastning. Timeouts opstår, hvis en forbindelse forbliver inaktiv for længe, eller hvis en forespørgsel overskrider grænsen; variablerne wait_timeout (for ikke-interaktive klienter) og interactive_timeout (for konsolforbindelser) er særligt effektive her. Connect_timeout tæller for etablering af en forbindelse, mens net_read_timeout og net_write_timeout er relevante for læse- og skriveprocesser. En enkelt langsom anmodning uden et passende indeks kan tage minutter og tilstoppe forbindelsespuljen og blokere for yderligere anmodninger. Høj netværksforsinkelse eller store afstande mellem app-serveren og databasen forværrer problemet, og derfor evaluerer jeg altid timeouts sammen med forespørgslens kvalitet og netværksstien.
Klassificer fejlmeddelelser korrekt
Jeg skelner først mellem „Connection timed out“ (opsætningen mislykkes) og „Command timeout“ (kommandoen kører for længe), fordi begge er forskellige. Årsager og Løsninger har. Meddelelser som „MySQL server has gone away“ indikerer ofte tabte forbindelser, for små pakker (max_allowed_packet) eller en hård genstart. Jeg genkender mønstre i logfiler: Hvis timeouts ophobes på spidsbelastningstidspunkter, er det mere sandsynligt, at det skyldes belastning eller manglende pooling; hvis de opstår med det samme, tjekker jeg netværket, DNS eller firewalls. Til et struktureret dyk bruger jeg den langsomme forespørgselslog og ser på de kritiske udsagn med EXPLAIN. Jeg opsummerer en kompakt oversigt over årsager og begrænsninger her: Årsager og serverbegrænsninger.
Indstil systemvariabler specifikt
Jeg justerer timeouts i sessionen først og tjekker opførslen, før jeg starter globale timeouts. Standardindstillinger og Filer ændring. For eksempel indstiller jeg sessionsbaseret. SET SESSION wait_timeout = 3600;, global per SET GLOBAL wait_timeout = 3600;, hvor globale ændringer går tabt efter en genstart. Jeg indtaster permanente værdier i my.cnf/my.ini, f.eks. under [mysqld] med wait_timeout, interactive_timeout, connect_timeout, net_read_timeout og net_write_timeout. Derefter genstarter jeg tjenesten og måler, om fejlrater og svartider forbedres. Jeg undgår meget høje timeouts, fordi åbne, inaktive forbindelser binder ressourcer og kan udløse kædereaktioner senere.
Diagnose: Logfiler, langsomme forespørgsler og køretider
Til analysen aktiverer jeg den langsomme forespørgselslog (slow_query_log = 1) og tjekke, hvilke udsagn der regelmæssigt overskrider tærsklen, fordi det ofte er her, den sande Bremser og Låse. Jeg bruger EXPLAIN til at opdage manglende indekser, ugunstige join-sekvenser eller brug af filesort/temporary, hvilket indikerer et behov for optimering. I spidsbelastningsperioder tjekker jeg med VIS PROCESLISTE, om forbindelser venter på hinanden, og med VIS VARIABLER LIKE '%timeout%', om sessionsindstillingerne er anderledes end forventet. I PHP ser jeg på max_udførelsestid; Hvis værdien er for lille, afsluttes scriptet, selv om databasen stadig beregner. For at få en meningsfuld sammenligning kører jeg de samme forespørgsler lokalt mod en kopi og tjekker, om caching, mindre datamængder eller andre buffere forvrænger billedet.
Tydelig afgrænsning af timeouts for webserver, proxy og klient
Jeg adskiller nøje MySQL-timeouts fra web/proxy- og klientgrænser, så de ikke bliver fordrejet det forkerte sted. I Nginx, for eksempel. proxy_read_timeout, fastcgi_read_timeout og keepalive_timeout ventetiderne for upstreams; i Apache Timeout og ProxyTimeout relevant. PHP-FPM afslutter anmodninger via request_terminate_timeout, selv om MySQL stadig beregner. I HAProxy-indflydelse timeout-klient, timeout server og timeout tunnel lange forbindelser. På klientsiden sætter jeg eksplicit tidsgrænser, så de ikke nedarves implicit:
// PHP PDO
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_TIMEOUT => 5, // sekunder til etablering af forbindelse
PDO::ATTR_PERSISTENT => false
]);
// mysqli
$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); // connect_timeout
$mysqli->options(MYSQLI_OPT_READ_TIMEOUT, 10); // net_read_timeout (klient-side)
$mysqli->real_connect($host, $user, $pass, $db);
// Node.js (mysql2)
const pool = createPool({
host, bruger, adgangskode, database,
connectionLimit: 20, waitForConnections: true, queueLimit: 100,
connectTimeout: 7000, acquireTimeout: 10000, enableKeepAlive: true
});
Vigtigt: Summen af webserver-, app- og DB-timeout må ikke resultere i en „sandwich“, hvor det ydre lag (f.eks. Nginx) afsluttes tidligere end de indre lag (app/DB). Jeg justerer værdierne, så fejl kan tildeles tydeligt.
Målrettet brug af performance schema og sys schema
Performance-skemaet og sys-skemaet giver mig reproducerbar indsigt ud over den langsomme forespørgselslog. Jeg aktiverer de relevante instrumenter og analyserer hotspots via digest:
-- Top statements efter 95. percentil
SELECT * FROM sys.statements_with_runtimes_in_95th_percentile
ORDER BY avg_timer_wait DESC LIMIT 20;
-- Aktive ventehændelser (låse, I/O, mutex)
VÆLG EVENT_NAME, SUM_TIMER_WAIT, COUNT_STAR
FROM performance_schema.events_waits_summary_global_by_event_name
ORDER BY SUM_TIMER_WAIT DESC LIMIT 20;
-- Nuværende „hængende“ udsagn
SELECT THREAD_ID, DIGEST_TEXT, TIMER_WAIT, CURRENT_SCHEMA
FROM performance_schema.events_statements_current
HVOR TIMER_WAIT IKKE ER NULL;
Det giver mig mulighed for at se, om timeouts med større sandsynlighed kommer fra I/O-ventetider, låsekæder eller CPU-intensive planer. Jeg tjekker også sys.user_summary og sys.host_summary, for at indsnævre genkendelige outliers efter konto/vært. Det forhindrer mig i symptomatisk at „forlænge“ timeouts, selvom det faktisk er låse eller I/O, der er flaskehalsen.
Optimale timeout-værdier efter scenarie
Jeg tilpasser timeouts til den tilsigtede brug, fordi interaktivitet, jobkørselstider og Forsinkelse og datamængde varierer meget. Webapplikationer med mange korte forespørgsler har gavn af mindre tomgangstimeouts, så puljen tømmes, og nye brugere får forbindelse med det samme. Databehandling med timelange rapporter har brug for mere generøse grænser, ellers ender vigtige jobs i timeout. Ved høj latenstid øger jeg connect_timeout moderat, så oprettelsestider for forbindelser ikke fejlagtigt vises som fejl. Følgende tabel giver stabile startværdier, som jeg derefter finjusterer ved hjælp af reelle målte værdier.
| Indstilling | Web-apps med høj trafik | Databehandling | Hint |
|---|---|---|---|
| vent_timeout | 60–300 s | 3600-7200 s | Kortere for mange brugere, længere for batchjobs |
| interaktiv_timeout | 1800 s | 7200 s | Til CLI/konsol, sjældent kritisk til web |
| connect_timeout | 5-10 s | 10-20 s | Øges moderat med høj latenstid |
| innodb_lock_wait_timeout | 10-30 s | 50-120 s | Afhængig af transaktionens varighed |
Connection pooling og tomgangstider
En korrekt konfigureret pool forhindrer inaktive forbindelser og sikrer, at forespørgsler hurtigere sendes videre til en ledig forbindelse. Ressource og Forbindelse kommer. Jeg sætter puljens idle timeout til ca. 10-15 % under MySQL wait_timeout, så sessioner lukkes på en ordentlig måde, før de udløber. Puljen begrænser også samtidige forbindelser, hvilket forhindrer overløb på delte servere. For WordPress, Nextcloud og lignende værktøjer overvåger jeg inaktiviteten efter login-faser og opsætter poolede forbindelser, så de ikke dør for tidligt. Jeg har opsummeret mere baggrundsinformation og praktiske eksempler her: Connection pooling i hosting.
Hold låse, deadlocks og transaktioner korte og præcise
Mange timeouts skyldes lange transaktioner og låsekæder. Jeg holder transaktionerne små, læser data uden låse først og åbner kun skrivetransaktionen umiddelbart før opdateringen/indsættelsen. I tilfælde af venteproblemer tjekker jeg innodb_lock_wait_timeout og frem for alt deadlocks:
-- Deadlocks og InnoDB-status
VIS MOTOR INNODB STATUS\G
-- Se aktive låse (MySQL 8+)
SELECT * FROM performance_schema.data_locks\G
SELECT * FROM performance_schema.data_lock_waits\G
Jeg undgår autocommit-uvenlige mønstre (f.eks. lange åbne sessioner med „glemte“ cursorer). Jeg sørger for, at isolations- og skrivemønstre matcher (f.eks. REPEATABLE READ vs. READ COMMITTED), og at sekundære processer (rapporter, eksport) ikke har unødvendigt lange låse. Jeg løser deadlocks ved hjælp af genforsøgslogik i appen, men aldrig ved blindt at øge timeouts.
Gør forespørgsler hurtigere: Indekser og joins
Jeg accelererer forespørgsler først med passende Indekser og slankere Tilslutter sig, før jeg øger timeouts. I EXPLAIN forventer jeg, at indekset bruges til filtre og sortering; hvis ikke, tilføjer jeg nøglen specifikt eller ændrer betingelsen. I store tabeller gemmer jeg ikke brede TEXT/BLOB-felter i samme adgangssti, hvis de er irrelevante for forespørgslen. Jeg tjekker også, om en LEFT JOIN virkelig er nødvendig, eller om en INNER JOIN er tilstrækkelig, da det reducerer resultatsættet. Disse trin reducerer kørselstiden mærkbart, og poolen forbliver tilgængelig.
PHP-, Node- og WordPress-tuning i praksis
I PHP øger jeg for lange rapporter max_udførelsestid moderat og forhindre annulleringer, der ligner databasefejl, men er forårsaget af scriptet. ligge. Hvor det er muligt, aktiverer jeg automatiske genforbindelser i driveren eller håndterer fejl, så et nyt forbindelsesforsøg starter rent. I Node.js opretholder jeg keep-alive, poolstørrelser og inaktivitetstider baseret på reelle latency- og throughput-målinger. Med WordPress er jeg opmærksom på caching, magre plugins og cron-jobs uden for spidsbelastningsperioder. Det holder MySQL-belastningen lav, og timeouts er sjældne.
Hold øje med netværksstien, DNS og TLS
Jeg tjekker hele vejen mellem appen og databasen: DNS-opløsning, routing, firewalls, NAT og TLS-handshakes. Hvis det er muligt, bruger jeg stabile IP'er eller interne DNS'er med korte, men ikke for aggressive TTL'er. Forhindret på serversiden skip_name_resolve dyre reverse lookups (forsigtighed i delte miljøer). Med TLS er jeg opmærksom på genoptagelse af sessioner og holder handshake-overheadet lavt. TCP-Keepalive hjælper med at genkende døde forbindelser hurtigere; på OS-niveau keepalive_time og keepalive_intvl Jeg aktiverer Keep-Alive i driveren i appen. I cloud-opsætninger tager jeg højde for NAT idle timeouts, så poolede forbindelser ikke „lydløst“ bliver afviklet, mens appen stadig anser dem for at være aktive.
Grænser og forbindelsesnumre i hosting
Delt hosting begrænser ofte samtidige forbindelser, hvilket betyder, at på trods af korte køretider i Stikord eller Fejl køre. Jeg sætter app-puljen op, så den respekterer disse øvre grænser og genkender overløb tidligt i overvågningen. Hvis antallet af 500-fejl stiger, tjekker jeg forholdet mellem max_connections, poolstørrelse og timeouts. Hvis optimering ikke nytter, taler jeg med udbyderen om passende grænser eller overvejer større planer (vServer, dedikeret DB). Du kan finde en kompakt fejlfindingsguide her: Forbindelsesgrænser og 500 fejl.
Vælg ressourcebudget og max_connections realistisk
Hver forbindelse koster RAM: Sorterings-, join- og læsebuffere bruges pr. tråd. Jeg planlægger derfor max_forbindelser ikke efter spidsbelastning, men efter tilgængelig hukommelse. For mange samtidige tråde genererer kontekstskift og I/O-pres, hvilket har en tendens til at fremme timeouts. Jeg holder tråd_cache_størrelse og table_open_cache så forbindelses- og tabelændringer ikke er unødigt dyre. Stor max_tilladt_pakke-Jeg sætter kun høje værdier, hvor eksport/uploads har brug for det - globalt set bruger for store pakker RAM og kan i kombination med mange forbindelser forårsage flaskehalse.
Replikering, failover og læseskalering
I replikerede opsætninger tjekker jeg, om appen reagerer hensigtsmæssigt i tilfælde af failover eller replikaforsinkelse. Jeg bruger læsereplikaer til læsebelastninger, men er opmærksom på forsinkelser: en for lille net_read_timeout eller app-timeout kan fortolke lange replikeringssvar som fejl. Jeg implementerer sundhedstjek og en backoff på disconnects i stedet for aggressive retries. Ved opdeling i læsning og skrivning sørger jeg for, at transaktionsmæssigt konsistente læseanmodninger ikke fejlagtigt går til forsinkede replikaer - ellers opstår der tilsyneladende „timeouts“, som i virkeligheden skyldes, at man venter på nye data.
Vedligeholdelse, sikkerhedskopiering og DDL uden overraskelser
Backups, online DDL og indeksopbygning kan øge I/O og låse. Jeg planlægger sådant arbejde uden for spidsbelastningsperioder og bruger online-algoritmer, hvor det er muligt. Under DDL tjekker jeg innodb_lock_wait_timeout konservativt, så produktionstransaktioner ikke blokerer for evigt. Jeg måler I/O-udnyttelsen under backups; hvis læsehastigheden og bufferpuljens gennemløb kolliderer, stiger svartiderne og downstream-timeout-raten. Også FLUSH-TABELLER MED LÆSELÅS Jeg bruger det kun selektivt, da det kan blokere globalt.
Overvågning af nøgletal og målværdier
Jeg definerer SLO'er og måler dem konsekvent: p95/p99-latency for de vigtigste forespørgsler, fejlrate efter type (connect vs. command timeout) og udnyttelse. Vigtige målinger omfatter. Tråde_løber (hold kort), Tråde_forbundet (justering af puljestørrelse), Afbrudte_forbindelser og Connection_errors_* (netværks-/auth-problemer), og Handler_læse_* (indeksudnyttelse). En konstant høj andel af „fulde tabelscanninger“ hænger ofte sammen med timeout-toppe. Jeg bruger også en oversigt til at vise de største forbrugere af CPU, I/O og ventetid for at kunne anvende optimeringer der, hvor de virkelig reducerer timeout-raten.
Sikre timeouts vs. DoS-risiko
Jeg afbalancerer timeouts mellem brugervenlighed og beskyttelse, så hverken Misbrug stadig Afbrydelser dominerer. Med høj netværkslatens øger jeg forsigtigt connect_timeout, så forbindelserne ikke bryder sammen for tidligt. I sårbare opsætninger sænker jeg den samme værdi, så angreb med lange håndtryk har mindre effekt. Ved uploads eller store resultatsæt øger jeg max_allowed_packet, så overførsler ikke afbrydes. Jeg gennemfører altid disse indgreb ved at overvåge fejlraten og svartiderne, så jeg kan se effekterne og bivirkningerne med det samme.
Undgå almindelige fejl
Jeg øger aldrig timeouts blindt, fordi der åbnes lange ventevinduer Møder og Låse akkumulere. I stedet løser jeg langsomme forespørgsler først og justerer derefter grænseværdierne minimalt. Jeg adskiller lange transaktioner, sætter fornuftige kontrolpunkter og tjekker, om innodb_lock_wait_timeout matcher skrivemønsteret. Hvis der er brug for store pakker, øger jeg kun max_allowed_packet så meget som nødvendigt og tester upload-, eksport- og importstier på en realistisk måde. Med løbende overvågning opdager jeg tilbagefald tidligt og holder systemet pålideligt.
Resumé: Sådan holder du forbindelserne pålidelige
Jeg starter med en klar diagnose, adskiller forbindelsesfejl fra kommando-timeouts og tjekker Logfiler og Forespørgsler i den langsomme forespørgselslog. Derefter optimerer jeg indekser og joins, sætter puljens idle-tid til lige under wait_timeout og sætter realistiske connect-, read- og write-timeouts. Jeg vælger korte idle-værdier for webtrafik og længere grænser for batchjobs; jeg tester begge varianter under belastning. Jeg harmoniserer PHP/node-grænser og MySQL-parametre, så appen og databasen trækker vejret i samme tidsrum. Det reducerer antallet af fejl, forespørgsler forbliver hurtige, og MySQL-timeouts mister deres virkning.


