默认情况下,复制是异步的。主库不知道写入操作是否已经到达从库。如果主库和从库之间存在延迟,并且主库崩溃,尚未到达从库的那些数据就会丢失。为了解决这种问题,你可以使用半同步复制。
在半同步复制中,主库会一直等待,知道至少有一个从库接收到写入的数据。默认情况下,rpl_semi_sync_master_wait_point
的值是AFTER_SYNC
,这意味着主库将事务同步到二进制日志,再由从库读取使用。
之后,从库向主库发送确认消息,然后主库提交事务并将结果返回给客户端。所以,写入操作能到达中继日志就主够了,从库不需要提交这个事务。你可以将变量rpl_semi_sync_master_with_wait_point
更改为AFTER_COMMIT
来改变此行为。在这种情况下,主库将事务提交给存储引擎,但不会将结果返回给客户端。一旦事务在从库上提交,主库就会收到对事务的确认消息,然后将结果返回给客户端。
如果你希望在更多的从库上确认事务,则可以增加动态变量rpl_semi_sync_master_wait_for_slave_count
的值。你还可以设置主库必须等待多少毫秒才能通过动态变量rpl_semi_sync_master_timeout
获取从库的确认,其默认值是10秒。
在完全同步复制中,主库一直等待,知道所有从库都提交了事务。
在主库上,安装rpl_semi_sync_master
插件,
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM information_schema.plugins WHERE plugin_name LIKE '%semi%';
输出,
+----------------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +----------------------+---------------+ | rpl_semi_sync_master | ACTIVE | +----------------------+---------------+ 1 row in set (0.00 sec)
在主库上,启用半同步并调整超时(例如调整为1秒),
SET @@GLOBAL.rpl_semi_sync_master_enabled=1;
SET @@GLOBAL.rpl_semi_sync_master_timeout=1000;
在从库上,安装rpl_semi_sync_slave
插件,
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM information_schema.plugins WHERE plugin_name LIKE '%semi%';
输出,
+----------------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +----------------------+---------------+ | rpl_semi_sync_slave | ACTIVE | +----------------------+---------------+ 1 row in set (0.00 sec)
在从库上,启用半同步复制,并重新启动从库IO线程,
SET GLOBAL rpl_semi_sync_slave_enabled=1;
STOP REPLICA IO_THREAD;
START REPLICA IO_THREAD;
你可以通过以下方式监控半同步复制的状态。
SHOW STATUS LIKE 'rpl_semi_sync_master_clients';
未完待续。