sql >> Database >  >> RDS >> Mysql

mysql_ping loopt vast bij Amazon RDS

Ik kan geen verwijzing vinden in de documentatie, maar mijn ervaring suggereert dat de netwerkinfrastructuur van EC2 in het algemeen (waaronder RDS en waarschijnlijk elke andere AWS-service die draait op virtuele machines die per klant, zo niet alle AWS, en het lijkt zeker niet strikt beperkt te zijn tot "EC2-instanties") implementeert stateful pakketinspectie en zal "vergeten" dat een TCP-verbinding geldig is na een paar minuten van absolute nietsdoen... wat het gedrag veroorzaakt dat u beschrijft.

De machines aan beide uiteinden van de verbinding zijn er misschien van overtuigd dat de verbinding er nog steeds is, maar het netwerk laat het verkeer niet tussen hen door, omdat TCP-sessies in een SPI-omgeving niet worden ontdekt, ze worden gemaakt en alleen kunnen worden gemaakt wanneer het netwerk de verbinding helemaal aan het begin ziet (SYN, SYN/ACK, ACK ). Ik kwam dit probleem oorspronkelijk tegen met MySQL-servers in EC2 (niet RDS), maar het zou me verbazen als de onderliggende oorzaak niet dezelfde is.

Er zijn twee mogelijke benaderingen om dit te omzeilen.

Als uw PHP-machine Linux is, configureert u de kernel om de verbindingen op laag 4 actief te houden. Deze wijziging is voor u onzichtbaar in die zin dat deze keepalives de waarde in de Time niet veranderen. kolom in SHOW PROCESSLIST voor verbindingen in Sleep omdat het de tijd dat de verbinding inactief is geweest op laag 7 niet zal resetten ... maar het zou de time-outs van de AWS-infrastructuur moeten vermijden als de bibliotheken die de MySQL-verbindingen beheren de socket-opties correct instellen om ervan te profiteren.

http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive .html legt uit hoe je dit live kunt instellen en hoe je het persistent kunt maken tijdens het opnieuw opstarten.

Als dat niet lukt, is de andere optie om MySQL te dwingen de verbinding eerder te sluiten dan de netwerktime-out zodat de PHP-machine onmiddellijk zal herkennen dat hij probeert te praten op een gesloten socket. Het klinkt misschien contra-intuïtief om een ​​time-out te verkorten in plaats van deze te verlengen, maar als u de time-out verkort, zou uw ping-test zeer snel moeten mislukken als een sessie te lang inactief is geweest, wat ook (in wezen) het probleem "oplost", ervan uitgaande dat u gezond verstand hebt. in de PHP-clientbibliotheek. Als uw applicatie eenmaal drukker is, zullen de verbindingen vermoedelijk zelden lang genoeg inactief zijn om de time-out te bereiken.

MySQL Server heeft twee verschillende time-outinstellingen voor inactiviteit: wait_timeout (voor niet-interactieve sessies, d.w.z. verbindingen van code, zoals PHP) en interactive_timeout (van querybrowsers en de opdrachtregelclient), maar de server kent het verschil alleen omdat de clientbibliotheek de server moet laten weten welk type verbinding tot stand wordt gebracht. Ervan uitgaande dat uw klantenbibliotheek de juiste instellingen gebruikt, dan wait_timeout is degene die je zoekt. Door dit in te stellen op een waarde onder 900 zou het probleem moeten worden opgelost als het wijzigen van de TCP keepalive-instellingen in de Linux-kernel dat niet doet. Houd er echter rekening mee dat na het aanbrengen van de wijziging alleen toekomstige verbindingen worden beïnvloed -- verbindingen die al tot stand zijn gebracht wanneer de wijziging wordt aangebracht, zullen nog steeds worden uitgevoerd met de huidige waarde, die standaard 8 uur (28800 seconden) is. Deze zijn configureerbaar in de RDS-parametergroep voor uw exemplaar.

Er zijn hints van soortgelijk gedrag in de AWS-documenten hier , samen met de Windows-registerinstellingen die moeten worden aangepast om TCP keepalives te wijzigen als u de PHP-server op Windows gebruikt, in plaats van Linux, zoals ik hierboven aannam ... hoewel het artikel specifiek gaat over Redshift en externe verbindingen naar EC2 het lijkt nog steeds het onderliggende probleem te valideren, zoals hierboven besproken.




  1. MySQL-referenties verbergen in toepassing

  2. Identiteitsachtige kolom maar gebaseerd op Group By-criteria

  3. Hoe Joda-Time te gebruiken met java.sql.Timestamp

  4. CASE-instructie in SQL WHERE-clausule