MySQL的主从复制模式包括异步复制,全同步复制,半同步复制。MySQL默认为异步模式。MySQL5.7引入了一种新的半同步方案,并且在5.7引入了一个新的参数,rpl_semi_sync_master_wait_point,这个参数有两种取值,1)AFTER_SYNC 2)AFTER_COMMIT 前者是新的半同步方案后者为老的半同步方案。
MySQL的主从复制模式有三种
异步复制:
(Asynchronous replication)。MySQL的默认复制,主库在执行完客户端提交的事务后会立刻将执行结果返回给客户端,并不关心从库是否已经接收处理,这样带来的问题就是当主死掉了,此时主上提交的事务可能还没有传到从上。而强行将从提升为主就会导致新主上的数据不完整。
异步复制是一种基于偏移量的主从复制,实现的原理是:主库开启bbinlog功能并授权从库连接主库,从库通过change master得到主库的相关同步信息,然后连接主库进行验证,主库的IO线程根据从库slave的线程请求,从master.info开始记录的位置点向下开始取信息,同时把提取到的位置点和最新的位置与binlog信息一同发给从库IO线程,从库将相关的sql语句放在relay_log中,最终从库的sql线程会将relay_log里的sql语句应用到从库上,至此同步过程完成,以后一直循环此过程。
对于异步复制而言,主库将事务的Binlog事件写入到binlog文件中,此时主库会通知下dump线程发送这些新的binlog然后主库会继续处理提交操作,而此时并不保证这些日志会传输到任何一个从库的节点上。
全同步复制:
(Fully synchronous replication)。当主库执行完一个事务,所有的从库都执行了该事务才会将结果返回给客户端。这样保证了数据的安全性,但是因为需要等待所有从库执行完该事务才能返回客户端结果,所以全同步复制的性能必然会受到很大的影响。
对于全同步复制而言,当主库提交一个事务后,要求所有从库节点必须收到,执行并提交这些事务,然后主库线程才能继续做后续操作,而因此带来的问题就是主库完成一个事务的时间被大幅度拉长,性能降低。
半同步复制:
(Semi synchronous replication)。介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时也会造成一定程度的延迟,这个延迟为一个TCP/IP往返的时间。所以半同步复制需要在低延时的网络中使用。
对于半同步复制而言,是介于同步复制和异步复制之间的一种,主库需要等待至少一个从库节点收到并且刷新binlog到relay日志中,主库不需要等待所有从库给主库反馈,同时这里只是收到反馈而不死和完全执行并且提交事务的反馈,这样会节省很多的时间。
主库上安装插件
install plugin rpl_semi_sync_master soname 'semisync_master.so';
查询数据库插件:mysql>show plugins;
#启用半同步
mysql>set global rpl_semi_sync_master_enabled=1;
#查询同步
mysql>show global variables like '%rpl_semi%';
master服务器/etc/my.cnf里加入:
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1second
socket=/data/mysql/mysql.sock
port = 3306
open_files_limit = 8192
log_bin
server_id=1
expire_logs_days = 7
gtid-mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1second
innodb_buffer_pool_size = 512M
character-set-server=utf8
从库安装插件
mysql>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql>show plugins;
#启用半同步,#(0/1) -->1是开启状态,0 是关闭状态
mysql>set global rpl_semi_sync_slave_enabled=1;
#查询
mysql>show global variables like '%rpl_semi%';
slave服务器/etc/my.cnf里加入:
rpl_semi_sync_slave_enabled=1
socket=/data/mysql/mysql.sock
port = 3306
server_id = 2
log_bin
gtid-mode=ON
enforce-gtid-consistency=ON
log_slave_updates=ON
rpl_semi_sync_slave_enabled=1
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8
MySQL8.0关闭binlog,在my.cnf下加入
#skip-log-bin
skip-log-bin
从库优化之InnoDB引擎库修改刷盘方式
innodb_flush_log_at_trx_commit:是 InnoDB引擎特有的,ib_logfile的刷新方式( ib_logfile:记录的是redo log和undo log的信息)
取值:0/1/2
innodb_flush_log_at_trx_commit=0,表示每隔一秒把log buffer刷到文件系统中(os buffer)去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。也就是说一秒之前的日志都保存在日志缓冲区,也就是内存上,如果机器宕掉,可能丢失1秒的事务数据。cndba.cn/hbhe0316/article/22631
innodb_flush_log_at_trx_commit=1,表示在每次事务提交的时候,都把log buffer刷到文件系统中(os buffer)去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。这样的话,数据库对IO的要求就非常高了,如果底层的硬件提供的IOPS比较差,那么MySQL数据库的并发很快就会由于硬件IO的问题而无法提升。cndba.cn/hbhe0316/article/22631
innodb_flush_log_at_trx_commit=2,表示在每次事务提交的时候会把log buffer刷到文件系统中去,但并不会立即刷写到磁盘。如果只是MySQL数据库挂掉了,由于文件系统没有问题,那么对应的事务数据并没有丢失。只有在数据库所在的主机操作系统损坏或者突然掉电的情况下,数据库的事务数据可能丢失1秒之类的事务数据。这样的好处,减少了事务数据丢失的概率,而对底层硬件的IO要求也没有那么高(log buffer写到文件系统中,一般只是从log buffer的内存转移的文件系统的内存缓存中,对底层IO没有压力)。
原文链接:https://blog.csdn.net/wenchun001/article/details/131397065
半同步复制的条件:
必要条件
1)MySQL5.5及以上版本
2)变量have_dynamic_loading 为YES(查看命令:show variables like "have_dynamic_loading";)
3)主从复制已经存在(即提前部署mysql主从复制环境,主从同步要配置基于整个数据库的,不要配置基于某个库的同步,即同步时不要过滤库)