ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MySQL内存占用过高怎么排查?一套完整的调优实战指南

MySQL内存占用过高怎么排查?一套完整的调优实战指南 接手一台MySQL服务器的第一件事永远不是急着调参数。说句实话大家在群里问“MySQL内存占用过大怎么排查”十有八九是先被top或者云监控的告警吓到了看到RES那栏飘到十几个G甚至几十个G第一反应就是“这玩意儿是不是漏了”。但实际上MySQL吃内存这件事跟Java进程“想占就占”的脾气还不太一样——它有章可循有参数能查有一整套内存账本可以算得明明白白。这篇文章就拿我最近一次处理线上MySQL内存问题的完整过程当例子把排查的思路、工具、参数调优和那些容易踩的坑一次说清楚。先给结论MySQL内存占用过高90%以上的情况不是“内存泄漏”而是“配置没算明白”。真正需要慌的是极少数——比如performance_schema无限膨胀、连接数爆炸、或者某个奇葩SQL把排序缓冲撑爆。大部分时候你只需要知道内存到底花在哪了、哪些参数能缩、哪些参数打死不能动就能把内存降到合理水位而且不影响性能。把这套东西摸透适合谁看呢如果你是运维、DBA、后端开发或者自己折腾服务器部署过MySQL的小白这篇文章能帮你少走弯路。下面的内容我会先带你建立MySQL内存架构的整体概念再给出具体的排查命令和调优参数最后附上我实际踩过的问题清单。全程不会有“背参数”式的枯燥我会告诉你这个参数为什么这么调、算出来的依据是什么。1. 先看现象一台飙内存的MySQL长什么样1.1 现场还原free看到的是“被吃光”那天下午收到告警说某台8G内存的云主机可用内存只剩不到1个G。我free -h一看used差不多6.7Gbuff/cache倒是没占多少就说明这机器内存确实是被实打实“吃”掉了而不是被文件缓存占了。再用top切到内存排序看一眼MySQL的RES已经到6.3G了%MEM直接78%。这种场景很多朋友都见过。但这里有个容易误判的点RES本身并不完全等于MySQL真实占用的“逻辑内存”。RES里还包含共享内存段、堆内存的物理驻留部分等等。所以它适合做“是否异常”的初步判断但不能用来精确算账。真正要算细账得进MySQL内部看。我做的第一件事不是连MySQL而是先在系统层面确认一件事——是不是只有MySQL吃内存ps aux --sort-%mem | head扫了一遍发现其他进程加一起也就占了几百M。那就锁定问题范围了MySQL自身的内存管理出了问题或者配置本身就不合理。1.2 排查前先排除“假性内存占用”这里的“假性”不是骗人的意思而是指系统层面的缓存计数误差。Linux的内存管理里free显示的used是“真正被进程使用的物理内存”buff/cache则被算作“可用”的一部分。MySQL的InnoDB缓冲池是直接用mmap和read/write来管理内存的它的内存页既会算在RES里部分页也会出现在buff/cache里。如果只看top不加区分很容易觉得“MySQL占了所有内存”。还有一个常见情况是刚重启过MySQL第一次跑大查询时内存会迅速爬升这是“预加载”机制在起作用不算泄漏。所以排查的第一步一定是先记录当前数值作为基线而不是马上动手改配置。后续所有判断都要跟这个基线做对比不然就是盲人摸象。2. 搞清楚内存到底被谁吃了MySQL内存架构拆解2.1 两类内存全局的桶 vs 每连接的水杯MySQL的内存模型我用一个生活化的比喻来解释全局缓冲是仓库会话缓冲是每个工人手里的水杯。仓库是所有人共享的比如innodb_buffer_pool_size就是InnoDB用来缓存数据页和索引页的“主仓库”数据读写都从这里经过。除了它还有key_bufferMyISAM索引缓冲、query cache如果还开着的话、performance_schema内存池、以及各类内部结构table cache、thread cache等。这些是“不管多少连接都要占的固定大头”。会话缓冲则是每个连接各自占一份的临时空间。比如sort_buffer_size排序缓冲、join_buffer_size嵌套循环连接缓冲、read_buffer_size顺序读缓冲、read_rnd_buffer_size随机读缓冲、bulk_insert_buffer_size批量插入缓冲。问题就出在这这些参数虽然是按连接来分配的但很多时候“分配”不等于“立刻使用”而是“按需增长”。可一旦你真的跑了一个要排序的大SQL这几个缓冲就会瞬间拉满。2.2 最容易爆雷的performance_schema可能很多朋友都忽略了这块。performance_schema是MySQL 5.7和8.0里默认开启的性能监控模块它会在内存里维护大量的监控数据表。如果你把performance_schema的采集项开得很全比如events_waits_history_long、events_statements_history_long它默认会保留每个线程的若干条历史记录而且每条记录占几百字节到几KB不等。连接数一多、SQL一频繁这个模块可以轻松吃掉几百MB甚至上GB的内存。我自己踩过一个特别典型的坑某次为了排查慢查询把performance_schemaON打开随手把performance_schema_max_table_instances设成了很大。结果MySQL吃掉的内存比平时多了1.5G而且都是不可回收的。后来一查SHOW ENGINE PERFORMANCE_SCHEMA STATUS看到memory那一行的字节数才发现是它干的。2.3 线程和连接数乘法效应的恐怖MySQL的每一个连接都会对应一个线程每个线程默认会预分配一份thread_stack通常256KB加上net_buffer_length默认16KB等即便这个连接什么都不干也要占几百KB。如果连接数涨到500光这层就是几百MB。更关键的是每个连接都在做sort或join的时候如果sort_buffer_size设为2M那你开500个连接又恰好同时触发排序那就是1G的瞬时内存。这就是为什么我一直强调“小参数 × 大连接数 大内存”这是排查时最容易忽略的乘法效应。3. 动手调优第一步三个全局参数先调明白3.1 innodb_buffer_pool_size核心中的核心只要跑的是InnoDB引擎innodb_buffer_pool_size就是内存占用的绝对大头。它缓存数据页、索引页、插入缓冲、锁信息等是所有InnoDB读写的必经之路。它设多大合适业界有一个经验公式专机专用服务器上只有MySQL设为物理内存的 50%~70%留出操作系统、文件缓存和临时性内存增长的空间。我这里说的8G机器如果跑的是纯MySQL理论上可以设5G。但实际情况是这台机器还跑着监控agent和一些脚本我最终设成了4G。怎么判断合不合适看SHOW GLOBAL STATUS LIKE Innodb_buffer_pool_read_requests逻辑读请求次数和Innodb_buffer_pool_reads从磁盘读的次数命中率 逻辑读请求次数 /逻辑读请求次数 磁盘读次数。如果命中率长期低于95%那就说明缓冲池太小了如果长期在99%以上且还有富余内存可以考虑加。但注意在内存本就紧张的场景下提高缓冲池不是唯一解也有可能是SQL没走索引导致扫了大量数据页。这里还有一个坑innodb_buffer_pool_size不是越小越好也不是越大越好。把它调到1G这种“安全值”确实能把内存降下来但代价是会产生严重的磁盘IO和性能劣化。线上业务如果对延迟敏感这种“自杀式调优”宁可别做。3.2 innodb_buffer_pool_instances大缓冲池的并行优化MySQL 5.7及以上版本如果你把innodb_buffer_pool_size设到了1G以上强烈建议把innodb_buffer_pool_instances也调起来。这个参数把缓冲池切分成多个独立实例减少并发访问的锁竞争。理论上每个实例建议不低于1G比如4G缓冲池可以设4个实例每实例1G。这个参数本身不会直接“减少内存占用”但它能改善大缓冲池的并发性能间接减少因锁等待产生的临时内存和线程堆积。注意了重点来了修改innodb_buffer_pool_size和innodb_buffer_pool_instances都需要重启MySQL才能生效。所以在生产环境改这个之前一定先确认业务低峰期并做好回滚方案。3.3 performance_schema关掉还是调瘦前面说过performance_schema是隐藏的内存大户。但这模块本身很有用我不建议粗暴关闭。正确做法是“调瘦”只保留你需要的采集项。比如把performance_schema_events_statements_history_long_size从默认的10000调小到1000把performance_schema_events_waits_history_long_size同理调小或者直接禁止某些不需要的consumer。改完再配合SHOW ENGINE PERFORMANCE_SCHEMA STATUS来看内存有没有降下来。如果业务量很小、遇到内存极度紧张也可以直接在my.cnf里performance_schemaOFF。但如果你要排查慢查询、等待事件、锁问题这个模块又不可或缺。我个人的习惯是先用它排查问题排查完调瘦配置而不是直接关掉。4. 动手调优第二步线程级内存参数别让小缓冲吃大内存4.1 sort_buffer_size 和 join_buffer_size典型的“按需分配”被误解很多老教程会告诉你“sort_buffer_size建议设2M、4M甚至8M”然后你就信了。但实际上在MySQL 5.7和8.0里这两个缓冲是“连接创建时不立刻分配需要排序或join时才按需增长到最大值”的。但架不住并发高啊你想想sort_buffer_size4M、500个并发排序瞬时内存就是2G。所以这个参数不能拍脑袋我建议的方法是先把线上实际的SHOW STATUS LIKE Sort_merge_passes拿出来看如果这个值很高说明排序频繁落盘说明sort_buffer_size太小如果这个值很低但内存压力又大那说明sort_buffer_size设大了该缩。默认值256KB其实对绝大多数OLTP场景足够了。join_buffer_size同理它既不是连接缓冲也不是索引缓冲而是“当join无法使用索引时为每次连接操作分配的缓冲块”。你把它设大了对于用小表驱动大表、且驱动表能被完全放入缓冲的场景确实能减少扫描次数但代价同样是乘连接数。我一般建议在2M以内并且要留意SHOW STATUS LIKE Select_full_join的值如果频繁出现全表join调大缓冲远不如优化SQL或加索引来得有效。4.2 read_buffer_size 和 read_rnd_buffer_size顺序读和随机读的缓冲区这两个参数也经常被误调。read_buffer_size是MyISAM和InnoDB做顺序全表扫描时用的缓存read_rnd_buffer_size则是读取排序后的结果集时用到的随机读缓存。它们都是会话级的、按需分配的。read_buffer_size不能用太大不然全表扫描一次就吃掉几十MB的例子我也见过。一般保持默认值或小幅调高到1M到2M就够了。这里有个经验点排查内存问题时先别动这两个因为它们对内存的影响远小于排序和连接相关的参数。只有当确认了SQL层没有全表扫描和排序问题时才轮到它们。4.3 tmp_table_size 和 max_heap_table_size临时表内存的上限MySQL内部临时表有两种一种是内存临时表MEMORY引擎一种是磁盘临时表。tmp_table_size决定了单个内存临时表的最大大小超过后就自动转为磁盘临时表。max_heap_table_size则限制MEMORY引擎表的大小。两个参数取较小的那个值作为实际上限。很多朋友可能不知道group by和order by一起出现、union、子查询等情况都可能在内存里建临时表。如果你把这两个值设得很大内存临时表塞得下还好塞不下就会触发磁盘临时表Created_tmp_disk_tables状态值猛涨性能陡降。如果设得太小SQL频繁创建临时表又会撑爆内存。我的经验值是如果业务里复杂统计查询多可以设到64M上下但要配合监控Created_tmp_disk_tables确保落盘次数不夸张如果业务是简单CRUD设16M都嫌多。注意这两个参数不是全局唯一的是会话级的还是有乘法效应别贪。4.4 max_connections内存账本里的乘法基数max_connections虽然不直接叫“内存参数”但它本质上是所有会话缓冲的内存乘法基数。刚才说的一堆xxx_buffer_size全部都要乘以这个数才是不最坏情况下的内存预算。假设你把sort_buffer_size、join_buffer_size、read_buffer_size、read_rnd_buffer_size都调到2M那每个连接在最坏情况下就会吞掉8M以上再算上thread_stack等固定开销假设max_connections是1000光是理论上限就是8GB以上物理内存再多也被榨干。所以我算内存账的时候永远会先问自己一个问题这台机器要支撑的最大并发连接数是多少用SHOW STATUS LIKE Threads_connected看实际峰值然后跟max_connections对比。如果实际峰值只有50max_connections却设成1000那是不合理配置至少说明风险敞口太大。调低max_connections比调低任何缓冲参数都更有效。但注意调低之前一定要确认你的应用连接池比如HikariCP、Druid的最大连接数小于这个值否则连接池建连失败报Too many connections的错那就得不偿失了。5. 容易被忽略的隐藏内存杀手连接数、碎片和监控系统5.1 连接数异常从几十直接冲到几百线上环境最常见的“突然飙内存”往往不是参数配错而是连接数瞬间长起来了。可能是有慢SQL堵住了连接池应用不断新建连接也可能是某个后台任务发起了全表扫描把连接全占住了。此时你进MySQL执行SHOW PROCESSLIST会看到一大堆Sleep状态的连接它们占着连接不释放每个连接又留着各自的会话缓冲分配内存自然就上去了。遇到这种情况第一件事是查SHOW STATUS LIKE Threads_connected和SHOW STATUS LIKE Threads_running前者是当前打开的连接数后者是当前正在执行的线程数。如果Threads_running很高说明确实有大量SQL在跑这时候调内存参数没用得先杀慢查询或优化SQL。如果Threads_running很低但Threads_connected很高说明是连接泄漏、没有正常归还要去查应用层的连接池配置。这里插一句MySQL 8.0.16以后有个好用的功能是SHOW STATISTICS不是是SHOW ENGINE INNODB STATUS里的连接信息有限我一般直接用performance_schema里的events_statements_summary_by_digest来查哪类SQL消耗最大。这才是从根上解决问题的思路。5.2 内存碎片进程龟速膨胀的原因之一有一回我遇到的情况很诡异SHOW GLOBAL STATUS里所有缓冲参数都合理连接数也不高但MySQL的RES就是缓慢上涨重启之后过几天又涨回来。查了一圈才想到是内存碎片。InnoDB缓冲池本身是有LRU淘汰机制的按理说不会无限膨胀。但如果你用了大量的临时表、频繁的排序、频繁的连接/断开C层的malloc/free会产生内存碎片物理内存的驻留量RSS就会慢慢升高。这时候SHOW GLOBAL STATUS LIKE Memory_used可能显示得并不高但操作系统层面看到的RSS却很高。这种情况最实用的解法是定期低峰期重启MySQL比如每两周一次或者把performance_schema相关的内存池重建一下ALTER INSTANCE DISABLE INNODB REDO_LOG这类操作不行但可以用CALL sys.ps_rebuild_table这种整理碎片的方式。实际上最干净的办法是调整连接池减少频繁建连/断连让MySQL复用线程和内存碎片问题会显著缓解。5.3 监控系统吃掉的内存你自己可能就是问题的一部分排查的时候别光盯着MySQL。我遇到过一个有趣的问题某台服务器上装了node_exporter和mysqld_exporter采集频率设成了1秒结果Prometheus每抓一次就建连一次连接数忽高忽低内存也跟着抖动。后来把采集时间间隔改成15秒内存立刻平稳很多。所以排查内存问题时把监控软件也纳入排查范围。MySQL的连接数对监控系统来说是“看不见的手”。6. 排查方法论从现象到根因的一套完整流程6.1 第一步用free和top建立基线不要上来就改配置。先记录free -h top -o %MEM | head -30 ps aux --sort-%mem | head -10这三条命令能在30秒内告诉你内存总量、MySQL的RES、有没有其他进程抢内存。把这个时间点的数据记下来作为“优化前”的基线。后续改完参数对比才知道调优有没有效果。6.2 第二步进MySQL看全局状态和关键指标登录MySQL后重点查询以下几个SHOW GLOBAL STATUS LIKE Innodb_buffer_pool_read%; SHOW GLOBAL STATUS LIKE Threads_connected; SHOW GLOBAL STATUS LIKE Threads_running; SHOW GLOBAL STATUS LIKE Sort_merge_passes; SHOW GLOBAL STATUS LIKE Created_tmp_disk_tables; SHOW VARIABLES LIKE innodb_buffer_pool_size%; SHOW VARIABLES LIKE max_connections%; SHOW VARIABLES LIKE performance_schema%;Innodb_buffer_pool_read_requests和Innodb_buffer_pool_reads的比值能看出缓冲池命中率。Sort_merge_passes高说明排序频繁落盘sort_buffer_size可能偏小Created_tmp_disk_tables高说明临时表频繁落地tmp_table_size可能偏小。这两个指标偏高不一定会“占大内存”但会“占大CPU和磁盘”间接拖慢业务所以也要留意。6.3 第三步使用状态变量计算“最坏情况内存”这里给出一个可以直接套用的MySQL内存预估公式总内存预算 ≈ innodb_buffer_pool_size key_buffer_size max_connections ×sort_buffer_size join_buffer_size read_buffer_size read_rnd_buffer_size thread_stack net_buffer_length performance_schema内存池 固定开销我自己算过一次4G缓冲池key_buffer8Mmax_connections200每个连接的会话缓冲加起来大概6MBsort2M、join2M、read1M、read_rnd1M、thread_stack256K、net_buffer16K等这边就是1.2Gperformance_schema大约0.5G固定开销0.5G总共大约6.2G。这台机器物理内存8G理论上能扛住。但如果max_connections是500呢会话缓冲部分直接变成3G总预算飙到8G以上系统就随时可能OOM。公式算出来你会发现真正占大头的往往不是缓冲池而是会话缓冲乘连接数。6.4 第四步针对性调参并验证根据上面的计算如果确定是max_connections偏大就调小它如果确定是sort_buffer_size偏大就调小。每次只改一个参数改完观察一段时间用第6.2步的指标来验证效果。我反对“一次改十个参数”的搞法那样出了问题根本不知道是哪一步引入的。一个小技巧MySQL 5.7以上支持动态调整部分参数不用重启。比如SET GLOBAL sort_buffer_size 1048576;这种可以临时生效先观察效果再决定是否写进my.cnf。但innodb_buffer_pool_size这种就不能动态“缩”到过小它内部有加载数据页的过程缩减反而会引发性能抖动所以这类参数必须在低峰期做。6.5 常用的问题排查速查表现象首选排查指标常见根因推荐动作内存缓慢上涨重启后回落RSS、Memory_used、碎片状态内存碎片、连接频繁建连/断开调连接池、定期低峰期重启内存突增伴随CPU飙高Threads_running、慢查询日志大量排序、全表扫描、笛卡尔积join抓慢SQL、优化索引、限制sort/join缓冲内存高但Threads_running很低Threads_connected、应用连接池配置连接泄漏、连接池maxSize过大调连接池、排查应用代码归还连接刚上线新功能后内存翻倍performance_schema内存状态采集项开太多、监控导致连接数暴涨调小采集历史、延长监控采集间隔配置看起来合理但内存仍高全局状态、表数量、缓存表数量table_open_cache过大、表数量太多调小table_open_cache、优化表数量7. 实操现场一次8G内存机器的完整调优记录7.1 现场数据采集接着文章开头那个案例继续说。我那台8G内存的机器free -h显示used 6.7GMySQL的RES是6.3G。进MySQL一看innodb_buffer_pool_size是5Gmax_connections是300sort_buffer_size是2Mjoin_buffer_size是2Mread_buffer_size是1Mread_rnd_buffer_size是1Mperformance_schemaON且没做过任何瘦身。7.2 算账和定位按公式估算5GBuffer Pool 300×2M 2M 1M 1M 256K 16K ≈ 5G 300×6.3M ≈ 5G 1.85G ≈ 6.85G。再加上操作系统和其他进程8G的机器确实被榨干了。但再仔细看一眼Threads_connected实际只有80。也就是说这台机器日常根本用不到300个连接。问题不在Buffer Pool而在于max_connections的配置和会话缓冲乘出来的“最坏情况内存”。另外performance_schema没做瘦身估算也吃了0.6G左右。7.3 调整动作和效果我的调整方案是把innodb_buffer_pool_size从5G降到4G留出操作系统和突发内存的余量把max_connections从300降到150跟应用侧确认过连接池上限是100sort_buffer_size和join_buffer_size先动态降到1M观察一星期看Sort_merge_passes和Select_full_join是否明显增长performance_schema把events_statements_history_long_size从10000调到2000降完以后最坏情况内存预算 ≈ 4G 150×1M 1M 1M 1M 256K 16K ≈ 4G 0.65G ≈ 4.65G。实际运行一周MySQL的RES从6.3G降到了4.2G业务查询延迟没有明显变化Sort_merge_passes没有增加连接数峰值稳定在90左右。7.4 临时性内存暴涨的应急处理如果遇到的是“立刻要降内存”的突发状况来不及仔细调参可以这样应急-- 杀空闲连接 SHOW PROCESSLIST; -- 找到大量Sleep的连接之后可以使用如下语句批量kill这只是示例执行前一定确认连接ID KILL connection_id;但注意KILL不能乱用必须先确认那些连接确实是可以断开的。更稳妥的办法是直接在应用连接池层面做流控或者把max_connections动态改小让新连接进不来SET GLOBAL max_connections 100;这种操作能瞬间卡住新增连接给排查争取时间。但要记住这只是一个临时止血动作根本解法还是要把慢SQL和连接池问题处理掉。8. 避坑清单那些年我们一起踩过的内存坑8.1 别被“默认配置就是合理的”骗了my.cnf如果是从网上某个教程直接复制来的很可能别人那台机器是128G内存而你的只有4G。安装完MySQL的第一件事永远是手动检查一遍内存相关参数而不是直接用默认的。尤其是innodb_buffer_pool_size在8.0里默认值变成了128M对于小内存机器但大数据的场景这配置反而会逼着MySQL频繁刷盘性能惨不忍睹。默认值只保证“能跑”不保证“跑得好”。8.2 调小InnoDB Buffer Pool之前先想清楚代价Buffer Pool是InnoDB的性能根基它不是“省内存万能药”。如果遇到内存不足优先调会话缓冲、连接数、performance_schema这些“水分”比较大的部分最后才考虑动Buffer Pool。我曾经见过一哥们儿为了把内存从2G降到512M把Buffer Pool调成128M结果业务QPS直接掉了一半。内存是降下来了性能也废了这属于本末倒置。8.3 不要盲信“RES高 内存泄漏”MySQL的RSS高不一定就是泄漏。它可能只是把Buffer Pool占满后又因为某些原因没有及时把冷数据页刷出。MySQL的LRU机制会根据innodb_old_blocks_time等参数延迟淘汰所以刚跑完大查询后内存短暂居高不下是正常现象。要判断是否泄漏应该持续观察好几个小时或几天看RSS是否在业务平稳的前提下还持续上涨而不是看完一次top就下结论。8.4 修改参数后别忘了重启和验证有些参数支持动态修改但写进配置文件后需要重启才生效。我有一次在my.cnf里改了max_connectionsSET GLOBAL也执行了但忘了改配置文件下次MySQL重启后配置又回去了等于白忙活。另外一个细节是SET GLOBAL对已存在的连接无效新连接才用新值。所以如果是想立刻限制现有连接数得手动Kill掉一部分多余的连接。8.5 不同的存储引擎内存参数完全不同这篇文章主要讨论InnoDB。但如果你还在用MyISAM表那key_buffer_size就要单独算。MyISAM的索引缓存全靠它默认8M很容易成为瓶颈但设大了也是内存开销。用SHOW GLOBAL STATUS LIKE Key_blocks_unused来看利用率一般情况下key_buffer_size设到256M以内足够大多数场景用了。如果你的库全是InnoDB那key_buffer_size保持默认就行别浪费内存。9. 一点额外的复盘从内存问题看到更本质的东西排查MySQL内存问题看起来是一个“调参”的活儿但实际上是对整个数据库运行状态做一次综合体检。内存只是表象背后往往是SQL质量、索引设计、连接池管理、监控体系这些更深层的东西。比如我们线上那次内存告警真正的根因其实是一个业务方跑了半小时的报表查询触发了大排序和临时表把会话缓冲全部拉满。如果只调整内存参数而不管SQL下次还会以另一种形式爆发。所以我最后想分享的一个实际心得是每次处理完内存问题不要急着关工单花一点时间把所有慢查询日志拉出来看看把events_statements_summary_by_digest按总延迟排序揪出那几个消耗最大的SQL模板。你会发现优化其中一条SQL的索引省下的内存可能比你调十个参数还多。我这次排查的最后就是帮业务方加了一个联合索引那条报表查询的排序临时表直接消失了MySQL内存又降了500M。这才是治本。另外还有一个小技巧可能很多人不知道mysql客户端连接时可以执行RESET CONNECTION或者用连接池的心跳检测定期清理会话状态把每个连接上临时表、排序缓冲、用户变量都释放掉。如果你用的连接池是HikariCP可以打开connectionTestQuery确保拿到的连接是健康的。这些小细节平时没人提但真到内存紧张的时候它们是压死骆驼的最后一根稻草和救命稻草的区别。本文的调参经验和数值都是基于我实际维护过的环境总结出来的。你的服务器配置和业务场景跟我不同数值不能盲目照搬但排查思路和计算公式是完全通用的。建议你收藏这份方法论下次再看到MySQL内存告警至少能从容地先算一笔账而不是重启了事。
返回列表