The mysqld process is consuming excessive RAM, leading to system instability and performance degradation. This often manifests as the database server becoming unresponsive or the entire host crashing due to Out-Of-Memory (OOM) killer events.
Here are the most common culprits and how to address them:
1. Innodb Buffer Pool Size Too Large
- Diagnosis: Check your
my.cnf(ormy.ini) forinnodb_buffer_pool_size. Then, compare it with your total system RAM. A common recommendation is 50-80% of total RAM for dedicated database servers. If this value is set to80%or higher, or if it’s a very large absolute number (e.g.,20Gon a32Gserver), it’s a prime suspect.grep innodb_buffer_pool_size /etc/mysql/my.cnf free -h - Fix: Reduce
innodb_buffer_pool_sizein yourmy.cnf. For example, if it’s set to20Gon a32Gserver, try16G.
Restart MariaDB for the change to take effect.innodb_buffer_pool_size = 16G - Why it works: The InnoDB buffer pool caches data and indexes for InnoDB tables. While crucial for performance, if it’s too large, it starves the operating system and other processes of memory, leading to swapping or OOM kills.
2. Large Query Cache Size (MariaDB < 10.5)
- Diagnosis: The query cache is deprecated and removed in MariaDB 10.5. If you’re on an older version, check
query_cache_sizeandquery_cache_type. A largequery_cache_size(e.g.,128Mor more) combined withquery_cache_type = 1(ON) can consume significant memory, especially with a high rate of writes that invalidate cached results.mysql -e "SHOW VARIABLES LIKE 'query_cache%';" - Fix: Disable the query cache by setting
query_cache_size = 0andquery_cache_type = 0inmy.cnf.
Restart MariaDB.query_cache_size = 0 query_cache_type = 0 - Why it works: The query cache stores the results of identical
SELECTstatements. While it can speed up reads, it incurs overhead for maintaining the cache, especially with frequent data modifications. Disabling it frees up this memory and reduces contention.
3. Too Many Open Connections (max_connections)
- Diagnosis: Each connection consumes memory. If
max_connectionsis set excessively high (e.g.,1000or more) and your application is actually opening many connections concurrently, this can lead to high memory usage. Check the current number of active connections.mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';" mysql -e "SHOW VARIABLES LIKE 'max_connections';" - Fix: Lower
max_connectionsto a reasonable number based on your application’s typical usage, plus a buffer. For many applications,150-300is sufficient.
Restart MariaDB.max_connections = 250 - Why it works: By limiting the maximum number of simultaneous connections, you cap the memory allocated for connection threads, network buffers, and per-connection state.
4. Large Per-Connection Buffers
- Diagnosis: Variables like
sort_buffer_size,join_buffer_size,read_buffer_size, andread_rnd_buffer_sizeare allocated per connection (or per thread executing a complex operation). If these are set to very high values (e.g.,16Mor32M), and you have many connections, the memory footprint can explode.mysql -e "SHOW VARIABLES LIKE '%buffer_size';" - Fix: Reduce these values to more conservative settings. For example,
sort_buffer_size = 2M,join_buffer_size = 1M,read_buffer_size = 1M,read_rnd_buffer_size = 1M. These are often best left at their defaults or slightly increased only if specific query analysis justifies it.
Restart MariaDB.sort_buffer_size = 2M join_buffer_size = 1M read_buffer_size = 1M read_rnd_buffer_size = 1M - Why it works: These buffers are used for specific operations (sorting, joins, sequential reads). Allocating excessively large buffers per connection leads to a multiplicative memory increase with the number of connections.
5. MyISAM Key Buffer Size (if using MyISAM tables)
- Diagnosis: If you still have MyISAM tables, the
key_buffer_sizecaches MyISAM index blocks. Check its value and compare it to your total RAM. A large value here, especially if most of your data is InnoDB, is wasteful.mysql -e "SHOW VARIABLES LIKE 'key_buffer_size';" - Fix: If you are primarily using InnoDB, reduce
key_buffer_sizeto a small value (e.g.,16Mor32M). If you have critical MyISAM tables, tune it appropriately, but generally, the InnoDB buffer pool is far more important.
Restart MariaDB.key_buffer_size = 32M - Why it works: This buffer is specific to MyISAM index caching. Reducing it frees memory for the InnoDB buffer pool or other system processes if MyISAM is not your primary storage engine.
6. Large Temporary Tables (Disk vs. Memory)
- Diagnosis: Complex queries that require temporary tables can consume significant memory if
tmp_table_sizeandmax_heap_table_sizeare set too high, or if they spill to disk and cause I/O thrashing. MonitorCreated_tmp_disk_tablesstatus variable.mysql -e "SHOW GLOBAL STATUS LIKE 'Created_tmp%';" mysql -e "SHOW VARIABLES LIKE 'tmp_table_size';" mysql -e "SHOW VARIABLES LIKE 'max_heap_table_size';" - Fix: Ensure
tmp_table_sizeandmax_heap_table_sizeare set to reasonable values (e.g.,64Mor128M). IfCreated_tmp_disk_tablesis high, it indicates complex queries and potentially insufficient RAM for in-memory temporary tables, or that queries are not optimized. Optimize queries first.
Restart MariaDB.tmp_table_size = 128M max_heap_table_size = 128M - Why it works: These variables control the maximum size of in-memory temporary tables. If a temporary table exceeds these limits, it’s converted to an on-disk table, which is much slower and can indirectly lead to higher memory usage through complex query plans.
After applying these fixes, monitor your system’s memory usage closely. You’ll likely encounter issues related to insufficient disk space for replication logs or slow query logs if those were previously disabled due to disk constraints.