半同步复制不能保证强一致性,仅确保至少一个从库收到binlog;配置错误(如插件缺失、timeout过短、GTID下未设MASTER_AUTO_POSITION=1)会导致自动降级为异步。

半同步复制不能保证强一致性,只能把主库宕机时的数据丢失风险压到“至少一个从库已收到 binlog”这个层面;配置错一步,它就自动退化成异步复制,你还以为自己很安全。
半同步插件加载失败:找不到 semisync_master.so 或权限报错
MySQL 5.7+ 默认不自带半同步插件文件,得靠你手动确认是否存在、路径对不对、有没有读权限。常见错误是执行 INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so' 时报 “Can't open shared library”,本质就是文件缺失或路径错误。
- 先查插件目录:
SHOW VARIABLES LIKE 'plugin_dir';,典型路径是/usr/lib64/mysql/plugin/或/usr/lib/mysql/plugin/ - 再确认文件存在:
ls -l /usr/lib64/mysql/plugin/semisync_*.so,主库要semisync_master.so,从库要semisync_slave.so,二者不可混用 - 若缺失,重装
mysql-community-server包,或单独下载对应版本的插件包(注意平台后缀:Linux 是.so,macOS 是.dylib) - 插件加载失败会在错误日志里留下
Plugin 'rpl_semi_sync_master' init function returned error,必须先解决这个,再设rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout 设太小导致频繁降级为异步
这个参数单位是毫秒,默认 10000(10 秒),但生产环境设成 10 秒等于没设——网络抖动、从库 IO 峰值、relay log 刷盘延迟都可能触发超时,结果主库默默切回异步,Rpl_semi_sync_master_status 变成 OFF,你却没监控到。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 建议设为
3000~5000,既留出合理等待窗口,又不至于让事务卡太久 - 设为
0表示永不超时(主库会一直等),不推荐,写入链路可能被单个故障从库拖死 - 降级是设计行为,不是故障;网络恢复后会自动重连并重新启用半同步,无需重启 MySQL
- 务必监控
Rpl_semi_sync_master_no_tx(降级次数)和Rpl_semi_sync_master_yes_tx(成功半同步事务数),比值突增就是信号
GTID 模式下 CHANGE MASTER TO 忘加 MASTER_AUTO_POSITION = 1
开启 gtid_mode = ON 后,传统基于 MASTER_LOG_FILE 和 MASTER_LOG_POS 的配置方式直接报错:ERROR 1777 (HY000): CHANGE MASTER TO with MASTER_AUTO_POSITION = 0 is not allowed when @@GLOBAL.GTID_MODE = ON。半同步本身不干预位点管理,但它依赖复制链路能正常建立,而 GTID 下位点错配会导致 IO 线程起不来,半同步自然失效。
- 从库执行
CHANGE MASTER TO时,必须显式带上MASTER_AUTO_POSITION = 1 - 正确写法示例:
CHANGE MASTER TO MASTER_HOST='192.168.65.131', MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_PORT=3306, MASTER_AUTO_POSITION = 1; - 配置完别忘了重启 IO 线程:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;,否则插件不会生效 - 检查
SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running是否均为Yes,这是半同步工作的前提
最容易被忽略的是:半同步只确认“从库已写入 relay log”,不关心 SQL 线程是否回放完成。如果从库 SQL 线程积压严重,你看到 Rpl_semi_sync_master_status = ON,但实际数据还没应用——此时主库切换过去,照样丢数据。所以半同步必须搭配 sync_binlog = 1 和 innodb_flush_log_at_trx_commit = 1 才能真正降低丢失概率,而不是只靠一个 ACK。

















