GTID概念
从MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
开启GTID的好处
GTID相对于行复制数据安全性更高,故障切换更简单。
1) 根据 GTID 可以快速的确定事务最初是在哪个实例上提交的。
2) 简单的实现 failover,不用以前那样在需要找 log_file 和 log_pos。
3) 更简单的搭建主从复制,确保每个事务只会被执行一次。
4) 比传统的复制更加安全,一个 GTID 在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
5)GTID是连续的没有空洞的,保证数据的一致性,零丢失
6)GTID 用来代替classic的复制方法,不再使用 binlog+pos 开启复制。而是使用 master_auto_postion=1 的方式自动匹配 GTID 断点进行复制。
7) GTID 的引入,让每一个事务在集群事务的海洋中有了秩序,使得 DBA 在运维中做集群变迁时更加方便
如何开启
只需要在my.cnf中添加:
# 开启gtid
gtid_mode=ON
enforce-gtid-consistency=true
然后执行:
stop slave;
change master to master_host='主库的IP',master_port=3306,master_user='slaveuser',master_password='password',master_auto_position = 1;
start slave;
跟之前对比,不需要再去查master_log_file
和master_log_pos
,直接用master_auto_position = 1
代替即可。
注意事项
需要在主库和从库都开启才有效。
查看GTID是否开启
show variables like 'gtid_mode'
实战
环境说明
准备两台数据库A和B,其中A为正在使用的线上环境的数据库,B为将要添加的数据库。最终A和B为主主关系。
开启同步及GTID
修改数据库A的my.cnf文件,在末尾添加:
[mysqld]
log-bin=mysql-bin
binlog_format=mixed
server-id=1
log-slave-updates
slave-skip-errors=all
binlog-ignore-db=mysql,sys,performance_schema,information_schema
replicate-ignore-db=mysql,sys,performance_schema,information_schema
# 开启gtid
gtid_mode=ON
enforce-gtid-consistency=true
B的my.cnf也添加以上内容,但需要将server-id改为其他数字,不能与A一样。例如改成server-id=2
创建同步账号
在A和B库执行如下语句添加一个账号为slaveuser,密码为password的同步账号。
SET SQL_LOG_BIN=0;
CREATE USER slaveuser@'%' IDENTIFIED WITH mysql_native_password BY 'password';
grant replication slave on *.* to slaveuser@'%';
flush privileges;
SET SQL_LOG_BIN=1;
重启mysql
分别重启A库和B库
配置同步
在A库执行:
stop slave;
change master to master_host='B库的数据库地址',master_port=3306,master_user='slaveuser',master_password='password',master_auto_position = 1;
start slave;
在B库执行:
stop slave;
change master to master_host='A库的数据库地址',master_port=3306,master_user='slaveuser',master_password='password',master_auto_position = 1;
start slave;
检查同步
分别在A库和B库执行:
show slave status;
如果这两个字段都为Yes,则表明同步已正常开启。
测试同步
修改A库和B库的数据内容,检查是否同步。
故障模拟
下面模拟A库挂掉,程序切换至B库,重新搭建A库并加入同步的过程。
模拟A库挂掉
在A库执行以下代码,搞坏A库的mysql以及数据。我这里使用的是宝塔安装的mysql,所以mysql的安装位置是:/www/server/mysql
,数据存放在/www/server/data
,需要根据你的实际情况修改。
#结束mysql进程
pkill -9 mysqld
#卸载mysql
rm -rf /www/server/mysql
#删除数据库文件
rm -rf /www/server/data
执行以上语句后,A库的mysql已打不开了,且数据也丢失了。
业务系统切换至B库
修改业务系统的数据库连接地址,改成B库的地址,让业务系统继续运转。
A库重装mysql
略。
修改A库my.cnf
在末尾添加:
[mysqld]
log-bin=mysql-bin
binlog_format=mixed
server-id=1
log-slave-updates
slave-skip-errors=all
binlog-ignore-db=mysql,sys,performance_schema,information_schema
replicate-ignore-db=mysql,sys,performance_schema,information_schema
# 开启gtid
gtid_mode=ON
enforce-gtid-consistency=true
创建同名数据库
在A库创建一个跟B库同名的数据库,最好密码也一致,方便管理。
从B库复制数据到A库
从B库复制数据到A库。由于业务系统已切换到B库,意味着B库的数据随时在变动。后面配置好同步后,A库会自动更新到最新的B库的数据。
创建同步账号
在A库创建同步账号:
CREATE USER slaveuser@'%' IDENTIFIED WITH mysql_native_password BY 'password';
grant replication slave on *.* to slaveuser@'%';
flush privileges;
重启A库mysql
重启A库的mysql服务。
配置同步
在A库上执行:
stop slave;
change master to master_host='B库的地址',master_port=3306,master_user='slaveuser',master_password='abc123456',master_auto_position = 1;
start slave;
在B库上执行:
stop slave;
change master to master_host='A库的地址',master_port=3306,master_user='slaveuser',master_password='abc123456',master_auto_position = 1;
start slave;
检查同步情况。
挺不错的,而且试了有效果,感谢分享。另外我有个疑问,如果是三台或三台以上又应该怎么配置呢?