Principles and Optimization of Database Connection Pools
Description
A database connection pool is a technology for managing database connections. It pre-creates a certain number of database connections when the application starts and stores them in a pool. When the application needs to interact with the database, it directly obtains a connection from the pool. After use, the connection is returned to the pool instead of being closed, thereby avoiding the overhead of frequently creating and destroying connections. The core goals of a connection pool are to improve performance, reduce resource consumption, and support high-concurrency scenarios. Typical applications include web servers, microservices architectures, etc.
Why is a Connection Pool Needed?
- High Connection Creation Cost: Each time a database connection is established, it requires steps like TCP three-way handshake, authentication, and resource allocation, taking approximately 10ms~100ms.
- Connection Limit: Databases have limits on concurrent connections (e.g., MySQL defaults to 151). Frequently creating connections can overload the database.
- Resource Reuse: Connections are scarce resources; reusing them can reduce memory and CPU consumption.
Core Components of a Connection Pool
- Connection Pool Manager: Responsible for initializing, destroying connections, and monitoring connection status.
- Idle Connection List: Stores reusable idle connections.
- Active Connection List: Records connections currently in use.
- Connection Pool Configuration Parameters: Such as minimum/maximum connections, timeout settings, etc.
Workflow of a Connection Pool
-
Initialization Phase:
- Based on the configured
minIdle(minimum idle connections), pre-establish connections and place them in the idle list. - Example: Setting
minIdle=5immediately creates 5 connections upon startup.
- Based on the configured
-
Connection Acquisition Phase:
- When the application requests a connection, the pool first allocates one from the idle list.
- If the idle list is empty and the current total connections have not reached
maxTotal(maximum connections), a new connection is created. - If the connection limit is reached, the request may be blocked (until
maxWaitMillistimeout) or throw an exception.
-
Connection Return Phase:
- After the application finishes using the connection, the pool marks it as idle instead of physically closing it.
- The pool resets the connection state (e.g., auto-commit mode, isolation level) to ensure no residual data for the next use.
-
Connection Destruction and Maintenance:
- Periodically checks if idle connections have timed out (
minEvictableIdleTimeMillis) and closes them if so. - Verifies connection validity (e.g., via
SELECT 1). Invalid connections are removed and replaced with new ones.
- Periodically checks if idle connections have timed out (
Key Parameters and Optimization Strategies
-
maxTotal (Maximum Connections):
- Setting too high may drastically increase database pressure. Adjust based on database and system load.
- Reference formula:
maxTotal = (QPS × Average Processing Time) / Concurrent Threads.
-
maxIdle and minIdle (Maximum/Minimum Idle Connections):
maxIdleshould be close to typical concurrency to avoid frequent connection creation/destruction.minIdleensures there are always backup connections for sudden traffic spikes.
-
maxWaitMillis (Maximum Wait Time to Acquire a Connection):
- Avoids long thread blocking. Degrade or retry after timeout.
-
Connection Validity Detection:
- Use
validationQuery(e.g., MySQL'sSELECT 1) to periodically verify connections. - Recommended to detect when borrowing a connection (
testOnBorrow=true) rather than during idle time to reduce overhead.
- Use
-
Connection Leak Handling:
- Set
removeAbandonedTimeoutto automatically reclaim connections not returned for a long time.
- Set
Practical Example: Tomcat JDBC Connection Pool Configuration
<Resource
name="jdbc/mydb"
maxTotal="100"
maxIdle="20"
minIdle="5"
maxWaitMillis="3000"
validationQuery="SELECT 1"
testOnBorrow="true"
/>
Common Issues and Solutions
- Connection Leaks: Connections not properly returned in code. Locate via log monitoring or tools (e.g., Druid's monitoring interface).
- Connection Failure After Database Restart: Configure
testWhileIdle=trueandtimeBetweenEvictionRunsMillisfor periodic detection. - Insufficient Connections Due to Instant High Concurrency: Appropriately increase
maxTotaland combine with rate-limiting strategies (e.g., circuit breakers).
Summary
Connection pools significantly improve performance by reusing connections, but configuration must align with business scenarios. It is recommended to monitor metrics like connection count, activity, wait time, and continuously optimize parameters.