server1:172.25.27.101 | master节点 |
server2:172.25.27.102 | slave节点 |
1、基本概念:
server-id:服务器身份id,在初始化MySQL时,会自动生成一个server-id并写到数据目录的auto.cnf文件中,官方不建议修改,并且server-id跟GTID有密切关系,并且对于任意一个数据库节点,server-id是唯一的。
GTID:全局事务标识符,使用这个功能时,内次事务提交都会在binlog里生成一个唯一的标识符,它由UUID和事务ID组成,首次提交的事务为1,第二次为2,第三次为3,以此类推。
GTID实际上是由UUID+TID (即transactionId)组成的。其中UUID(即server_uuid) 产生于auto.conf文件(cat /data/mysql/data/auto.cnf),是一个MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增,所以GTID能够保证每个MySQL实例事务的执行(不会重复执行同一个事务,并且会补全没有执行的事务)
GTID在一组复制中,全局唯一。通过GDIT保证每个主库上提交的事务在集群中有一个唯一的ID.这种方式强化了数据库的主备一致性,故障恢复以及容错能力
主从复制,默认是通过pos复制(postion),就是说在日志文档里,将用户进行的每一项操作都进行编号(pos),每一个event都有一个起始编号,一个终止编号,我们在配置主从复制时从节点时,要输入master的log_pos值就是这个原因,要求它从哪个pos开始同步数据库里的数据,这也是传统复制技术。
异步复制的效率高,master节点不会等待slave节点
基于gtid的主从复制不容易因为master一个事件的中断而造成数据丢失而不能复制
基于position的主从复制容易因为master一个事件的中断而造成数据丢失而不能复制
2、实验原理:
在master上一个事务提交,并写入binlog里。
binlog日志发送到slave,slave接收并写入中继日志里,slave读取到这个GTID,并设置gtid_next的值。例如
set @@session。gtid_next=’=fbd841f9-5590-11e8-b819-000c29e6461e’;
然后告诉slave接下来的事务必须使用GTID,并写入它自己的binlog里。
slave检查并确认这个GTID没有被使用,如果没有被使用,那么开始执行这个事务并写入自己的binlog里
由于gtid_next的值不为空,slave不会尝试去生成一个新的gtid而是通过主从同步来获取GTID
3、master配置
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin master需要这个参数,slave不需要这个参数
server-id=1
gtid_mode=ON
enforce-gtid-consistency=true 强制开启gtid同步模式
mysql -uroot -p ZHAOjun@123
CREATE USER 'repl'@'172.25.27.%' IDENTIFIED BY 'ZHAOjun@!23'; //创建复制帐户
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.27.%'; //授予此帐户复制所需的权限
flush privileges; //刷新授权表
cat /usr/lib/mysql/auto.cnf 查看服务器uuid信息
server-uuid=413bd0a3-b028-11e9-aab7-525400835722
cd /usr/lib/mysql
mysqlbinlog mysql-bin.000002 查看事件格式
usr mysql;
show status like '%repl%'; 查看repl用户
4、slave配置
vim /etc/my.cnf
server-id=2
gtid_mode=ON
enforce-gtid-consistency=true
systemctl restart mysqld
mysql -uroot -pZHAOjun@123
#如果之前做了主从复制,那么需要重新更改复制模式
stop slave
change master to master_host='172.25.20.4',master_user='repl',master_password='YLZ123+a',master_auto_position=1;
#查看如果同步了master库则会有执行事务的id号
select * from mysql.gtid_executed;
show slave status; 如果复制了master数据,则会显示执行的事务id
select * from mysql.gtid_executed; 发现slave完成了master的所有事件
stop slave io_thread;
start slave io_thread;
5、测试
master上的操作
create database westos; 创建数据库westos
#插入数据
insert into westos.test values ('user3','333');
insert into westos.test values ('user4','333');
show processlist;
select * from westos.test;
slave上的操作
show databases; 查看数据库,是否已经同步master上的操作
select * from westos.test; 查看插入的数据
show slave status\G; 复制的事务id
Retrieved_Gtid_Set: b920c6db-b028-11e9-b2d3-525400356eac:1-2
Executed_Gtid_Set: b920c6db-b028-11e9-b2d3-525400356eac:1-2
select * from mysql.gtid_executed; 执行的事务id
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| b920c6db-b028-11e9-b2d3-525400356eac | 1 | 1 |
| b920c6db-b028-11e9-b2d3-525400356eac | 2 | 2 |
+--------------------------------------+----------------+--------------+
1、基本概念
半同步复制:一主多从模式下,有一个从节点返回成功,即成功,不必等待多个节点全部返回
该模式可以确保从服务器接收完主服务器发送的binlog日志文件并写入自己的中继日志(relay log)里,然后会给主服务器一个反馈,告诉对方已经接收到完毕,这时主库线程才返回当前session告知操作完成,当出现超时情况时,源主服务器会暂时切换到异步复制模式,直到至少有一台设置为半同步复制模式的从服务器及时收到信息为止。
异步复制可能丢失数据:半同步复制就是为了解决数据丢失问题
master做完一步等一步,需要等待至少一个slave节点完成复制之后才开始进行下一个操作
master做大事件的时候,需要进行半同步,master节点等待一个节点即可
当半同步出现问题的时候会自动切换为异步同步
银行数据库全同步,master节点等待集群中的所有全部节点
数据库要避免慢查询问题,会造成延迟,占用数据库的IO
优点:提高了数据完整性,数据至少会存在两个节点(master节点和一个slave节点)
加了消息确认ACK,不会造成数据丢失
出现问题会自动降低为异步复制
2、master操作
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 VARIABLES LIKE 'rpl_semi_sync%';查看变量的值
show status like '%rpl%';查看变量的状态
3、slave操作
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';安装半同步模块
SELECT PLUGIN_NAME, PLUGIN_STATUS设置 查看插件
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%semi%';
激活插件
SET GLOBAL rpl_semi_sync_slave_enabled = 1开启
STOP SLAVE IO_THREAD;关闭
START SLAVE IO_THREAD;开启
SHOW VARIABLES LIKE 'rpl_semi_sync%'; 查看变量
4、测试
1、server2上关闭io进程
2、server1上边
use westos
insert into usertb values ('user4','123');
等待10s,没有接收到slave的ack请求,自动转换为异步复制,需要等待一个节点完成所有的复制
insert into usertb values ('user5','123');发现特别快,已经变成异步了
show status like '%rpl%';发现半同步已经关闭OFF
有10秒的延迟,这是因为从库的io进程关闭了,不能及时的写入数据;主库等待10秒之后从库还没有起来,主库不再等待直接写入
等待完毕,10秒后直接写入
再次插入数据,主库直接写入,没有延迟
3、在server2上边启动io进程
start slave io_thread;
show processlist;
use westos
select * from usertb;发现所有的数据都过来了(基于gtid),接着上一次的事情做
半同步复制再一次失败后会自动切换成异步复制,从库进程起来之后会将没有做的事情再做一遍
注意:将插件安装在数据库中是临时的,退出重新登陆会失效,永久的可以将配置写在配置文件中