sql >> Database teknologi >  >> RDS >> Mysql

mysql_ping hænger sammen med Amazon RDS

Jeg kan ikke finde et citat i dokumentationen, men min erfaring tyder på, at netværksinfrastrukturen i EC2 generelt (som vil omfatte RDS og sandsynligvis enhver anden AWS-tjeneste, der kører på virtuelle maskiner, der leveres pr. kunde, hvis ikke alle AWS, og ser bestemt ikke ud til at være strengt begrænset til "EC2-forekomster") implementerer stateful pakkeinspektion og vil "glemme" at en TCP-forbindelse er gyldig efter et par minutters absolut tomgang... hvilket forårsager den adfærd du beskriver.

Maskinerne i begge ender af forbindelsen kan være overbevist om, at forbindelsen stadig er der, men netværket vil ikke tillade trafikken at passere mellem dem, fordi TCP-sessioner i et SPI-miljø ikke opdages, de er oprettet og kan kun oprettes, når netværket ser forbindelsen helt i begyndelsen (SYN, SYN/ACK, ACK ). Jeg stødte oprindeligt på dette problem med MySQL-servere i EC2 (ikke RDS), men ville blive meget overrasket, hvis den underliggende årsag ikke er den samme.

Der er to mulige tilgange til at omgå dette.

Hvis din PHP-maskine er Linux, konfigurer kernen til at holde forbindelserne i live på lag 4. Denne ændring vil være usynlig for dig i den forstand, at disse keepalives ikke ændrer værdien i Time kolonne i SHOW PROCESSLIST for forbindelser i Sleep fordi den ikke vil nulstille den tid, forbindelsen har været inaktiv på lag 7 ... men den burde undgå timeouts fra AWS-infrastrukturen, hvis bibliotekerne, der administrerer MySQL-forbindelserne, indstiller socket-indstillingerne korrekt for at drage fordel af det.

http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive .html forklarer, hvordan du opsætter dette live, og hvordan du gør det vedvarende på tværs af genstarter.

Hvis det ikke lykkes, er den anden mulighed at tvinge MySQL til at lukke forbindelsen snarere end netværkets timeout så PHP-maskinen med det samme vil genkende, at den forsøger at tale på en lukket stikkontakt. Det kan lyde kontraintuitivt at forkorte en timeout i stedet for at forlænge den, men en afkortning af timeouten burde få din ping-test til at mislykkes meget hurtigt, hvis en session har været inaktiv for længe, ​​hvilket også (i det væsentlige) "løser" problemet under forudsætning af fornuft i PHP-klientbiblioteket. Når først din applikation er mere travl, vil forbindelserne formodentlig sjældent være inaktive længe nok til at nå timeout.

MySQL Server har to forskellige indstillinger for inaktiv timeout: wait_timeout (til ikke-interaktive sessioner, dvs. forbindelser fra kode, som PHP) og interactive_timeout (fra forespørgselsbrowsere og kommandolinjeklienten), men serveren kender kun forskellen, fordi klientbiblioteket skal give serveren besked om, hvilken type forbindelse den etablerer. Forudsat at dit klientbibliotek bruger den korrekte opsætning, så wait_timeout er den du leder efter. Indstilling af dette til en værdi under 900 burde løse problemet, hvis ændring af TCP Keepalive-indstillingerne i Linux-kernen ikke gør det. Bemærk dog, at efter at ændringen er foretaget, vil kun fremtidige forbindelser blive påvirket - forbindelser, der allerede er etableret, når ændringen er foretaget, vil stadig køre med den aktuelle værdi, som er standard til 8 timer (28800 sekunder). Disse kan konfigureres i RDS-parametergruppen for din forekomst.

Der er hints om lignende adfærd i AWS-dokumenterne her , sammen med Windows registreringsdatabasen indstillinger, der skal justeres for at ændre TCP keepalives, hvis du kører PHP serveren på Windows, i stedet for Linux, som jeg antog ovenfor... selvom artiklen specifikt handler om Redshift og forbindelser eksternt til EC2 ser det stadig ud til at validere det underliggende problem som diskuteret ovenfor.




  1. Indlæs data fra database + ajax + php

  2. Sådan viser du tabeldata mere tydeligt i oracle sqlplus

  3. SQL:forskel mellem to datoer

  4. Udfyldning af en rullemenu med databaseresultater i Laravel 4