sql >> Databasteknik >  >> RDS >> Mysql

mysql_ping hänger med Amazon RDS

Jag kan inte hitta ett citat i dokumentationen, men min erfarenhet tyder på att nätverksinfrastrukturen för EC2 i allmänhet (som skulle inkludera RDS och troligen alla andra AWS-tjänster som körs på virtuella maskiner som tillhandahålls per kund, om inte alla AWS, och verkar absolut inte vara strikt begränsad till "EC2-instanser") implementerar stateful paketinspektion och kommer att "glömma" att en TCP-anslutning är giltig efter några minuter av absolut ledighet... vilket orsakar beteendet du beskriver.

Maskinerna i båda ändarna av anslutningen kan vara övertygade om att anslutningen fortfarande finns där, men nätverket kommer inte att tillåta trafiken att passera mellan dem, eftersom TCP-sessioner i en SPI-miljö inte upptäcks, de skapas och kan bara skapas när nätverket ser anslutningen i början (SYN, SYN/ACK, ACK ). Jag stötte ursprungligen på det här problemet med MySQL-servrar i EC2 (inte RDS) men skulle bli mycket förvånad om den underliggande orsaken inte är densamma.

Det finns två möjliga sätt att komma runt detta.

Om din PHP-maskin är Linux, konfigurera kärnan för att hålla anslutningarna vid liv på lager 4. Denna förändring kommer att vara osynlig för dig i den meningen att dessa keepalives inte kommer att ändra värdet i Time kolumnen i SHOW PROCESSLIST för anslutningar i Sleep eftersom det inte kommer att återställa den tid som anslutningen har varit inaktiv vid lager 7 ... men den bör undvika timeouts från AWS-infrastrukturen om biblioteken som hanterar MySQL-anslutningarna ställer in socketalternativen korrekt för att dra fördel av det.

http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive .html förklarar hur man ställer in detta live och hur man gör det beständigt vid omstarter.

Om det misslyckas är det andra alternativet att tvinga MySQL att stänga anslutningen tidigare än nätverkets timeout så att PHP-maskinen omedelbart kommer att känna igen att den försöker prata på ett slutet uttag. Det kan låta kontraintuitivt att förkorta en timeout snarare än att förlänga den, men att förkorta timeouten bör göra att ditt pingtest misslyckas mycket snabbt om en session har varit inaktiv för länge, vilket också (i huvudsak) "löser" problemet, förutsatt att du är förståndig i PHP-klientbiblioteket. När din applikation väl är upptagen kommer anslutningarna förmodligen sällan att vara inaktiva tillräckligt länge för att nå timeout.

MySQL Server har två olika tidsgränsinställningar för vilotid: wait_timeout (för icke-interaktiva sessioner, d.v.s. anslutningar från kod, som PHP) och interactive_timeout (från frågewebbläsare och kommandoradsklienten) men servern vet bara skillnaden eftersom klientbiblioteket måste meddela servern vilken typ av anslutning den upprättar. Förutsatt att ditt klientbibliotek använder rätt inställning, sedan wait_timeout är den du letar efter. Att ställa in detta till ett värde under 900 bör lösa problemet om ändring av TCP Keepalive-inställningarna i Linux-kärnan inte gör det. Observera dock att efter att ändringen har gjorts kommer endast framtida anslutningar att påverkas -- anslutningar som redan upprättats när ändringen görs kommer fortfarande att köras med det aktuella värdet, som är standard på 8 timmar (28800 sekunder). Dessa är konfigurerbara i RDS-parametergruppen för din instans.

Det finns tips om liknande beteende i AWS-dokumenten här , tillsammans med Windows registerinställningar som måste justeras för att ändra TCP keepalives om du kör PHP-servern på Windows, istället för Linux, som jag antog ovan... även om artikeln specifikt handlar om Redshift och anslutningar externt till EC2 verkar det fortfarande validera den underliggande frågan som diskuterats ovan.




  1. Fel 1215:Det går inte att lägga till begränsning av främmande nyckel

  2. Rails:Hur man delar skriv/läs-fråga över master/slav-databas

  3. Snabbaste sättet att subset - data.table vs. MySQL

  4. SLOPP alla främmande nycklar i MYSQL-databasen