slave_compressed_protocol=1是跨机房mysql主从同步中应对带宽瓶颈最直接、成本最低的压缩加速手段,仅需从库启用且对业务零侵入,专压binlog传输层,实测压缩率40%–50%,需配合内核参数调优方能生效。

slave_compressed_protocol=1 是跨机房 MySQL 主从同步中应对带宽瓶颈最直接、成本最低的压缩加速手段,它在从库侧启用后即可生效,无需主库改动,且对业务零侵入。
为什么必须用 slave_compressed_protocol 而不是连接压缩?
MySQL 的客户端连接压缩(如 mysql --compress)只压缩应用到数据库的查询和结果,对复制流量完全无效。而主从复制走的是专用的 dump 协议,其数据流(binlog event)默认不压缩。只有 slave_compressed_protocol 才作用于 IO 线程与主库之间的 binlog 传输层,真正压的是 relay log 的源头数据。
常见错误是误以为开了 my.cnf 里的 compress=1 或应用层加了 --compress 就能加速复制——这些配置对 Seconds_Behind_Master 毫无影响。
slave_compressed_protocol=1 的实操要点
该参数仅在 MySQL 5.7.9+ 支持,旧版本必须升级:
- 在从库
my.cnf的[mysqld]段落添加:slave_compressed_protocol = 1,然后重启 MySQL;或动态执行:SET GLOBAL slave_compressed_protocol = 1 - 无需主库任何配合,也不依赖 binlog_format 或 GTID;但要求主库 MySQL 版本 ≥ 5.6.2(兼容协商)
- 压缩由从库 IO 线程自动与主库协商启用,可通过
SHOW SLAVE STATUS\G中的Slave_IO_State是否含Compressed字样确认(部分版本不显示,以实际网络流量下降为准) - 实测典型压缩率:文本型变更(如 JSON、HTML 字段)可达 40%–50%,纯数值变更约 15%–25%;CPU 开销增加通常
单靠压缩不够?必须搭配的三项内核级优化
即使启用了压缩,若 TCP 层行为不匹配高延迟链路,压缩后的包仍会卡在 Nagle 算法或拥塞控制里,导致吞吐上不去。务必在从库(推荐主库也配)执行:
-
sysctl -w net.ipv4.tcp_nodelay = 1:禁用 Nagle,避免 IO 线程攒小包等待 200ms,让每个 binlog event 尽快发出 -
sysctl -w net.ipv4.tcp_congestion_control = bbr:BBR 在 RTT >20ms 场景下比默认 CUBIC 多榨取 2–3 倍有效带宽,尤其对抗丢包抖动更稳 -
sysctl -w net.core.somaxconn = 65535:增大连接队列,防止高并发 dump 请求被内核丢弃(主库 dump 线程数多时尤其关键)
这三项是 Linux 内核行为调整,不改 MySQL 配置,但能让 slave_compressed_protocol 的效果真正释放出来。漏掉任意一项,都可能出现“开了压缩但 iperf 测出的吞吐没提升”的情况。
别踩这些坑:压缩失效的典型场景
压缩不是万能银弹,以下情况它要么无效,要么得不偿失:
- 主库写入量极低(如每秒
- 从库 CPU 已长期 >90%,再加压缩负载会导致 IO 线程调度延迟,
Slave_IO_Running可能变为Connecting或频繁重连 - 用了
binlog_format = ROW且大量更新未修改字段(如UPDATE t SET c1=c1 WHERE id=1),此时应先设binlog_row_image = MINIMAL减体积,再开压缩 - 网络本身丢包率 >1%,压缩不能解决丢包,需先用
mtr定位中间节点问题,否则压缩后丢一个包,重传代价更高
压缩只解决“带宽窄”,不解决“链路差”或“CPU弱”。上线前务必用 iperf3 -c 主库IP -t 60 对比开启前后的实测吞吐,再结合 SHOW SLAVE STATUS\G 中 Read_Master_Log_Pos 推进速度验证效果。











