kvm运行oracle 19c必须调优,因其默认配置不满足数据库i/o密集、内存敏感、时序严苛需求;需调整内存(vm.swappiness=1)、i/o(禁用thp、用raw+virtio-scsi+udev)、时间同步(tsc=reliable+systemd-timesyncd+cssdstat校验)三大核心项。

为什么KVM里跑Oracle 19c要特别调优?
因为KVM默认配置是为通用虚拟化设计的,不是为Oracle这种I/O密集、内存敏感、时序严苛的数据库服务的。直接在KVM里装完Oracle 19c就上线,大概率会遇到:db file sequential read平均延迟飙升、log file sync超时告警频发、RAC节点间心跳丢包、ASM磁盘组反复offline——这些都不是Oracle坏了,而是KVM层没对齐它的底层需求。
关键矛盾点有三个:内存访问路径被多层虚拟化拉长(尤其是THP + KVM + Oracle SGA)、I/O栈深度超标(qemu-block → virtio-blk → host filesystem → storage device)、时间精度失控(KVM clocksource不稳定导致CSS心跳误判)。不碰这些,光调Oracle参数只是隔靴搔痒。
必须改的KVM宿主机内核参数
这些不是“建议”,是Oracle 19c RAC在KVM里存活的底线。CentOS/RHEL 7.6+ 或 Oracle Linux 7.9+ 环境下,/etc/sysctl.conf里必须包含:
-
vm.swappiness = 1—— 防止Oracle SGA被swap出去,哪怕只换出1页,恢复时就是秒级停顿 -
vm.dirty_ratio = 15和vm.dirty_background_ratio = 5—— 避免脏页积压触发同步刷盘,冲击DBWn和LGWR -
kernel.numa_balancing = 0—— Oracle进程必须绑定到固定NUMA节点,否则跨节点内存访问延迟翻倍 -
net.core.somaxconn = 65535—— RAC集群通信和客户端连接风暴时,避免listen queue溢出
改完执行 sysctl -p 生效,并确认 numactl --hardware 输出中每个节点内存可用量与规划一致。
虚拟磁盘与存储栈怎么配才不拖后腿?
别用qcow2格式存DATA或FRA,它加了额外元数据层和copy-on-write逻辑,iostat -x 1里能看到大量%util接近100但r/s上不去。正确做法:
- 宿主机用XFS文件系统,挂载选项加
noatime,inode64,swalloc - 虚拟磁盘类型选
raw格式,而不是qcow2;控制器用virtio-scsi(不是virtio-blk),并在XML里显式开启iothread - ASM磁盘组必须用UDEV规则绑定到稳定设备名(如
/dev/asm-disk1),且每个磁盘对应一个独立的qemu-iothread,避免I/O争抢 - 如果宿主机有NVMe盘,直接透传给虚拟机(
host-passthrough),比任何软件层缓存都可靠
验证方式:lsblk -t 查看ra(readahead)是否为0,cat /sys/block/vda/queue/scheduler 应为 none(禁用CFQ或BFQ)。
时间同步为什么不能只靠chrony?
KVM虚拟机的时间漂移不是误差问题,是机制缺陷:TSC(Time Stamp Counter)在vCPU切换时不可靠,chrony只能补偿已发生的偏移,无法预防下一毫秒的跳跃。RAC的CSS服务要求节点间时钟差,否则强制驱逐节点。
必须双保险:
- 宿主机启用
tsc=reliable内核启动参数(确认CPU支持invariant TSC) - 虚拟机内禁用
chronyd,改用systemd-timesyncd+ntpdate -s定时校准(每5分钟一次),并设置ntpd -gq开机强同步 - 在libvirt XML里添加:
<clock offset="utc"><timer name="kvmclock" present="yes"></timer><timer name="hpet" present="no"></timer><timer name="pit" present="no"></timer></clock>
最后用 ntpq -p 和 cssdstat -f 同时观察,确保RAC节点间offset稳定在±20ms以内——这才是生产可用的底线。











