MySQL主从复制(6)——GTID复制
基于GTID的复制是从 MySQL5.6 开始支持的一种复制方式,GTID称为全局事务ID(Global Transaction ID),保证为每一个在主服务器上提交的事务在复制集群中可以生成一个全局唯一的ID。GTID 使 MySQL 的主从复制变得更加简单,数据库一致性更可靠。
GITD 由服务器ID(source_id)以及事务ID(transaction_id)组合而成:(1)source_id 就是执行事务的主数据库的 server-uuid 值,server-uuid 保存在数据库的数据目录中的 auto.conf 文件中。(2)事务ID是从1开始自增的序列,表示某个事务是在主库上执行的第几个事务。
一、GITD 复制概述
1、GITD 复制的特点
基于 GITD 的复制与基于日志的复制的不同点:
(1)在基于日志的复制中,从服务器连接到主服务器并告诉主服务器要从哪个二进制日志的偏移量开始执行增量同步;
(2)在基于GTID的复制中,首先从服务器会告诉主服务器已经在从服务器执行完了哪些事务的 GTID 值,然后主库会把所有没有在从库上执行的事务,发送到从库上进行执行。并且同一个事务在指定的从库上只执行一次,可以避免重复执行导致数据混乱或者主从不一致的问题。
和传统的基于日志的复制方式相比,基于 GITD 的复制有以下特点:
(1)GTID 不再使用 MASTER_LOG_FILE 和 MASTER_LOG_POS 开启复制,而是使用MASTER_AUTO_POSTION=1的方式开始复制。
(2)在 GTID 复制方式下,slave 端的 binlog 必须开启,用来记录执行过的 GTID。而在基于日志的复制方式下,slave 端的 binlog 是不用开启的。
2、GTID 复制的工作原理
GTID 复制的工作原理如下:
(1)当一个事务在主库执行并提交时,产生 GTID,并记录到 binlog 日志中;
(2)binlog 传输到 slave,并存储到 slave 的 relaylog,读取这个 GTID 的值并设置 gtid_next 变量,即告诉Slave,下一个要执行的 GTID 值。
(3)SQL 线程从 relay log 中获取 GTID,然后对比 slave 端的 binlog 是否有该 GTID。如果有记录,说明该 GTID 的事务已经执行,slave 会忽略;如果没有记录,slave 就会执行该 GTID 事务,并记录该 GTID 到自身的 binlog,在读取执行事务前会先检查其他 session 持有该 GTID,确保不被重复执行。
二、GITD 复制的配置
1、操作环境
操作系统:CentOS Linux release 7.8.2003 (Core)
MySQL版本:MySQL5.7
主服务器IP:192.168.1.11
从服务器IP:192.168.1.12
2、修改主服务器和从服务器的配置文件
(1)配置主服务器的 my.cnf 文件,在配置文件中添加以下内容:
[mysqld]
server-id = 1
gtid_mode = on # 开启gtid模式
enforce_gtid_consistency = on # 强制gtid一致性
log_bin = mysql-master-binlog
log-slave-updates = 1
binlog_format = row # 二进制日志的模式建议使用row
skip_slave_start = 1
(2)配置从服务器的 my.cnf 文件,在配置文件中添加以下内容:
[mysqld]
server-id = 2
gtid_mode = on
enforce_gtid_consistency = on
log-bin = mysql-slave-binlog
log-slave-updates = 1
binlog_format = row
read-only = on
skip_slave_start = 1
3、创建复制账号
mysql> grant replication slave on *.* to 'repl'@'192.168.1.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
4、对主库的数据进行备份
执行以下的备份命令,备份所有的数据库和表:
[root@localhost data]# mysqldump -uroot -p123456 -A -B > /tmp/all.sql
5、把主库的备份恢复到从库
把主库的备份文件复制到从库,然后执行导入。
(1)把主库的备份文件复制到从库
[root@localhost data]# scp /tmp/all.sql 192.168.1.12:/tmp/
The authenticity of host '192.168.1.12 (192.168.1.12)' can't be established.
ECDSA key fingerprint is SHA256:0yqIuKW/XcSZS5t++Is1bOyYz67wUryyULbXgTc/HuY.
ECDSA key fingerprint is MD5:12:74:ba:b6:74:0c:6e:b1:59:ab:55:8d:60:18:3f:87.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.12' (ECDSA) to the list of known hosts.
[email protected]'s password:
all.sql 100% 785KB 28.3MB/s 00:00
[root@localhost data]#
(2)重置日志文件
mysql> reset master;
Query OK, 0 rows affected (0.02 sec)
(3)在从库导入数据
[root@localhost data]# mysql -uroot -p123456 < /tmp/all.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@localhost data]#
6、在从库设置复制信息
在从库执行如下命令:
CHANGE MASTER TO
MASTER_HOST='192.168.1.11',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_AUTO_POSITION = 1;
7、启动 slave,查看从库状态
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.11
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-master-binlog.000001
Read_Master_Log_Pos: 2776
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 444
Relay_Master_Log_File: mysql-master-binlog.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 2776
Relay_Log_Space: 655
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 19dc9ca1-c59e-11ea-9f11-000c296166d5
Master_Info_File: /usr/local/mysql/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set: 19dc9ca1-c59e-11ea-9f11-000c296166d5:1-11
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
8、验证
(1)在主库修改数据
mysql> select * from stu;
+------+------+------+
| s_id | name | age |
+------+------+------+
| 1 | Jack | 20 |
| 2 | Tom | 20 |
| 3 | Rose | 21 |
+------+------+------+
3 rows in set (0.00 sec)
mysql>
mysql>
mysql> update stu set age=age+1;
Query OK, 3 rows affected (0.01 sec)
Rows matched: 3 Changed: 3 Warnings: 0
(2)查看从库数据
mysql> use hist;
Database changed
mysql> select * from stu;
+------+------+------+
| s_id | name | age |
+------+------+------+
| 1 | Jack | 21 |
| 2 | Tom | 21 |
| 3 | Rose | 22 |
+------+------+------+
3 rows in set (0.00 sec)