5.2 KiB
PostgreSQL Auto-Healing Configuration Guide
This guide explains the auto-healing mechanisms implemented to prevent and recover from PostgreSQL connection exhaustion issues.
Overview
The auto-healing system consists of several components working together:
- Enhanced PostgreSQL Configuration
- Improved PgBouncer Connection Pooling
- Health Checks and Automatic Restarts
- Periodic Connection Cleanup
- Resource Limits and Scaling
Components
1. PostgreSQL Enhancements (postgis-deployment-enhanced.yaml)
- Increased max_connections: From 100 to 200
- Connection timeouts:
idle_in_transaction_session_timeout=30s: Kills idle transactions after 30 secondsstatement_timeout=300s: Kills queries running longer than 5 minutes
- Readiness probe: Fails if connection count exceeds 180 (90% of max)
- Increased resources: 2Gi memory, 1 CPU
2. PgBouncer Enhancements (pgbouncer-deployment-enhanced.yaml)
- Connection pooling settings:
- Pool mode:
transaction(releases connections after each transaction) - Default pool size: 25 connections per database/user pair
- Server idle timeout: 10 minutes
- Query timeout: 5 minutes
- Pool mode:
- Retry logic:
server_login_retry=15: Retries failed logins for 15 secondsserver_round_robin=1: Distributes connections evenly
- Enhanced logging: Tracks connections, disconnections, and errors
3. APRS Application Enhancements (aprs-statefulset-enhanced.yaml)
- Reduced connection pool: From 10 to 5 connections per pod
- Connection timeouts:
- Pool timeout: 60 seconds
- Connect timeout: 30 seconds
- Idle timeout: 15 minutes
- Startup probe: Allows up to 120 seconds for application startup
- Increased resources: 1Gi memory, 1 CPU
4. Automatic Connection Cleanup (postgres-cleanup-cronjob.yaml)
Runs every 15 minutes to:
- Kill idle connections older than 30 minutes
- Kill idle-in-transaction connections older than 5 minutes
- Log connection statistics
- Monitor connection usage percentage
5. Pod Disruption Budgets (postgis-pdb.yaml)
Ensures at least 1 replica of PostgreSQL and PgBouncer remain available during:
- Cluster upgrades
- Node maintenance
- Voluntary disruptions
How Auto-Healing Works
Connection Exhaustion Prevention
- Application-level: Reduced pool size prevents each pod from using too many connections
- PgBouncer-level: Connection pooling multiplexes many client connections over fewer server connections
- PostgreSQL-level: Timeouts automatically close stale connections
Automatic Recovery
-
Health checks: Pods restart automatically when:
- PostgreSQL has too many connections (>180)
- PgBouncer can't connect to PostgreSQL
- Application can't connect to the database
-
CronJob cleanup: Every 15 minutes, forcefully closes:
- Idle connections wasting resources
- Stuck transactions blocking others
-
Connection retry: PgBouncer retries failed connections for 15 seconds before giving up
Monitoring
Use the provided monitoring script to check system health:
./monitor-postgres-health.sh
This shows:
- Current connection count and states
- Connection usage percentage
- Recent errors from logs
- Last cleanup job execution
Manual Intervention
If automatic healing fails, you can manually intervene:
# Check connection details
kubectl exec -it deployment/postgis -n aprs -- psql -U aprs -d aprs_prod -c "SELECT * FROM pg_stat_activity WHERE datname = 'aprs_prod';"
# Kill all connections (emergency)
kubectl exec -it deployment/postgis -n aprs -- psql -U aprs -d aprs_prod -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'aprs_prod' AND pid <> pg_backend_pid();"
# Restart components
kubectl rollout restart deployment/postgis -n aprs
kubectl rollout restart deployment/pgbouncer -n aprs
kubectl rollout restart statefulset/aprs -n aprs
Applying the Configuration
To apply all auto-healing configurations:
cd /Users/graham/dev/infra/clusters/aprs
./apply-auto-healing.sh
This script:
- Backs up current configurations
- Applies all enhanced configurations
- Waits for rollouts to complete
- Provides a summary of changes
Tuning Parameters
You may need to adjust these based on your workload:
- PostgreSQL max_connections: Currently 200, increase if needed
- PgBouncer pool sizes: Currently 25, adjust based on connection patterns
- Application POOL_SIZE: Currently 5, can be increased if connections are available
- Cleanup intervals: Currently 15 minutes, can be more or less frequent
Troubleshooting
Common issues and solutions:
- "too many clients already": Cleanup job should fix this within 15 minutes
- "server login has been failing": PgBouncer is in retry mode, will recover in 15 seconds
- Pods in CrashLoopBackOff: Check logs for specific errors
- High memory usage: Consider increasing resource limits
Future Improvements
Consider implementing:
- Prometheus metrics for connection monitoring
- Alerting when connection usage exceeds 80%
- Horizontal pod autoscaling based on connection metrics
- Connection pooling at the application level using a library like
poolboy