MariaDB(MySQL)配置不当引发服务器资源耗尽崩溃的优化求助
Hey there, let's tackle your MariaDB configuration disaster that's pushing your server to 100% CPU/memory and causing crashes. First, let's recap your setup to make sure we're on the same page:
你的服务器环境
硬件配置
- 服务器类型:独立服务器
- CPU:Xeon E5-2650 v4 ×2
- 内存:128GB
- 存储:2T SSD
软件配置
- 操作系统:CentOS 7
- MariaDB版本:v10.11.4
- 表数量:66张
- 总数据行数:346,215,143
- 存储引擎:全部为InnoDB
- 数据库总大小:74,837 MB
- 字符集排序规则:数据库和表均为utf8mb4_general_ci
当前配置里的致命问题
Your /etc/my.cnf.d/server.cnf has several critical misconfigurations that are directly causing your resource exhaustion:
废弃的Query Cache配置
MariaDB 10.11已经彻底移除了Query Cache功能!设置query_cache_type = 1、query_cache_size = 64G和query_cache_limit = 2G不仅完全没用,还会让MariaDB浪费大量CPU和内存去维护一个不存在的缓存——这是导致高CPU的核心原因之一。每个连接的内存参数过度分配
参数sort_buffer_size、read_buffer_size、read_rnd_buffer_size都是每个数据库连接单独分配的内存。你设置的16G每个,哪怕只有10个并发连接,这三个参数加起来就会吃掉480G内存——远远超过你的128G总内存,直接导致内存耗尽、OOM kill或者服务器崩溃。InnoDB缓冲池配置偏低
你的所有表都是InnoDB,innodb_buffer_pool_size = 46G只用到了总内存的35%左右,没有充分利用SSD和大内存的优势,导致大量磁盘IO,加重CPU负载。MyISAM相关参数浪费内存
key_buffer_size = 16G是给MyISAM表缓存索引用的,你根本没用MyISAM,这个参数完全是内存浪费,应该大幅降低。临时表参数过大
tmp_table_size和max_heap_table_size设为32G,意味着每个临时表最多能占32G内存,多个并发查询创建临时表会瞬间吃光内存。
优化后的配置建议
先备份你的原配置文件:
cp /etc/my.cnf.d/server.cnf /etc/my.cnf.d/server.cnf.bak
然后替换为以下优化后的配置(注释里说明了修改原因):
[server] [mysqld] datadir = /var/lib/mysql socket = /var/lib/mysql/mysql.sock log-error = /var/log/mariadb/mariadb.log pid-file = /var/lib/mysql/hippo.pid port = 5000 #skip-networking symbolic-links = 0 bind-address = 0.0.0.0 default_authentication_plugin = mysql_native_password skip-name-resolve = 1 # 连接数调整:15000太高,根据你的日访问量,500-1000足够,避免过多连接占用资源 max_connections = 1000 max_user_connections = 800 # 移除废弃的Query Cache参数 # query_cache_type = 1 # query_cache_size = 64G # query_cache_limit = 2G innodb_file_per_table = ON # InnoDB缓冲池设为总内存的65%左右,充分利用大内存缓存数据和索引 innodb_buffer_pool_size = 83G innodb_flush_method = O_DIRECT innodb_read_io_threads = 16 innodb_write_io_threads = 16 # SSD的IO能力强,调高innodb_io_capacity innodb_io_capacity = 10000 innodb_io_capacity_max = 20000 open_files_limit = 32768 innodb_open_files = 32768 innodb_log_buffer_size = 32M # 日志文件大小调整为2G(太大的话崩溃恢复时间太长) innodb_log_file_size = 2G innodb_data_file_path = ibdata1:10M:autoextend innodb_flush_log_at_timeout = 3 # MyISAM索引缓存,因为不用MyISAM,设为128M足够 key_buffer_size = 128M # 每个连接的内存参数,大幅降低到合理值 sort_buffer_size = 2M read_buffer_size = 2M read_rnd_buffer_size = 8M join_buffer_size = 8M thread_cache_size = 64 # 临时表大小调整为2G,避免内存耗尽 tmp_table_size = 2G max_heap_table_size = 2G wait_timeout = 300 net_read_timeout = 300 net_write_timeout = 600 table_open_cache = 32768 [mysqld_safe] open_files_limit = 32768 [galera] [embedded] [mariadb] [mariadb-10.3]
后续操作建议
- 修改配置后,重启MariaDB服务:
systemctl restart mariadb
- 监控服务器的CPU、内存和磁盘IO使用情况(可以用
htop、iostat、mysqladmin status等工具)。 - 检查慢查询日志(可以开启
slow_query_log = 1和long_query_time = 2),找出需要优化的慢查询——这也是降低CPU负载的关键。 - 定期优化InnoDB表(
OPTIMIZE TABLE或者用pt-online-schema-change避免锁表),整理碎片提升性能。
备注:内容来源于stack exchange,提问作者damian ventura




