Database connection pools in multi-tenant environments are meant to be isolated. Customer A's abandoned connections shouldn't affect Customer B's application response times. Yet in shared hosting environments running hundreds of separate MySQL instances, connection pool boundaries blur in ways that traditional monitoring tools never detect.
The problem manifests as gradual performance degradation across seemingly unrelated customer accounts. One tenant's poorly coded application leaves connections in CLOSE_WAIT state, eventually exhausting the shared connection pool and causing timeouts for completely different customers on the same server.
Understanding Multi-Tenant MySQL Connection Pool Architecture
Most shared hosting setups use connection poolers like ProxySQL or MySQL Router to manage database connections efficiently. Each customer gets allocated connection limits, but the underlying socket management happens at the kernel level where tenant boundaries become invisible.
The /proc/net/tcp file shows raw socket states for all TCP connections on the system, including database connections. Unlike MySQL's SHOW PROCESSLIST, which only shows active queries, /proc/net/tcp reveals the complete socket lifecycle including leaked connections that applications have abandoned.
Each line in /proc/net/tcp represents one socket with its state shown in hexadecimal: 01 means ESTABLISHED, 08 represents CLOSEWAIT, and 06 indicates TIMEWAIT. For MySQL connections, you're primarily interested in persistent CLOSE_WAIT states which indicate client-side connection handling problems.
Reading TCP Socket States for Database Connections
To isolate MySQL connections from other TCP traffic, filter by port 3306 and examine the socket states:
grep ":0CEA " /proc/net/tcp | awk '{print $4}' | sort | uniq -c
This shows the distribution of connection states to port 3306 (0CEA in hexadecimal). Healthy connection pools should show mostly ESTABLISHED (01) connections with occasional TIME_WAIT (06) states during normal connection cycling.
Accumulating CLOSE_WAIT (08) connections indicate applications that have closed sockets improperly, leaving the database server waiting for proper connection termination. In multi-tenant environments, these leaked connections consume shared pool slots.
Mapping Socket Owners to Customer Tenants
The challenge in multi-tenant diagnosis is connecting socket states back to specific customer accounts. Each socket in /proc/net/tcp includes an inode number which can be cross-referenced with process file descriptors in /proc/PID/fd/.
For each suspicious socket, extract the inode number from field 10 in /proc/net/tcp, then search for processes holding that socket:
find /proc/*/fd -type l 2>/dev/null | xargs ls -l 2>/dev/null | grep "socket:\[12345\]"
This reveals which process owns each connection, allowing you to trace leaked sockets back to specific customer applications or connection pooler instances.
Step-by-Step Socket Leak Detection Process
Start monitoring by establishing baseline connection patterns during known quiet periods. Count total connections per state and note the normal cycling patterns.
During suspected performance issues, compare current socket state distributions against your baseline. Look for:
- CLOSE_WAIT connections that persist beyond normal application restart cycles
- Unusual accumulation of TIME_WAIT states suggesting rapid connection cycling
- ESTABLISHED connections that remain static while application activity varies
Filtering MySQL Connections from TCP Socket Data
Beyond port filtering, examine connection patterns by local and remote IP addresses. Multi-tenant setups often show characteristic connection clustering where each customer's applications connect from specific IP ranges or through designated connection pooler instances.
Group connections by remote IP to identify which customer environments are contributing to socket state anomalies. Applications with proper connection handling show balanced socket state distributions, while problematic applications create recognisable patterns of leaked states.
Cross-Referencing Connection Pools with Process Trees
In complex hosting environments with multiple connection poolers, trace socket ownership through the complete process hierarchy. Connection pooler processes may spawn per-customer workers, each maintaining separate socket pools.
Examine process command lines and working directories to identify customer associations. Many hosting control panels like cPanel embed customer identifiers in process names or working directory paths, making tenant isolation clearer.
Interpreting Socket State Patterns
Healthy multi-tenant MySQL environments show predictable socket patterns. Connection states should cycle cleanly with occasional accumulation during peak usage periods, but always return to baseline levels.
Normal vs Leaked Connection Signatures
Normal connection cycling creates brief TIMEWAIT accumulation followed by clean socket cleanup. Applications properly closing connections show balanced ESTABLISHED/TIMEWAIT ratios with minimal CLOSE_WAIT states.
Connection leaks create persistent CLOSE_WAIT accumulation that grows over time rather than cycling. These connections consume pool slots indefinitely until process restarts or system intervention.
Monitoring tools like Server Scout's service monitoring can track these patterns continuously, alerting when socket state distributions deviate from established baselines before customer-facing performance issues develop.
Timing Connection Lifecycle Events
Socket state transitions follow predictable timing patterns in healthy systems. ESTABLISHED connections should transition to TIME_WAIT within reasonable application timeout windows, typically under 30 seconds for web applications.
Connections persisting in intermediate states beyond expected application lifecycles indicate handling problems. Document normal state transition timing for your environment to establish reliable alerting thresholds.
Prevention and Early Warning Systems
Building automated detection prevents connection pool exhaustion before customer impact occurs. Monitor socket state distributions continuously rather than reactively during performance complaints.
Set alerts for CLOSE_WAIT connection accumulation beyond baseline levels, typically when counts exceed 20% of your normal ESTABLISHED connection volume. This provides early warning while pool capacity remains available.
The techniques described here work similarly for detecting issues in other database systems - the same /proc/net/tcp analysis applies to PostgreSQL connection pool monitoring and Redis cluster health detection.
Socket-level monitoring provides infrastructure insights that application-specific database tools miss. While MySQL's SHOW PROCESSLIST reports active queries, only kernel-level socket analysis reveals the complete connection lifecycle affecting your multi-tenant performance.
For more detailed guidance on connection pool crisis detection, examine the network stack patterns that provide 20 minutes of early warning before pool exhaustion impacts customers.
FAQ
How do I distinguish between normal TIMEWAIT accumulation and actual connection leaks?
TIMEWAIT states should clear within 60 seconds and show cyclical patterns matching application activity. CLOSE_WAIT states that persist beyond application restart cycles indicate true leaks requiring investigation.
Can this technique detect connection leaks in database systems other than MySQL?
Yes, the same /proc/net/tcp analysis works for any database system using TCP connections. Adjust the port filtering for PostgreSQL (5432), Redis (6379), or other databases, but the socket state patterns remain consistent.
What's the performance impact of continuously monitoring /proc/net/tcp on busy systems?
Reading /proc/net/tcp is a lightweight kernel operation with minimal CPU impact. The file access completes in microseconds even on systems with thousands of connections, making continuous monitoring practical for production environments.