1. 性能优化工程导入

数据库主机性能优化不是“调几个内核参数”的零散技巧,而是一项需要先看清系统全貌、再定位瓶颈、最后用可验证方式收敛问题的工程活动。在 RHEL 上承载 Oracle、MySQL、PostgreSQL 等数据库时,性能问题往往横跨硬件、操作系统、存储、网络与数据库实例多个层次。若一开始就凭经验改参数,很容易出现“压下一个瓶颈、冒出另一个瓶颈”的反复。因此,本章先建立一张完整的性能地图:典型架构是什么、问题通常从哪里来、优化目标如何量化、工程化方法如何落地。

一、RHEL 数据库主机的典型架构

一台典型的 RHEL 数据库主机,从下到上可以划分为若干层。最底层是物理或虚拟硬件,包括 CPU、内存、本地磁盘或 SAN/NVMe 存储、网卡。其上是 RHEL 内核,负责进程调度、内存管理、块设备 I/O 调度、文件系统(XFS/ext4)、网络协议栈以及 cgroup 资源控制。再往上是数据库实例进程,例如 Oracle 的 pmon/smon/dbwN、MySQL 的 mysqld 与后台线程、PostgreSQL 的 postmaster 与 backend/walwriter。最上层是客户端连接与业务 SQL。

理解这一分层非常关键:一次查询变慢,可能是 SQL 本身、可能是数据库缓冲区命中率、可能是文件系统写放大、也可能是存储阵列的队列深度饱和。只有把“请求—实例—内核—硬件”这条链路画清楚,才能判断该在哪一层动手。下图给出这一典型架构及主要性能观测点。

RHEL 数据库主机分层架构与性能观测点 客户端 / 应用层 连接池、JDBC/ODBC、业务 SQL、批量作业 观测:QPS、响应时间、连接数 数据库实例层 SQL 解析 / 执行计划 Buffer Pool / SGA Redo / WAL 写入 后台进程 RHEL 内核层 进程调度 CFS / 优先级 内存管理 HugePages / 回收 块设备 I/O 调度器 / 队列 文件系统 XFS / ext4 网络栈 TCP / 中断 硬件 / 存储层 CPU / NUMA 内存 / 带宽 SSD / NVMe / SAN 网卡 / 交换机 常见瓶颈落点: SQL 全表扫描 · Buffer Pool 不足 · Redo 写延迟 · I/O 队列饱和 · NUMA 跨节点访问 · 网络重传

二、性能问题的主要来源

从工程实践看,数据库主机的性能问题大致来自四类源头,且常常相互叠加。

第一类是 SQL 与访问路径问题。例如缺少合适索引导致全表扫描,执行计划因统计信息过期而退化,或一次批量操作在高峰期拉取百万行。这类问题的特征是“CPU 与 I/O 同时升高,但数据量并不大”,通过 EXPLAIN、AWR、慢查询日志往往能快速定位。

第二类是数据库实例配置问题。典型如 Buffer Pool 或 SGA 过小导致频繁物理读,Redo/WAL 日志文件过小引发频繁切换,连接数上限过低造成排队。这类问题表现为“资源未打满但吞吐上不去”。

第三类是 RHEL 内核与资源管理问题。例如透明大页(THP)导致数据库内存访问抖动、I/O 调度器不适合 NVMe、vm.swappiness 过高引发换页、NUMA 策略不当造成跨节点内存访问、cgroup 限制过紧。这类问题往往在系统层指标上先露出端倪。

第四类是硬件与存储问题。如磁盘 IOPS 达到上限、存储阵列缓存策略不当、网卡中断集中在单个 CPU、内存带宽成为瓶颈。这类问题通常需要结合 iostat、sar、perf 等工具与硬件规格共同判断。

判断问题来源的一个实用原则:先看“哪一层先饱和”。若 CPU 空闲而 I/O 等待高,优先查存储与文件系统;若 I/O 空闲而 CPU 系统态高,优先查中断、上下文切换与锁竞争。

三、优化目标的量化

没有量化目标的优化无法验收。数据库主机优化通常围绕以下指标设定目标,并明确“当前值—目标值—测量方法”。

指标类别典型指标示例目标(假设场景)观测工具
吞吐TPS / QPS由 3200 TPS 提升至 5000 TPS数据库自带统计、压测工具
延迟P95 / P99 响应时间P99 由 180ms 降至 80ms慢查询日志、APM
资源CPU 使用率、I/O awaitCPU 峰值 ≤ 75%,await ≤ 5mssar、iostat
稳定性换页次数、重传率swap in/out 接近 0,重传 < 0.1%vmstat、netstat

需要强调:上表数值为教学示例,实际目标必须结合业务 SLA、硬件规格与基线数据确定。优化的第一步永远是建立基线——在业务低峰与高峰分别采集一轮完整指标,否则后续任何“提升”都缺乏参照。

四、工程化方法:从基线到验证的闭环

把优化做成工程,而不是碰运气,核心是形成可重复的闭环:建立基线 → 定位瓶颈 → 提出假设 → 小范围变更 → 对比验证 → 固化配置。每一步都要有明确的输入与判据。

例如,怀疑 Redo 写延迟导致提交慢,可以先采集基线:iostat -x 1 观察日志盘 await 与 %util,数据库侧查看 log file sync 等待事件。若日志盘 await 持续高于 10ms,则提出假设“日志盘写入队列拥塞”。变更时只调整一项,例如将日志盘 I/O 调度器从 mq-deadline 切换为 none(NVMe 场景),或调整 nr_requests。变更后在同一压测负载下复测,比较 await、log file sync 平均等待与 TPS。只有指标改善且无副作用,才写入配置管理并记录变更单。

# 基线采集示例(教学示例命令)
iostat -x 1 5 > /tmp/io_baseline.txt
vmstat 1 5 > /tmp/vm_baseline.txt
sar -n DEV 1 5 > /tmp/net_baseline.txt

# 查看块设备调度器
cat /sys/block/nvme0n1/queue/scheduler

# 临时切换为 none(NVMe 推荐)
echo none > /sys/block/nvme0n1/queue/scheduler
任何内核参数或数据库参数变更都应遵循“一次只改一项、可回滚、有基线对比”的原则。批量修改会让因果关系无法归因,是性能优化中最常见的返工原因。

五、本课程的方法论约定