mysql内存占用过高怎么办_资源问题排查

2次阅读

mysql内存过高需区分合理缓存与异常占用:重点调优 innodb_buffer_pool_size(60%–80% 物理内存)、tmp_table_size/max_heap_table_size(16–64MB)、线程 级参数及 max_connections;通过 sys/performance_schema 查内存分布;结合 PROCEsslIST、EXPLai N 定位低效 SQL;检查大表、冗余索引及存储过程。

mysql 内存占用过高怎么办_资源问题排查

MySQL内存占用 过高,核心在于区分“合理缓存”和“异常占用”。InnoDB 缓冲池(innodb_buffer_pool_size)占大头是正常的,但若实际使用远超配置值、或内存持续增长不释放,就需系统排查。

查关键内存参数是否失当

重点检查以下几项是否与服务器物理内存不匹配:

  • innodb_buffer_pool_size:应设为物理内存的 60%–80%,例如 64GB 内存建议设 40–52GB。设太高会挤占系统和其他进程空间;设太低则频繁刷盘,反而拖慢性能。
  • tmp_table_sizemax_heap_table_size:两者需一致,建议 16–64MB。过大会让内部临时表长期驻留内存,尤其在 GROUP BY、ORDER BY 未走索引时。
  • sort_buffer_sizejoin_buffer_size等线程级参数:默认值(256KB–4MB)通常足够。盲目调大(如设到 32MB)会导致每个活跃连接多占几十 MB,连接数一多就雪崩。
  • max_connections:设 2000 但实际峰值仅 300,MySQL 仍会为每个连接预分配线程内存,造成浪费。应按真实 并发 压测结果设置,并配合应用端连接池控制。

看内存实际用在哪

别只看 top 里mysql d 占了多少,要进 MySQL 查真实分布:

  • 执行 red”>select SUM(CAST(REPLACE(current_alloc,’MiB’,”) AS DECIMAL(10,2))) FROM sys.memory_global_by_current_bytes WHERE current_alloc LIKE ‘%MiB%’; —— 看全局内存总用量(单位 MB)。
  • 执行 SELECT event_name, sys.format_bytes(CURRENT_NUMBER_OF_BYTES_USED) FROM performance_schema.memory_summary_global_by_event_name ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC LIMIT 10; —— 找出前 10 大内存消耗模块,比如memory/innodb/buf_buf_pool(正常)、memory/temptable/physical_ram(可能 SQL 有缺陷)、memory/group_rpl/Gcs_xcom::xcom_cache(主从复制积压)。
  • 执行 SELECT user, event_name, ROUND(current_number_of_bytes_used/1024/1024,2) AS mb_used FROM performance_schema.memory_summary_by_account_by_event_name WHERE host != ‘localhost’ ORDER BY mb_used DESC LIMIT 5; —— 定位高内存消耗账号,结合其 SQL 分析问题根源。

盯连接与查询行为

内存不释放常源于长连接 + 低效 SQL,而非配置本身:

  • 运行 SHOW FULL PROCESSLIST;,重点关注 StateCopying to tmp tableSorting resultSending dataTime 大于 60 秒的线程——这类查询大概率没走索引或数据量过大。
  • 对可疑 SQL 执行 EXPLAIN,确认是否全表扫描、是否用了临时表、是否需要文件排序(Extra列含 using filesortUsing temporary)。
  • 检查是否存在大量 Sleep 连接未断开(如应用未正确 close)。可用 SHOW STATUS LIKE ‘Threads_connected’; 对比 max_connections,若长期接近上限,说明连接泄漏。

对象 与数据规模是否失控

有些问题藏在 数据库 结构里:

  • 执行 SELECT table_schema, table_name, round(((data_length + index_length)/1024/1024),2) AS size_mb FROM information_schema.TABLES ORDER BY size_mb DESC LIMIT 10; —— 找出 TOP10 大表。单表超 50GB 且无分区,易导致大查询内存爆增。
  • 检查冗余索引:SELECT * FROM sys.schema_redundant_indexes;。多余索引不仅占磁盘,还会在写入和部分查询中增加内存开销。
  • 查看存储过程 / 函数数量:SELECT COUNT(*) FROM information_schema.ROUTINES WHERE routine_schema NOT IN (‘mysql’,’sys’,’information_schema’,’performance_schema’);。大量复杂逻辑 封装 在服务端,可能隐式申请大量内存且难追踪。

以上就是

站长
版权声明:本站原创文章,由 站长 2025-12-24发表,共计2185字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
1a44ec70fbfb7ca70432d56d3e5ef742
text=ZqhQzanResources