Verkeerspiek: tweehonderd actieve PHP-FPM-processen, elk opent een nieuwe verbinding met de database. PostgreSQL bereikt de limiet van honderd verbindingen – te veel verbindingen. Paniek: we verhogen de limiet naar vijfhonderd. Het databasegeheugen explodeert, het systeem schakelt over naar schijf en de prestaties verslechteren.
PgBouncer arriveert: tweehonderd applicatieclients, dertig echte PostgreSQL-verbindingen. De crisis leek opgelost – totdat dertig gelijktijdige langzame verzoeken de hele pool dertig seconden lang blokkeerden. De aanvraag verloopt massaal. De pool heeft de verbindingslimiet verborgen, niet de gelijktijdige verwerkingscapaciteit van de database.
Verbindingspooling lost open kosten op. Het lost geen volledige tabelscans op. Slecht aangepast, voegt het een onzichtbare wachtrij toe voor een reeds verstikte basis.
Waar het zwembad in de stapel moet worden geplaatst
Afhankelijk van uw omgeving verandert de tool; het principe blijft hetzelfde: een laag tussen de applicatieprocessen en de basis.
| Stapel | Gemeenschappelijk instrument |
|---|---|
| PHP / Python / Knooppunt → PostgreSQL | PgBouncer vóór PostgreSQL |
| MySQL | ProxySQL, MariaDB MaxScale of applicatiepool |
| Serverloze functies | Verplichte pooler (beheerde proxy) |
| PHP zonder pooler | Aanhoudende verbindingen — risico op zombieverbindingen |
Typische architectuur:
[PHP-FPM × N] → [PgBouncer:6432] → [PostgreSQL:5432]
Verdubbel de pool-applicatie en PgBouncer niet zonder de keten te begrijpen: geneste pools zorgen voor latentie en impasses.
Maatvoering: begin bij de basis, niet bij de toepassing
Voor PostgreSQL wordt het optimale aantal actieve verbindingen gemeten onder reële belasting – niet op een theoretisch spreadsheet. In de praktijk is een default_pool_size tussen de twintig en vijftig vaak voldoende voor een MKB-bedrijf; max_client_conn moet de som van applicatieprocessen omvatten.
| Symptoom | Waarschijnlijke oorzaak |
|---|---|
| Time-out van bestandspool | Pool te klein of vragen te lang |
| Lage basisprocessor, app-time-outs | Zoekopdrachten geblokkeerd door vergrendelingen |
| “Te veel verbindingen” | Zwembadbypass of verkeerde configuratie |
Transactiemodus: winst en valkuilen
Transactiepooling recycleert de PostgreSQL-verbinding na validatie. Gebruik deze modus niet met sessiegebonden voorbereide query's, persistente sessievariabelen of functies zoals luisteren en notificaties. De sessiemodus is veiliger om te migreren; transactiemodus na controle van uw gegevenstoegangslaag.
Op gedeelde MySQL-hosting zijn de verbindingen vaak beperkt tot tien of dertig: een pool aan de applicatiezijde is verplicht. Op beheerde PostgreSQL is soms een pooler inbegrepen: controleer uw aanbodlimieten en meet de wachtrij voordat u de hardware opschaalt.
In de praktijk verdwijnen de meeste ‘pool’-incidenten na optimalisatie van langzame queries: ontbrekende indexen, ongefilterde joins, te lange transacties. Het zwembad wordt dan een nuttige schokdemper in plaats van een glazen plafond.
De top: het zwembad verschuift van verzadiging
Correctievolgorde: langzame zoekopdrachten → pool → basisschaal. Het omkeren van de volgorde betekent dat je extra wachtrij en hardware moet betalen voor hetzelfde resultaat.
Beslis en ga vooruit zonder blinde vlek
Meet het aantal PostgreSQL- of MySQL-verbindingen op de huidige piek vóór eventuele wijzigingen. Implementeer PgBouncer of ProxySQL als uw applicatieprocessen de veilige max_connections aanzienlijk overschrijden. Stel pool_size in op basis van de werkelijke capaciteit van de database, niet op het aantal werknemers. Monitor wachtende klanten en de gemiddelde wachttijd. Analyseer de zwaarste queries parallel — zie EXPLAIN PostgreSQL en PHP-FPM saturation.
Veelgestelde vragen
Waarom PostgreSQL poolen?
Elke verbinding verbruikt geheugen; de pool multiplext honderden applicatieprocessen over minder serververbindingen.
Sessie versus transactiemodus PgBouncer?
De transactiemodus is efficiënter; de sessiemodus blijft beter compatibel met object-relationele mappingtools.
Hoe pool_size bepalen?
Begin met de capaciteit van de basisprocessor en meet de werkelijke belasting, niet het aantal applicatiewerknemers.
Overschrijft de pool de SQL-index?
Nee: langzame zoekopdrachten blijven traag als ze eenmaal zijn verbonden. Optimaliseer eerst zoekopdrachten.
De verbindingspool zorgt voor het openen en niet voor de query die de database verstikt zodra deze is verbonden.
