一、什么是双主复制

在传统主从复制的架构中,如果主库出现故障,从库便无法再写入数据。主库故障后手动进行主从切换的过程较为繁琐。为了解决这个问题可以使用双主模式,其中一台主库提供线上服务,另一台作为备机,两台数据库使用VIP提供服务,依靠Keepalived进行故障自动切换。但是强烈不建议用双主模式来实现双写,这样数据不一致的风险非常大。如果真要开启,建议指定不同的库写入指定的节点。比如DB1的写入都在MasterA完成、DB2的写入都在Master2完成。除了双写问题以外,还有一个binlog循环复制的问题值得思考,A运行SQL生成binlog,B执行后又生成同样的SQL再次传递给A,然后一直循环下去。MySQL为了避免这个问题,会依据server id来确定角色。当主库B收到主库A的binlog进行应用时,会在自己的binlog中增加上A的server id,而主库A接收到这个binlog后先判断server id,如果跟自己的相同表示这个日志是自己生成的,就直接丢弃这个日志。

二、双主复制配置

1、修改主库A的配置文件,增加以下内容

vi /etc/my.cnf
log-slave-updates = 1  #由于可能发生身份切换,所以打开该选项,作为从库也会记录binlog
replicate_same_server_id = 0  #避免循环写入问题
auto_increment_increment=2  #自增主键步长,通常有几个主库就写几,避免主键冲突
auto_increment_offset=1  #设置自增主键起始值,第一个主库为1,第二个主库为2,以此类推

2、主库A为主库B授权 

mysql > grant replication slave on *.* to 'repl'@'192.168.1.102' identified by '123456';

3、修改主库B配置文件 

vi /etc/my.cnf
log-slave-updates = 1
replicate_same_server_id = 0
auto_increment_increment=2
auto_increment_offset=2  #主键起始值,这里应该是2了

4、主库B为主库A授权 

mysql > grant replication slave on *.* to 'repl'@'192.168.1.101' identified by '123456';  #102为另外一台主的地址

5、主库A配置主从,位置信息要在主库B服务运行后show master status查看 

mysql > change master to master_host='192.168.1.102',master_user='repl',master_password='123456',master_log_file='master-bin.000002',master_log_pos=604,master_port=3306

6、主库B配置主从,位置信息要在主库A服务运行后show master status查看 

mysql > change master to master_host='192.168.1.101',master_user='repl',master_password='123456',master_log_file='master-bin.000002',master_log_pos=604,master_port=3306

7、两台机器都启动从服务,如果配置成功的话在任意一台写入数据都可以同步到另一台机器 

mysql > start slave

二、Keepalived配置

1、在两台数据库服务器上编译安装Keepalived

./configure --prefix=/usr/local/keepalived
make
meke install

2、创建Keepalived配置文件 

cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

vi /etc/keepalived/keepalived.conf
global_defs {
  # 全局设置,主要是主备切换时发送邮件通知,可以直接注释
  # notification_email {
  #   acassen@firewall.loc
  # }
  # notification_email_from Alexandre.Cassen@firewall.loc
  # smtp_server 192.168.145.1
  # smtp_connect_timeout 30
  # router_id LVS_DEVEL
  # vrrp_skip_check_adv_addr
  # vrrp_strict
  # vrrp_garp_interval 0
  # vrrp_gna_interval 0
}

vrrp_instance mysql {  #实例名称随便取
    state MASTER  #标记该节点是master还是backup,但并不起实际作用,为了防止脑裂抢占IP可以都设置为backup
    interface eth0  #配置VIP绑定的网卡,这里使用和外网通信的网卡
    virtual_router_id 51  #取1-255之间的值,主备需要相同,这样才能成为一个组
    priority 100  #权重,数值高的主机是master,这是影响主备的关键
    nopreempt  #非抢占模式,需要设置state为backup
    advert_int 1  #主备之间通讯的间隔秒数,用于判断主节点是否存活
    authentication {
        auth_type PASS  #进行安全认证的方式,PASS或者AH方式,推荐PASS
        auth_pass 1111  #PASS的密码
    }
    virtual_ipaddress {
        192.168.145.200  #VIP地址,最多可以写20个,keepalive启动后会自动配置该处VIP
    }
    virtual_server 192.168.145.200 {  #访问VIP所转发到的后端节点配置
        delay_loop 6 
        protocol TCP
        lb_algo rr
       lb_kind DR
        real_server 192.168.145.101 3306{  #后端节点1
          weight 1        }
        
       real_server 192.168.145.102 3306{  #后端节点2
          weight 1       }
   }
}

3、启动Keepalived后观察VIP是否绑定成功即可