When running ps auxww | grep mysql
, we're observing 13 persistent MySQL processes despite only having one active client connection (verified via mysqladmin processlist
). Each process grows to consume ~50MB of RAM, leading to significant memory pressure on the server.
The server is using the default my-medium.cnf
template from /usr/share/mysql
, which typically includes these relevant settings:
[mysqld] key_buffer_size = 16M max_allowed_packet = 1M table_open_cache = 64 sort_buffer_size = 512K net_buffer_length = 8K read_buffer_size = 256K read_rnd_buffer_size = 512K thread_stack = 192K
First, let's verify the actual connection count and thread usage:
mysql> SHOW STATUS LIKE 'Threads_%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Threads_cached | 8 | | Threads_connected | 1 | | Threads_created | 13 | | Threads_running | 1 | +-------------------+-------+ mysql> SHOW VARIABLES LIKE '%thread%'; +---------------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | thread_cache_size | 8 | | thread_handling | pool | | thread_stack | 192K | +---------------------------+-------+
Based on the diagnostic output, several potential issues emerge:
- Connection Pool Misconfiguration: Some storage engines (like InnoDB) maintain their own thread pools
- Background Operations: Maintenance threads for replication, cleanup, etc.
- Plugin Issues: Authentication or monitoring plugins spawning additional threads
Try these configuration adjustments in my.cnf
:
[mysqld] thread_cache_size = 8 thread_handling = one-thread-per-connection skip-name-resolve performance_schema = OFF plugin-load = "" # For InnoDB specifically innodb_read_io_threads = 4 innodb_write_io_threads = 4 innodb_purge_threads = 1
Then verify thread reduction with:
watch -n1 "mysql -e 'SHOW PROCESSLIST;' | wc -l"
For deeper analysis, examine the thread purposes:
mysql> SELECT * FROM performance_schema.threads WHERE TYPE='BACKGROUND'; mysql> SELECT THREAD_ID,PROCESSLIST_COMMAND FROM performance_schema.threads;
If using MySQL 8.0+, check resource consumption per thread:
SELECT t.THREAD_ID, t.PROCESSLIST_COMMAND, m.CURRENT_COUNT_USED, m.CURRENT_NUMBER_OF_BYTES_USED FROM performance_schema.threads t JOIN performance_schema.memory_summary_by_thread_by_event_name m ON t.THREAD_ID = m.THREAD_ID;
For stubborn cases, perform a clean debug installation:
# Backup first! mysqldump -u root -p --all-databases > full_backup.sql # Install debug version sudo apt-get install mysql-server-dbg # Run with strace strace -f -o mysqld.strace mysqld --console --debug
When investigating MySQL memory issues, seeing multiple mysqld processes with only one active client connection immediately raises red flags. The process list shows 13 instances (as seen in the ps aux output), each consuming up to 50MB RAM - a clear indication something's misconfigured.
The my-medium.cnf template often needs customization for production environments. Key parameters to examine:
# Check current thread settings
SHOW VARIABLES LIKE 'thread%';
SHOW STATUS LIKE 'Threads%';
# Suggested adjustments for medium workload:
[mysqld]
thread_cache_size = 8
thread_concurrency = 4 # For older MySQL versions
thread_handling = one-thread-per-connection # Modern alternative
Even with one active connection, connection pool implementations can create phantom processes:
# Check actual connection sources
SELECT * FROM performance_schema.threads
WHERE TYPE='FOREGROUND' AND PROCESSLIST_COMMAND != 'Sleep';
# Verify connection pool settings
SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'wait_timeout';
Engine-specific behaviors can spawn additional threads:
# Check active storage engines
SHOW ENGINES;
# InnoDB-specific diagnostics
SHOW ENGINE INNODB STATUS;
SHOW VARIABLES LIKE 'innodb_thread%';
Based on the symptoms, here's a step-by-step resolution approach:
- Backup current my.cnf
- Implement these changes:
[mysqld]
# Connection management
max_connections = 100
wait_timeout = 60
interactive_timeout = 60
# Thread optimization
thread_cache_size = 8
thread_stack = 256K
# Memory allocation
key_buffer_size = 32M
table_open_cache = 2000
Then restart MySQL and monitor with:
watch -n 5 "mysqladmin processlist; free -m"
Long-term monitoring setup:
# Create a monitoring user
CREATE USER 'monitor'@'localhost' IDENTIFIED BY 'securepassword';
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'monitor'@'localhost';
# Sample monitoring query
SELECT COUNT(*) as active_threads,
SUM(IF(COMMAND='Sleep',0,1)) as active_queries
FROM information_schema.PROCESSLIST;