Uitputting van databaseverbindingen in PHP uit zich vaak in intermitterende fouten: sommige requests mislukken, andere blijven wachten en het probleem wordt erger tijdens piekuren. De verbindingslimiet verhogen kan verlichting bieden, maar kan de overbelasting ook verplaatsen naar de databaseserver. De oplossing begint met vaststellen welke resource uitgeput raakt en waardoor verbindingen bezet blijven.
Herken de symptomen en baken de storing af

Let op fouten zoals ‘too many connections’, fouten bij het openen van een verbinding, time-outs of requests die de maximale uitvoeringstijd overschrijden. Vergelijk hoe vaak ze voorkomen met het verkeer en andere indicatoren: applicatielatentie, CPU- en geheugengebruik, databasefouten en de duur van requests.
Het verschil tussen hoge en lage belasting geeft een eerste aanwijzing. Als fouten tijdens pieken optreden en verdwijnen wanneer het verkeer afneemt, kan er sprake zijn van een concurrencylimiet. Blijven ze optreden bij weinig requests, onderzoek dan vastgehouden verbindingen, geblokkeerde processen, langdurige query's of een onbereikbare database. Bevestig ook of andere services dezelfde limiet delen: PHP is niet noodzakelijk de enige gebruiker.
Onderscheid uitgeputte verbindingen van trage query's en blokkeringen
Dit zijn verwante, maar niet gelijkwaardige problemen. Een uitgeputte verbinding doet zich voor wanneer er geen capaciteit beschikbaar is om een nieuwe verbinding te openen. Een trage query houdt een verbinding langer bezet en kan bij opeenhoping uitputting veroorzaken. Bij een blokkering wacht een query totdat een andere transactie resources vrijgeeft. Onbeschikbaarheid betekent dat de database door een bredere oorzaak geen verbindingen kan accepteren of verwerken.
Bekijk de foutmelding en het punt waarop de fout optreedt. Mislukt het request voordat een query wordt uitgevoerd, controleer dan het aanmaken van verbindingen en of de limiet is bereikt. Lukt het verbinden wel, maar duurt het daarna lang, inspecteer dan de lopende query's, hun uitvoeringstijden, wachttijden en openstaande transacties. Concludeer niet dat er ‘meer verbindingen nodig zijn’ alleen omdat de applicatie traag reageert: een hoger maximum verhelpt geen dure query of blokkering.
Breng PHP-concurrency in verband met de databaselimiet
In het gebruikelijke PHP-model waarin processen requests afhandelen, kan elk proces een verbinding nodig hebben terwijl het databasewerk uitvoert. De potentiële vraag hangt af van het aantal processen dat gelijktijdig actief kan zijn, het aantal verbindingen dat elk proces opent en hoe lang die verbindingen openblijven. Houd ook rekening met verbindingen van achtergrondtaken, consolecommando's en andere services.
Maak een conservatieve schatting van het worstcasescenario: vermenigvuldig de maximaal effectieve concurrency van elke procesgroep met het aantal gelijktijdige verbindingen dat elk proces kan gebruiken, en tel de gebruikers op die de database delen. Vergelijk dit met de ingestelde limiet en houd ruimte vrij voor beheeractiviteiten en variaties in belasting. Ga er niet van uit dat elk request altijd gelijkstaat aan één verbinding: de levenscyclus hangt af van de databaseclient, de configuratie en het gebruikspatroon.
Controleer ook hoe de belasting wordt verdeeld. Meerdere PHP-instanties kunnen hun lokale limieten respecteren en gezamenlijk toch het databasequotum overschrijden. Horizontaal schalen verhoogt de potentiële concurrency; het is geen veilige mitigatie zolang het totale aantal verbindingen niet opnieuw wordt berekend.
Meet vanaf beide kanten
Breng applicatie- en databasemetrics met tijdstempels met elkaar in verband. Registreer in PHP de duur van requests, verbindingsfouten, time-outs en het aantal bezette processen. Controleer in de database het aantal actieve en maximale verbindingen, afwijzingen, lopende query's, de leeftijd van sessies en de wachttijden die de database-engine beschikbaar stelt.
Voorkom dat je inloggegevens, volledige connection strings of gevoelige querygegevens registreert. Als de database-engine sessies en statussen kan identificeren, gebruik die informatie dan om een inactieve verbinding te onderscheiden van een actieve query of een openstaande transactie. Vergelijk de logs van beide kanten: een gelijktijdige piek in verbindingen en bezette PHP-processen wijst op concurrency; veel oude sessies of inactieve processen duiden mogelijk op vastgehouden verbindingen; enkele langdurige query's kunnen verklaren waarom het quotum geleidelijk wordt opgebruikt.
De instrumentatie moet antwoord geven op drie vragen: hoeveel verbindingen worden gebruikt, hoe lang blijven ze open en welk werk houdt ze bezet? Zonder die tijdlijn voegen limieten wijzigen of persistente verbindingen inschakelen extra variabelen toe en wordt het moeilijker de oorzaak te vinden.
Beoordeel persistente en langdurige verbindingen
Een persistente verbinding kan de kosten van herhaaldelijk verbindingen openen verlagen, vooral wanneer de omgeving processen tussen requests in stand houdt. Een verbinding die aan een proces gekoppeld blijft, kan echter ook een verbindingsslot bezet houden terwijl er geen query wordt uitgevoerd. Bij veel processen of meerdere instanties kan het totaal aan vastgehouden verbindingen de databaselimiet bereiken.
Controleer de werkelijke levenscyclus van het proces en de driver voordat je persistente verbindingen in- of uitschakelt. Verifieer hoe de sessie wordt hergebruikt en of de applicatie de verwachte status tussen requests herstelt, zoals transacties, sessievariabelen of specifieke verbindingsinstellingen. Persistente verbindingen zijn geen universele connection pool en garanderen geen lager verbruik; test ze onder representatieve belasting en observeer het maximale aantal verbindingen, de latentie en achtergebleven status.
Beperk de impact in de juiste volgorde en op basis van bewijs
- Beperk de concurrency. Pas het aantal PHP-processen of de paralleliteit van workers aan, zodat de gelijktijdige vraag past binnen het gedeelde quotum. Dit verlaagt de druk, maar kan de wachtrij en latentie verhogen als de capaciteit lager is dan de aanhoudende vraag.
- Geef resources vrij zodra ze niet meer nodig zijn. Sluit verbindingen expliciet als de library en het uitvoeringspatroon dit toelaten, en voorkom dat je ze openhoudt tijdens werk dat niets met de database te maken heeft. Houd er rekening mee dat het sluiten van een persistente verbinding niet noodzakelijk de fysieke verbinding op de server vrijgeeft: het resultaat hangt af van de driver en de levenscyclus van het proces. Controleer transacties die open blijven en foutpaden die de opruiming niet voltooien.
- Verkort de bezettingsduur. Analyseer trage query's, indexen, de omvang van resultaten en transacties. Een bewerking optimaliseren die een verbinding lang bezet houdt, kan de gelijktijdige vraag verlagen zonder de limiet te verhogen.
- Pas limieten pas aan nadat je hebt gemeten. Het maximum verhogen kan redelijk zijn als er voldoende CPU- en geheugencapaciteit overblijft in de database en het nieuwe worstcasescenario duurzaam is. Anders kunnen meer werkzaamheden zich opstapelen en kan de overbelasting verergeren.
Voer steeds één wijziging tegelijk door, leg de vorige toestand vast en bepaal wanneer je de wijziging terugdraait. Als het systeem al problemen ondervindt, kan de concurrency tijdelijk verlagen veiliger zijn dan alle processen tegelijk opnieuw starten, wat een nieuwe piek in verbindingen kan veroorzaken.
Wanneer een connection pool of proxy overwegen
Een connection pool of proxy kan fysieke verbindingen hergebruiken en het aantal verbindingen naar de database-engine beheersen. Dat is nuttig wanneer veel applicatieprocessen kortstondige verbindingen gebruiken. Het elimineert gelijktijdig werk niet en maakt query's niet sneller; het voegt een extra laag toe met eigen capaciteit, wachtrijen, limieten en bedrijfsmodi.
Controleer voordat je zo'n oplossing invoert de compatibiliteit met de database-engine, de PHP-driver, authenticatie, transacties en sessiestatus. Bekijk hoe de oplossing omgaat met langlopende verbindingen, reconnects en proxyproblemen, en definieer metrics en procedures voor het beheer ervan. Valideer de configuratie met tests die de werkelijke concurrency weerspiegelen: een configuratie die in ontwikkeling werkt, kan zich onder belasting anders gedragen.
Bereid herstel voor en voorkom herhaling

Stel alerts in voor verbindingen die de limiet naderen, afwijzingen, queryduur en overbelasting van PHP-processen. Voeg een representatieve loadtest toe met instanties, achtergrondtaken en andere gebruikers; controleer het worstcasescenario, niet alleen het gemiddelde. Houd een operationele procedure bij waarin staat wat je moet meten, hoe je de concurrency beperkt, wie het quotum mag wijzigen en wanneer je de wijziging moet terugdraaien.
Onderzoek na herstel van de service de gebeurtenissen die aan het incident voorafgingen: veranderingen in verkeer, deployments, nieuwe query's, groei van het aantal processen of fouten bij het opruimen. Het doel is oorzaak en gevolg met gegevens aan elkaar te koppelen. Tonen de metrics dat verbindingen worden vastgehouden, corrigeer dan hun levenscyclus; is de queryduur de belangrijkste factor, optimaliseer ze dan; overschrijdt de legitieme concurrency de capaciteit, schaal dan op en begrens die met een expliciet verbindingsbudget.



