先说一下我的环境:
这里我用的是虚拟机,系统是Centos7,安装mysql 用的是 docker
一主两从配置:
主库: 192.168.31.24
从库1: 192.168.31.23
从库2: 192.168.31.22
Centos7安装Docker-ce
Docker安装mysql 以及 redis
用Docker 安装好 mysql之后,需要修改两处设置
vi /usr/local/docker/mysql/conf/my.cnf
追加配置
server_id=1 log-bin=master-bin-log
重启mysql镜像
docker restart mysql
用 navicat 连接到mysql,在 数据库名为 performance_schema
的库里面执行
show variables like '%server_id%';
show master status;
如果显示为配置文件中的数据,说明就生效了
然后在 数据库名为 mysql
的库里面执行这两条sql
GRANT ALL PRIVILEGES ON *.* TO 'slave'@'192.168.31.%' IDENTIFIED BY 'root123456' WITH GRANT OPTION;
flush privileges;
vi /usr/local/docker/mysql/conf/my.cnf
追加配置
server_id=101 binlog_do_db=user binlog_do_db=account binlog_do_db=rule
binlog_do_db
就是要同步的库,多个库的话,就像我一样设置,要确保主库和从库都有这些数据库,并且表名和字段结构都一样,
如果不设置 binlog_do_db
,就是同步所有库
binlog_ignore_db
这个表示不需要同步的库
重启mysql
docker restart mysql
用 navicat 连接到mysql,在 数据库名为 performance_schema
的库里面执行
show variables like '%server_id%';
如果显示为配置文件中的数据,说明就生效了
从库执行
stop slave; change master to master_host='192.168.31.24', master_user='slave', master_password='root123456', master_log_file='master-bin-log.000002', master_log_pos=154; start slave;
master_log_file
和 master_log_pos
是主库执行 show master status;
查询到的数据
到这里主从 同步就搭建完成了
我们今天谈论第二种架构。我们知道,普通的replication,即MySQL的异步复制,依靠MySQL二进制日志也即binary log进行数据复制。比如两台机器,一台主库(master),另外一台是从库(slave)。
正常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave的io线程接收到t1并写入到自己的的relay log;slave的sql线程写入到本地数据库。 这时,master和slave都能看到这条新的事务,即使master挂了,slave可以提升为新的master。
异常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave因为网络不稳定,一直没有收到t1;master挂掉,slave提升为新的master,t1丢失。
很大的问题是:主库和从库事务更新的不同步,就算是没有网络或者其他系统的异常,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。
为了弥补以上几种场景的不足,MySQL从5.5开始推出了半同步复制。相比异步复制,半同步复制提高了数据完整性,因为很明确知道,在一个事务提交成功之后,这个事务就至少会存在于两个地方。即在master的dumper线程通知slave后,增加了一个ack(消息确认),即是否成功收到t1的标志码,也就是dumper线程除了发送t1到slave,还承担了接收slave的ack工作。如果出现异常,没有收到ack,那么将自动降级为普通的复制,直到异常修复后又会自动变为半同步复制
半同步复制具体特性:
追加修改主库配置文件:
plugin-load=rpl_semi_sync_master=semisync_master.so rpl_semi_sync_master_enabled=1
追加修改从库配置文件:
plugin-load=rpl_semi_sync_slave=semisync_slave.so rpl_semi_sync_slave_enabled=1
然后重启主库,从库
然后主库添加数据:
执行了10s,原因是期间主库一直在等待从库返回确认消息,没有从库开启同步,所以才会执行了10s
然后主库添加数据:
ok了