1.异步复制(Asynchronous replication)
- MySQL默认的复制即是异步的,
- 主库在执行完客户端提交的事务后会 立即将结果返给给客户端,并不关心从库是否已经接收并处理,
- 这样就会有一个问题,主如果down掉了,此时主上已经提交的事务可能并没有传到从上,
- 如果此时,强行将从提升为主,可能导致新主上的数据不完整
2.全同步复制(Fully synchronous replication)
- 指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。
- 因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响
3.半同步复制(Semisynchronous replication)
- 介于异步复制和全同步复制之间,
- 主库在执行完客户端提交的事务后不是立刻返回给客户端,
- 而是等待至少一个从库接收到并写到relay log中才返回给客户端
- 相对于异步复制,半同步复制提高了数据的安全性,
- 同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间
- 所以,半同步复制最好在低延时的网络中使用
- 在2010年MySQL 5.5版本之前,一直采用的是这种异步复制的方式
- 主库的事务执行不会管备库的同步进度,如果备库落后,主库不幸crash,那么就会导致数据丢失
- 于是在MySQL在5.5中就顺其自然地引入了半同步复制,
- 主库在应答客户端提交的事务前需要保证至少一个从库接收并写到relay log中
4.实现半同步复制的具体操作
前提:实现gtid模式的主从复制
主库:number1,172.25.254.1
从库:number2,172.25.254.2
1>配置主库master(number1)
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
#安装插件- 查看插件是否安装成功
SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%semi%';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
#激活插件
show status like '%rpl_semi_sync%';
#状态变量show variables like '%rpl%';
#环境变量
2>配置从库slave(number2)
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
#安装插件SET GLOBAL rpl_semi_sync_slave_enabled = 1;
#激活插件STOP SLAVE IO_THREAD;
#关闭IO线程START SLAVE IO_THREAD;
#开启IO线程- 从库重启io进程,激活插件之后必须要重启io进程,否则不会生效,如果重启不了的话就说明两端的数据不同步
show status like '%rpl_semi_sync%';
#状态变量show variables like '%rpl%';
#环境变量
3>测试
情况1
-
number2(从库)关掉IO线程:
stop slave io_thread;
-
在主库中插入数据,会等待10s,没有接收到slave的ack请求,自动转换为异步复制,需要等待一个节点完成所有的复制
-
insert into haha values('edc','000');
#插入数据 -
select * from haha;
#查看发现提交成功
-
select * from haha;
#在从库中查看,发现并没有同步
-
再次打开IO线程后,数据才能同步过来,此时复制过来的是异步复制的结果
-
START SLAVE IO_THREAD;
#打开I/O线程 -
select * from haha;
#在从库中查看,发现同步成功
-
也就是说只要从库的io进程恢复工作就会立即同步没有同步的数据
-
半同步复制失败后会自动切换成异步复制,从库进程起来之后会检测主从库数据是否同步;
-
若不同步,将会采用异步复制的方式同步数据
-
将插件安装在数据库中是临时的,退出重新登陆会失效,永久的可以将配置写在配置文件中
情况2 -
number2(从库)关掉IO线程:
stop slave io_thread;
-
在第二步插入数据的时候已经转换位异步复制
-
在从库开启线程,发现已经复制