尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

磁盘 await < 2ms,没有问题

磁盘 await < 2ms,没有问题
📅 发布时间:2026/7/9 2:11:45

搬运并适配自国外社区真实案例。原文出处见文末。

TL;DR

症状:生产数据库突然出现周期性延迟尖刺(P99 从 2ms 跳到 2000ms),CPU 无异常,磁盘 IO 正常,内存余量充足。根因:内核 Transparent Huge Pages(THP)默认defrag=always模式,在分配大页时触发同步内存压缩(compact_memory),STW(Stop-The-World)长达数百毫秒。解决:echo never > /sys/kernel/mm/transparent_hugepage/defrag,改异步压缩(khugepaged)或直接关闭。权威背书:Red Hat、MongoDB、PostgreSQL 官方文档均建议数据库场景关闭 THP。

现象

$topPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND9876 mysql 20 0 16.2g 8.1g 8232 S 5.0 5.1 24:30.12 mysqld$free-htotal used free shared buff/cache availableMem: 157Gi 96Gi 8.0Gi 450Mi 53Gi 58GiSwap: 2.0Gi 0.0Gi 2.0Gi$vmstat1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st3 0 0 8264832 678912 56053760 0 0 1234 5678 28901 4503 8 2 88 2 08 1 0 8251392 678912 56054784 0 0 512 0 → 突然大量线程阻塞在 D 状态$cat/proc/vmstat|grep-E"compact|thp|kswapd"compact_migrate_scanned 283471923compact_free_scanned 891234567compact_isolated 45678234thp_fault_alloc 123456thp_fault_fallback 9876543 ← 分配大页失败次数极高thp_collapse_alloc 234567

环境:CentOS 7 / Linux 4.18.0 | MySQL 8.0 InnoDB | 128GB 内存 | 运行 6 个月正常,近期延迟尖刺从每月 1 次增加到每天 3 次。

排查过程

第一回合:常规诊断 → 无功而返

$iostat-x1#磁盘await<2ms,没有问题$perftop-p$(pgrepmysqld)#热点函数正常:ha_innobase::index_read、btr_search_guess_on_hash#没有异常锁竞争

为什么常规指标失灵:THP 压缩在khugepaged内核线程中执行,不消耗进程 CPU 时间、不产生磁盘 IO、不改变free -h数值。它只做一件事:把分散的 4KB 物理页搬到一个连续区域。这个过程不改变进程地址空间,但对被移动页面的任何访问都会触发硬件 page fault —— 等待时间远超正常内存访问。

第二回合:抓到关键信号

$cat/proc/vmstat|grepcompact_compact_migrate_scanned 283471923 # 已扫描的迁移页面compact_free_scanned 891234567 # 已扫描的空闲页面compact_isolated 45678234 # 已隔离的页面compact_stall 1234 ← 关键!触发同步压缩停滞compact_fail 567 # 压缩失败次数$cat/proc/vmstat|grepthpthp_fault_alloc 123456 # fault 时成功分配大页thp_fault_fallback 9876543 # fallback 到 4KB ← 极高thp_collapse_alloc 234567 # khugepaged 合并成功thp_split_page 45678 # 大页被拆分

compact_stall=1234意味着应用线程在alloc_pages()时被强制等待内存压缩完成——这是同步阻塞,时长取决于物理内存碎片化程度。

第三回合:定位根因参数

$cat/sys/kernel/mm/transparent_hugepage/enabled[always] madvise never$cat/sys/kernel/mm/transparent_hugepage/defrag[always] defer defer+madvise madvise never

两个参数都设成了always: -enabled=always→ 所有进程默认尝试用大页 -defrag=always→ 如果大页分配失败,同步等待内存压缩——应用线程卡住,等内核把碎片整理好

数据库运行 6 个月后,物理内存碎片化严重,大页分配失败概率飙升 →compact_stall从 0 增长到 1234 → 每次 STW 100-2000ms。

第四回合:确认效果

#方案1:defrag改异步(推荐)$echonever>/sys/kernel/mm/transparent_hugepage/defrag$echonever>/sys/kernel/mm/transparent_hugepage/enabled#验证$cat/proc/vmstat|grepcompact_stallcompact_stall 1234 # 不再增长#应用延迟恢复$# P99 恢复至 < 10ms

根因:内核代码级解析

THP 的核心在两个文件中:

  • mm/huge_memory.c— fault-time 分配:进程缺页中断时,内核尝试分配 2MB 大页
  • mm/khugepaged.c— 后台合并:khugepaged内核线程扫描,把连续 4KB 页合并成大页

当defrag=always时,fault-time 分配失败后的逻辑(简化):

// mm/page_alloc.c — __alloc_pages_slowpath()staticstructpage*__alloc_pages_slowpath(gfp_tgfp_mask,...){// ... reclaim 尝试后仍失败// defrag=always → 同步压缩if(gfp_mask&__GFP_DIRECT_RECLAIM){// try_to_compact_pages() 会迁移页面,耗时取决于碎片程度page=__alloc_pages_direct_compact(gfp_mask,order,...);// 这个过程可能耗时数百毫秒!}// 失败 → 返回 4KB 页面(fallback)returnfallback_to_4k_pages();}

为什么数据库场景特别严重: - 数据库的内存访问模式偏向随机读写,页面分散,THP 的"连续虚拟地址 → 连续物理地址"优势不明显 - InnoDB 的innodb_flush_method=O_DIRECT绕过 page cache,THP 对数据库页面的加速效果几乎为零 - 频繁malloc/free导致物理内存碎片化,大页分配失败率随时间线性增长

为什么 Redis 也受影响: - Redis fork 子进程做 RDB/AOF rewrite 时,Copy-on-Write(COW)会因 THP 放大:一个 2MB 大页哪怕只改 1 byte,也要完整复制 2MB

解决方案(按推荐度)

方案 1:彻底关闭 THP(数据库场景首选)

# 立即生效echonever>/sys/kernel/mm/transparent_hugepage/enabledechonever>/sys/kernel/mm/transparent_hugepage/defrag# 持久化cat>>/etc/rc.local<< 'EOF'echo never > /sys/kernel/mm/transparent_hugepage/enabledecho never > /sys/kernel/mm/transparent_hugepage/defragEOF# 或 grub 内核参数# /etc/default/grub:# GRUB_CMDLINE_LINUX="transparent_hugepage=never"# $ grub2-mkconfig -o /boot/grub2/grub.cfg

方案 2:用defer模式(折中)

echodefer>/sys/kernel/mm/transparent_hugepage/defrag

defer模式:fault 时不触发同步压缩,交给khugepaged后台异步处理。应用线程不卡,但大页利用率可能略低。

方案 3:per-process 精细化控制(JH/Java 场景)

# 只给 Java heap 开 THP(madvise 模式)echomadvise>/sys/kernel/mm/transparent_hugepage/enabled# Java 启动参数:# -XX:+UseTransparentHugePages 或 -XX:+UseLargePages

如何自检你是否中招

# 一行命令:检查是否有同步压缩停滞awk'/^compact_stall/ { stalls=$2 }/^thp_fault_alloc/ { alloc=$2 }/^thp_fault_fallback/ { fallback=$2 }END {printf "compact_stall=%d, alloc=%d, fallback=%d\n", stalls, alloc, fallback;if (stalls > 0) print "⚠️ 检测到同步压缩停滞!建议关闭 THP 或改 defrag=defer";if (fallback > alloc * 10) print "⚠️ 大页分配成功率 < 10%,物理内存碎片化严重"}'/proc/vmstat

持续监控脚本(/etc/cron.d/thp-monitor):

*/5****rootawk'/compact_stall/{s=$2}/compact_fail/{f=$2}END{if(s>100||f>50)system("logger -t thp-monitor WARNING compact_stall="s" compact_fail="f)}'/proc/vmstat

启示

  1. 默认配置不是为你优化的——Linux 内核 THP 默认always是为通用负载(Web 服务、文件服务器)设计的,不是为数据库。数据库场景 90% 的情况该关掉。
  2. 内存余量充足 ≠ 没有内存问题——THP 的延迟尖刺在free -h、vmstat、iostat上都不可见。唯一能抓到的信号是compact_stall字段。
  3. 不要只用enabled,一定要管defrag——很多运维只关了enabled但defrag还是always,以为问题解决了。两个参数独立生效。
  4. 碎片化随时间加重——今天没延迟不代表明天没有。物理内存碎片化是不可逆的累积过程,compact_stall只增不减(除非 reboot)。
  5. "透明"不透明——THP 的名字承诺"对应用透明",但延迟尖刺就是透明度破产的证明。真正透明的性能提升不该有代价。

原始出处: - kernel.org: Transparent Hugepage Support — 官方文档,defrag 五种模式详解 - kernel-internals.org: THP — 内核数据结构、khugepaged 扫描机制、/proc/vmstat字段解释 - Red Hat Performance Tuning Guide — RHEL 官方建议:数据库场景禁用 THP - YugabyteDB TA-26440 — THP 导致内存使用异常增长和 RSS 膨胀


本文首发于 CSDN 专栏《运维漏洞指南》。每篇都是排查回合制实录,从现象到内核代码,给可执行命令而非堆概念。

相关新闻

  • CycleGAN 图像风格迁移:PyTorch 实现马到斑马转换,PSNR 达 28.5
  • 02.01.01.ComfyUI Ubuntu:环境搭建篇(安装配置)
  • 《邮件钓鱼攻防工程》Part 2:构建不可溯源的基础设施

最新新闻

  • 制造业ERP系统推荐榜单有哪些?5款主流厂商选型参考
  • Go 微服务优雅上下线:PreStop Hook 和 Readiness Probe 的协作
  • 如何快速掌握AcFun视频下载:免费开源工具AcFunDown终极指南
  • Vivado IBERT 7系列GTX误码率测试:4种环回模式对比与眼图扫描实战
  • Windows 环境使用 Git Bash 最佳实践
  • Claude Code × MCP企业级部署手册(含SOC2合规配置模板、审计日志字段映射表、密钥轮换SOP)

日新闻

  • SQL 查询语句的标准逻辑执行顺序(即语义处理顺序),它与实际书写顺序不同,但决定了数据库如何解析和执行查询
  • ORB-SLAM2 重定位模块深度解析:从 BoW 候选帧到 PnP 优化的 6 步流程
  • 罗技鼠标宏压枪脚本终极指南:从原理到实战的完整解析

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号