多实例性能上不去主因是资源争抢而非单实例配置低;必须隔离cpu、内存、磁盘i/o:buffer_pool总和≤物理内存70%、各实例路径物理分离、按业务分级设置刷盘策略、绑定cpu核心并启用cgroup限流。

多实例部署下性能上不去,大概率不是单个实例配置太低,而是多个实例在抢资源——CPU、内存、磁盘 I/O 三者只要有一项没隔离好,整体就卡顿。关键不是“调大 buffer_pool”,而是让每个实例互不干扰。
innodb_buffer_pool_size 总和不能超物理内存 70%
常见错误是给每个实例都设成 innodb_buffer_pool_size = 16G,结果 3 个实例直接吃掉 48G 内存,系统开始 swap,查询延迟翻倍。实际应按公式算:总可用内存 × 0.7 − 系统保留(2–4G)− 其他进程(如 Redis、Nginx)占用。
- 32G 物理内存服务器,建议所有实例的
innodb_buffer_pool_size总和 ≤ 20G - 每个实例再按负载差异化分配:读多写少的设高些(如 12G),后台统计类设低些(如 4G)
- 必须开
innodb_buffer_pool_instances(推荐值 = CPU 核心数,但 ≥ 4),否则大缓冲池反而引发内部锁争用 - 监控命中率用
show engine innodb status\g查Buffer pool hit rate,低于 99% 才考虑调大,不是默认就拉满
日志和临时文件路径必须物理分离
多个实例共用一块 SATA 盘,datadir、log_bin、tmpdir 全挤在一起,I/O 队列立刻堆满。哪怕只是 SSD,也要避免不同实例写同一 mount point。
- 每个实例的
datadir指向独立挂载点(如/data/mysql1、/data/mysql2) -
log_bin和innodb_log_group_home_dir也分盘,尤其不要和datadir同盘 -
tmpdir统一指向/dev/shm或 NVMe 分区,禁用默认/tmp - SSD 上关闭磁盘调度器:
echo noop > /sys/block/nvme0n1/queue/scheduler
max_connections 和 thread_cache_size 要按实例粒度配
全局设 max_connections = 2000 看似够用,但某个报表实例把连接占满,其他 OLTP 实例就直接报 Too many connections。连接数必须按业务类型硬隔离。
- OLTP 实例:设
max_connections = 300,thread_cache_size = 32(≈ 10%) - OLAP 实例:设
max_connections = 50,但sort_buffer_size = 8M、read_rnd_buffer_size = 4M,防临时表落盘 - 务必同步调高系统级限制:
open_files_limit至少为所有实例max_connections总和的 2 倍 - 用
show status like 'Threads_%'看Threads_cached / Threads_created比率,低于 0.8 就说明thread_cache_size不够
innodb_flush_log_at_trx_commit 和 sync_binlog 要按数据重要性分级
所有实例统一设 innodb_flush_log_at_trx_commit = 1,写性能直接打五折;全设成 2,又可能丢一秒数据。多实例场景下,得按业务容忍度切开。
- 核心交易库:保持
innodb_flush_log_at_trx_commit = 1,sync_binlog = 1 - 日志归档库 / 报表库:可设
innodb_flush_log_at_trx_commit = 2,sync_binlog = 0 - 注意:若开启 GTID,
sync_binlog = 0会导致主从不一致,必须关 GTID 或改回 1 - 监控
show status like 'Innodb_log_waits',非零值持续上升,说明日志刷盘跟不上,要调大innodb_log_file_size(建议 256M–1G)
最容易被忽略的是 CPU 绑核和 cgroup 限流——参数调得再细,实例之间仍在争抢 CPU 时间片。上线前必须用 taskset -c 0-3 mysqld --defaults-file=/etc/my1.cnf 这类方式绑定核心,否则所有调优都是空中楼阁。











