本节摘要:数据库跑在 OS 上,OS 内核参数影响性能。本节讲清楚文件句柄、swap、大页、IO、内核参数调优,让 OS 不拖数据库后腿。
数据库依赖 OS:
OS 参数不当:
数据库打开多文件(数据文件、日志、连接 socket)。
问题:句柄不够——"Too many open files" 错误,连接/查询失败。
调优:
* soft nofile 65535 * hard nofile 65535 mysql soft nofile 100000 postgres soft nofile 100000
原则:句柄宁多勿少,但注意每句柄占内存(小)。
swap:内存不够时把页换到磁盘,严重退化(磁盘比内存慢 10 万倍)。
调优:
原则:数据库不用 swap——加内存而非靠 swap。swappiness 调低,监控 swap 使用,高则加内存。
OOM Killer:
问题:大内存机器,4KB 小页——页表巨大,TLB miss 多,性能降。
HugePages:2MB 大页——页表小,TLB 命中高。
配置:
权衡:
1. 脏页比例
2. 脏页过期
3. IO 调度器(见 6.2)
1. 内存 overcommit
2. SOMAXCONN(见 6.3 网络)
3. TCP 参数(见 6.3 网络)
4. 时钟
5. CPU 调度
6. NUMA(见 6.1)
1. 系统评估
2. 调优顺序
3. 持久化
4. 测试验证
5. 不要过度调
1. 系统资源
2. 内核统计
3. 数据库视角
⚠️ 常见误读:以为"内核参数调越多越好"。默认参数多数够用,只调瓶颈相关。过度调可能反害——如大页分配不当浪费内存、swappiness=0 极端 OOM 杀进程。
💡 关键直觉:OS 影响数据库——文件 IO/内存管理/进程调度/TCP 栈。文件句柄(ulimit -n 65535 当前/limits.conf 永久 nofile/file-max 系统总 1000000,不够"Too many open files"错误)。swap(swappiness 0-100,数据库设 1-10 尽量不用但不完全禁防 OOM 杀进程,echo 1 > /proc/sys/vm/swappiness,加内存而非靠 swap,监控 swap 高则加内存,OOM Killer overcommit_memory=2 严格防过度承诺/oom_score_adj 降 DB 被杀)。大页(4KB 小页 TLB miss 多,2MB 大页页表小 TLB 命中高;THP 透明大页数据库禁用防延迟突刺 echo never;静态大页 sysctl nr_hugepages=N 预分配 MySQL/PG huge_pages=on/Oracle 推荐;大内存 >64GB 提性能小内存浪费)。IO(dirty_ratio 20→10 dirty_background_ratio 10→5 减 OS 缓存脏页数据库自管/dirty_expire 调长减 OS 主动刷/IO 调度器见 6.2)。其他(overcommit_memory 0 或 2 严格防 OOM/SOMAXCONN/TCP 见 6.3/时钟 tsc 高精度/CPU performance 高频)。实践:评估当前→调优顺序(句柄→swap→大页→IO→网络→其他)→持久化 sysctl.conf/limits.conf/systemd→压测验证→不过度调默认多数够。监控 top/vmstat/iostat/free、/proc/meminfo 大页缓存、file-nr 句柄、sar 历史、数据库日志 OS 错误。
内核参数是"改了不容易看出效果、出问题却最先被怀疑"的层,所以每个改动都要配验证闭环。闭环三步:改动前记录基线(目标工作负载的关键指标——每秒 IO 数、上下文切换率、网络重传率),改动后同负载复测对比,差异不显著就回退——"理论上有用但实测无效"的参数很多,数据说了算。三个经典项的验证要点:文件句柄上限——高连接系统的隐形天花板,验证指标是句柄使用率曲线是否还顶格;交换策略——数据库服务器通常直接禁用交换(内存不够就去第 4 章解决,换页是性能的死亡之吻),验证指标是换页活动归零;透明大页——对数据库的内存访问模式可能造成延迟尖峰,主流实践是关闭改用显式大页,验证指标是延迟分位数的尾部改善。变更管理提醒:内核参数改动要进配置管理(与数据库参数同等待遇的留档与评审),散落在个人备忘录里的内核魔改是三年后故障排查的迷宫来源。内核层的最后一课:它服务的对象是上面的数据库——一切改动的裁判不是参数文档,是数据库的指标曲线。
内核调优的收官是观测工具箱——改内核参数前,你得先能看见内核的行为。四件基础工具:CPU 侧的上下文切换与运行队列观测(判断调度压力)、内存侧的缺页与换页计数(判断内存压力的真实形态——缺页是常态、换页是警报)、IO 侧的队列深度与服务时间分布(判断存储设备的真实负载特征)、网络侧的重传与乱序统计(判断链路质量而非带宽)。工具使用的两条纪律:其一,观测要在问题发生的当下做(事后重启现场全无),常用手段是把轻量级采集常驻(低采样率持续记录,异常时加密采样);其二,工具输出要与数据库指标对表(内核的 IO 繁忙要与数据库的等待事件互相印证),单侧证据容易误诊。一个成熟度标志:当团队讨论"内核参数要不要改"时,第一反应是"先看哪个指标"而不是"官方推荐值是多少"——那时内核层就从黑箱变成了你机器的仪表盘。全书到此从 SQL 一路讲到内核,六层贯通的调优师与单层专家的差别,就在这种"任何一层的问题都能找到它的观测面"的全局能力上。
内核章收官给一个年度审计清单——内核配置的漂移需要定期归零。审计项:文件句柄上限与实际峰值的余量、交换策略是否仍为禁用(系统升级常偷偷改回)、透明大页状态(内核更新后可能复位)、IO 调度器与当前介质的匹配、内核参数与数据库厂商推荐矩阵的对照(版本升级后矩阵会更新)。审计方法:配置采集脚本化(一次性把散在系统各处的内核态导出为清单),与基线清单做差异比对——漂移项逐个定性(有意的变更补登记、无意的漂移评估后回正)。归档:每次审计的差异报告存入第 4 章的参数台账(内核参数与数据库参数同册管理)。年度审计的哲学与全书一致:系统的每个层面都会悄悄偏离设计——SQL 会腐化、索引会腐化、统计会腐化,内核配置同样会——而对抗腐化的唯一手段,就是定期的、有清单的对账。至此六层对账全部闭环,这台数据库从硅片到 SQL 的每一寸,都在你的账本上了。
内核章的真正收官给一个"最后看一眼"清单——每次疑难杂症排查的收尾动作,顺手扫一眼内核态:上下文切换率(是否异常翻倍)、缺页与换页(换页出现即重大异常)、IO 队列与设备延迟(内核视角与数据库等待互相印证)、网络重传(请求慢的另一半真相)。四眼扫完无事,才能说"问题不在物理层"——而这句话说出口时,你就有全链路的证据链背书。这个习惯的仪式意义大于技术意义:它提醒调优者,六层是一个整体,任何结论都要在"上不冤枉应用、下不冤枉硅片"的前提下做出。全教程至此真正结束——从第一条慢 SQL 到最后一眼内核态,这条路你走通了,往后余生,性能问题于你不再是风险,是日常。
合上内核章也是合上全书,最后一句留给未来的你:六层的知识会随版本过时,但"每层有观测、每个变更有台账、每个结论有证据"的工程人格不会——它是这套教程真正想交付的东西,也是任何技术浪潮都稀释不了的竞争力。
全书的最后一句放这里:性能问题永无终结,但一个建立了六层观测、台账与纪律的团队,会把"永无终结"变成"永有余裕"——数据库调优的终点不是精确的系统,是从容的团队。愿你带着这份从容,去接每一通深夜的电话。
全书真正收官的彩蛋:把六章每章的"要点回顾/速记"打印成一页纸的"值班卡片"随身带——接警时按卡片的层次顺序走一遍,八成的故障在第三层前定位。这张卡片是整套教程的物理压缩形态,也是你读完全书的凭证——愿你用它值好每一个班,也愿卡片很快被你的肌肉记忆取代,那时它就只是一张纪念品了。