先来了解下同步复制和异步复制的概念:

同步复制:
    客户端提交事务,首先会在主服务器数据区域中存储下来,而后事件再写入到二进制日志中,同时,主服务器上的二进制日志文件要写入到从服务器中的中继日志中去,并且由从服务器上的sql thread在本地执行一遍,保存到自己的数据区域,然后通知主服务器同步完成,主服务器再响应给客户端 ,这种机制耗费时间较长,会造成服务器性能降低;
异步复制:
    客户端提交一个新事务,它只要记录到二进制日志文件中就会立即响应给客户端,至于从服务器是否将数据同步过去了,它不做关心,而是由从服务器自身通过各种机制将数据同步;
 
而在mysql主从复制模型下,主从服务器是异步复制的,也就是说,主服务器在发送给从服务器新的事务后,是不会关心从服务器是否同步的进度的,假如说,用户请求的事务过多,从服务器复制滞后于主服务器,而这个时候恰好主服务器crash(宕机)了,就会导致从服务器所复制的数据不完整,那么这个时候,我们就无法通过从服务器来恢复数据了!!
 
而半同步复制在一定程度上解决了这个问题,它通过google补丁,可以在主从服务器中安装对应的插件,以实现半同步的机制(对应插件在安装mysql的的库目录下);
 
半同步的工作机制和同步一样,是等到从服务器将同步过来的数据在本地存储之后,通知给主服务器,主服务器再响应给客户端;这种机制和同步又不同,当它应用在一主多从的模型中,只要有一台从服务器将数据存储成功,通知给主服务器,主服务器就会响应给客户端了,还可以通过设置从通知主的超时时间,如果从服务器超过了通知时间,会自动降级为异步模式;
 
半同步复制配置:
环境:
Red Hat Enterprise Linux Server release 5.8 
主服务器:IP : 172.16.9.1    
从服务器:IP :172.16.9.2
mysql版本:mysql-5.5.28
 
Master
 
  1. vim /etc/my.cnf 
  2. datadir=/data/mydata 
  3. server-id = 1 
  4. log-bin = /bin/log/mysql-bin 
  5. sync_binlog = 1 
启动服务
 
  1. service mysqld start 
进入数据库
 
  1. mysql> grant replication client,replication slave on *.* to 'rpuser'@'172.16.9.2' identified by 'redhat'; 
  2. mysql> flush privileges; 
  3. mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';  #为主服务器安装插件
  4. mysql> set global rpl_semi_sync_master_enabled=1;  #设定启用半同步机制
  5. mysql> set global rpl_semi_sync_master_timeout=1000;  #设定通知的超时时间,单位是毫秒,这里设置为1秒
  6. mysql> show master status;  #记录二进制文件以及所在位置
  7. +------------------+----------+--------------+------------------+ 
  8. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
  9. +------------------+----------+--------------+------------------+ 
  10. | mysql-bin.000004 |      354 |              |                  | 
  11. +------------------+----------+--------------+------------------+ 
  12. 1 row in set (0.00 sec) 
Slave
 
  1. vim /etc/my.cnf 
  2. datadir = /data/mydata 
  3. server-id = 5 
  4. relay-log = /relaylog/mysql-relay  #开启中继日志功能 
  5. relay-log-index = /relaylog/mysql-relay.index   #开启中继日志的索引功能 
  6. read-only = 1          #只读功能 
  7. #bin-log = mysql-bin   #关闭二进制日志功能 
 
开启服务
 
  1. service mysqld start 
进入数据库,设定其主服务器
 
  1. mysql> change master to  master_host='172.16.9.1'master_user='reuser'master_password='reuser'master_port=3306master_log_file='mysql-bin.000004'master_log_pos=354
  2. mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; 
  3. mysql> set global rpl_semi_sync_slave_enabled=1;  #开启半同步机制
  4. mysql> start slave;
  5. mysql> show slave status\G; 
  6. *************************** 1. row *************************** 
  7.                Slave_IO_State: Waiting for master to send event 
  8.                   Master_Host: 172.16.9.1 
  9.                   Master_User: reuser 
  10.                   Master_Port: 3306 
  11.                 Connect_Retry: 60 
  12.               Master_Log_File: mysql-bin.000004 
  13.           Read_Master_Log_Pos: 354 
  14.                Relay_Log_File: mysql-relay.000011 
  15.                 Relay_Log_Pos: 500 
  16.         Relay_Master_Log_File: mysql-bin.000004 
  17.              Slave_IO_Running: Yes 
  18.             Slave_SQL_Running: Yes 
  19. …………………………………………………………………………………………………………………………………………
以上在mysql中的变量操作只是临时生效,如果想让其永久生效,可以将其写入到主配置文件中;
 
Master
 
  1. vim /etc/my.cnf 
  2. 在[mysqld]字段中添加 
  3. rpl_semi_sync_master_enabled=1   
  4. rpl_semi_sync_master_timeout=1000  
Slave
 
  1. 在[mysqld]字段中添加 
  2. rpl_semi_sync_slave_enabled=1 
在主从服务器上各自重启mysqld服务,即可生效
 
查看半同步机制是否生效:
Master

MySQL复制篇之---半同步复制_半同步

以上变量中clients选项中值为1,说明半同步构建成功!!
 
Slave

MySQL复制篇之---半同步复制_主从_02

从服务器端状态也为ON,主从半同步复制构建成功!!
 
如果你在主服务器中操作了一些需要同步的语句,一些和同步等待时间的变量值就会改变的。。
如图:
 

MySQL复制篇之---半同步复制_主从_03

至此,半同步主从复制完成!!