Poolningslägen för transaktioner kontra sessioner
Välj rätt PgBouncer-läge och lär dig vilka funktioner som slutar fungera vid transaktionspoolning.
Poolningslägen för transaktioner kontra sessioner är en gratis lektion i Prestandaoptimering och frågeoptimering i PostgreSQL på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Prestandaoptimering och frågeoptimering i PostgreSQL, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Prestandaoptimering och frågeoptimering i PostgreSQL innehåller totalt 4 lektioner.
Varför poolningslägen spelar roll
Varje PostgreSQL-backendprocess kostar minne (work_mem, katalogcachar, plancachar) och CPU. Några tusen overksamma klientanslutningar kan överbelasta en server även när ingenting körs.
PgBouncer sitter mellan applikationen och PostgreSQL och multiplexar många klientanslutningar över ett litet antal riktiga server-anslutningar. Inställningen pool_mode avgör när en serveranslutning lämnas tillbaka till poolen.
- session – serveranslutningen hålls under klientens hela session
- transaction – serveranslutningen hålls endast under en transaktion
- statement – serveranslutningen lämnas tillbaka efter varje sats
Poolningsläge för sessioner
Vid sessionpoolning tilldelas en klient en serveranslutning när den ansluter, och anslutningen lämnas tillbaka till poolen först när klienten kopplar från.
Detta är det säkraste läget: klienten får en dedikerad backend under hela sin livstid, så alla PostgreSQL-funktioner fungerar precis som vid en direktanslutning. Nackdelen är dålig återanvändning – en overksam men ansluten klient håller fortfarande en serveranslutning reserverad.
; PgBouncer config: pgbouncer.ini
[pgbouncer]
pool_mode = session
max_client_conn = 10000
default_pool_size = 20
[databases]
appdb = host=127.0.0.1 port=5432 dbname=appdbPoolningsläge för transaktioner
Vid transaktionspoolning tilldelas serveranslutningen endast under en enskild transaktion. Så snart transaktionen genomförs eller återställs går backend tillbaka till poolen och kan därefter betjäna en annan klient.
Det ger betydligt bättre återanvändning: tusentals till största delen overksamma klienter kan dela på en mycket liten pool, eftersom en serveranslutning bara lånas under aktivt arbete. Detta är det rekommenderade läget för webbappar med många kortlivade begäranden.
[pgbouncer]
pool_mode = transaction
max_client_conn = 10000
default_pool_size = 20
; 10000 clients multiplexed onto only 20 backendsDen centrala avvägningen
Valet står mellan återanvändning och funktionskompatibilitet:
- Session: full kompatibilitet, låg återanvändning av anslutningar.
- Transaction: hög återanvändning, men allt som är beroende av tillstånd utanför en transaktion kan sluta fungera.
Den viktiga insikten är att på transaktionsnivå kan på varandra följande transaktioner från samma klient hamna på olika backends. Allt som finns kvar på anslutningen mellan transaktioner är osäkert.
Det som går sönder: tillstånd på sessionsnivå
Eftersom en backend delas mellan klienter mellan transaktioner kan allt sessionsomfattande tillstånd som ställs in i en transaktion läcka till en annan klient eller gå förlorat.
Följande slutar ofta fungera med transaktionspoolning:
SET/SET SESSIONför GUC:er på sessionsnivå (t.ex.SET statement_timeout,SET search_pathutanför en transaktion)- Advisory-lås på sessionsnivå (
pg_advisory_lock) - Prenumerationer med
LISTEN/NOTIFY - Sessionsvariabler utan parametrar och markörer med
WITH HOLD
-- Unsafe in transaction pooling: runs in its own tx,
-- the GUC is reset before your next query reuses a backend
SET statement_timeout = '5s';
-- Session advisory lock may be acquired on one backend
-- and never matched by the unlock on another
SELECT pg_advisory_lock(42);Det som går sönder: förberedda satser
Namngivna förberedda satser lagras på en specifik backend. I transaktionsläge kan nästa körning hamna på en annan backend som aldrig har sett den förberedda satsen, vilket orsakar fel som prepared statement "sN" does not exist.
Möjliga åtgärder:
- Inaktivera förberedda satser på klientsidan eller använd enkelt/namnlöst protokoll.
- PgBouncer 1.21+ har stöd för
max_prepared_statements, som automatiskt spårar och förbereder namngivna satser på nytt för varje backend.
; PgBouncer 1.21+ : safely allow named prepared statements
; in transaction mode by tracking them per server connection
[pgbouncer]
pool_mode = transaction
max_prepared_statements = 200Behåll inställningarna i transaktionen
Om ni behöver en GUC som statement_timeout eller search_path vid transaktionspoolning ska ni begränsa den till transaktionen med SET LOCAL. Den gäller bara tills transaktionen avslutas, så den kan aldrig läcka till nästa klient på den backend-anslutningen.
Använd detta mönster i stället för ett fristående SET.
BEGIN;
SET LOCAL statement_timeout = '5s';
SET LOCAL search_path = analytics, public;
SELECT count(*) FROM orders WHERE created_at >= now() - interval '1 day';
COMMIT;Långa transaktioner binder upp poolen
Transaktionspoolning återanvänder bara backends mellan transaktioner. En långvarig fråga eller en fråga som är idle-in-transaction håller sin backend under hela tiden, precis som i sessionsläge.
Om många klienter håller transaktioner öppna töms den lilla poolen och nya begäranden hamnar i kö. Skydda er mot detta:
- Ange ett lågt värde för
idle_in_transaction_session_timeoutpå servern. - Håll transaktionerna korta; kör aldrig
BEGINoch vänta sedan på I/O på applikationssidan.
-- Server-side safety net (postgresql.conf or ALTER ROLE)
ALTER ROLE app_user SET idle_in_transaction_session_timeout = '10s';
-- Now an app that BEGINs and stalls gets its backend
-- reclaimed instead of starving the PgBouncer poolDimensionera default_pool_size
Vid transaktionspoolning är default_pool_size antalet riktiga backends per par av (databas, användare). Eftersom arbetet varvas behöver ni betydligt färre backends än klienter.
En vanlig utgångspunkt är ungefär antalet CPU-kärnor som är tillgängliga för frågor, inte antalet klienter. Om poolen dimensioneras för stort återskapas bara problemet med anslutningsstormar som ni använde PgBouncer för att undvika.
[pgbouncer]
pool_mode = transaction
default_pool_size = 20 ; ~ matches Postgres CPU capacity
min_pool_size = 5 ; keep warm backends ready
reserve_pool_size = 5 ; burst headroom
max_client_conn = 10000 ; how many apps can attachGranska poolens beteende
PgBouncer tillhandahåller en virtuell administratörsdatabas. Anslut till den och kör SHOW POOLS; för att se hur många klienter som är aktiva eller väntar samt hur många serveranslutningar som är aktiva eller overksamma, per pool.
Om cl_waiting konsekvent är större än noll står klienter i kö för en backend – höj antingen default_pool_size eller förkorta transaktionerna.
-- psql -p 6432 pgbouncer
SHOW POOLS;
-- columns: database | user | cl_active | cl_waiting
-- sv_active | sv_idle | sv_used | pool_mode
SHOW STATS; -- query/transaction throughput per databaseLägesöverskridanden per databas
Ni behöver inte välja ett enda läge globalt. Ange ett standardvärde för pool_mode och åsidosätt det per databas. En typisk uppdelning är:
- Den huvudsakliga OLTP-applikationsdatabasen i läget transaction för maximal återanvändning.
- En äldre databas eller administratörsdatabas som använder
LISTEN/NOTIFY, advisory-lås eller temporära tabeller i läget session för korrekt funktion.
[databases]
; high-concurrency web traffic -> transaction reuse
appdb = host=127.0.0.1 dbname=appdb pool_mode=transaction
; uses LISTEN/NOTIFY + session advisory locks -> keep session
jobsdb = host=127.0.0.1 dbname=jobsdb pool_mode=sessionSnabbkontroll
Välj rätt beteende vid transaktionspoolning med PgBouncer.
Sammanfattning
Sessionspoolning kontra transaktionspoolning, sammanfattat:
- Sessionsläge: backend hålls tills klienten kopplar från. Full funktionskompatibilitet, låg återanvändning. Använd det för databaser som behöver LISTEN/NOTIFY, advisory-lås på sessionsnivå eller beständiga förberedda satser.
- Transaktionsläge: backend lämnas tillbaka efter varje transaktion. Hög återanvändning för många korta begäranden, men tillstånd på sessionsnivå kan läcka eller försvinna.
- Det som går sönder i transaktionsläge: fristående
SETför GUC:er, namngivna förberedda satser, advisory-lås på sessionsnivå, LISTEN/NOTIFY och markörer med WITH HOLD. - Lösningar:
SET LOCALi en transaktion,max_prepared_statements(1.21+), korta transaktioner,idle_in_transaction_session_timeoutoch lägesöverskridanden förpool_modeper databas.
Lär dig SQL med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 22
- Lektioner
- 88
Vanliga frågor
Är lektionen ”Poolningslägen för transaktioner kontra sessioner” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Prestandaoptimering och frågeoptimering i PostgreSQL, inklusive ”Poolningslägen för transaktioner kontra sessioner”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Prestandaoptimering och frågeoptimering i PostgreSQL innehåller totalt 4 lektioner.
Vad lär jag mig i ”Poolningslägen för transaktioner kontra sessioner”?
Välj rätt PgBouncer-läge och lär dig vilka funktioner som slutar fungera vid transaktionspoolning. Ni övar på Prestandaoptimering och frågeoptimering i PostgreSQL med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Prestandaoptimering och frågeoptimering i PostgreSQL?
Du behöver inga förkunskaper. Utbildningen i Prestandaoptimering och frågeoptimering i PostgreSQL på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Poolningslägen för transaktioner kontra sessioner”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Prestandaoptimering och frågeoptimering i PostgreSQL-lektionen?
Ja. Varje Prestandaoptimering och frågeoptimering i PostgreSQL-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Varför anslutningar är kostsamma i PostgreSQL
- Poolningslägen för transaktioner kontra sessioner
- Dimensionera pooler efter antal kärnor
- Diagnostisera poolmättnad och köbildning