借鉴大佬文章:https://www.lagou.com/lgeduarticle/89886.html
二、基于二进制日志的复制
2.1 复制原理
MySQL 的复制原理如下图所示:
- 主库首先将变更写入到自己的二进制日志中;
- 备库会启动一个 IO 线程,然后主动去主库节点上获取变更日志,并写入到自己的中继日志中。
- 之后从中继日志中读取变更事件,在从库上执行变更。
- 当备库与主库数据状态一致,备库的 IO 线程就会进入睡眠。当主库再次发生变更时,其会向备库发出信号,唤醒 IO 线程并再次进行工作。
如果没有进行任何配置,主库在将变更写入到二进制日志后,就会返回对客户端的响应,因此默认情况下的复制是完全异步进行的,主备之间可能会短暂存在数据不一致的情况。
2.3 优缺点
基于二进制日志的复制是 MySQL 最早使用的复制技术,因此 MySQL 对其的支持比较完善,对执行修改的 SQL 语句几乎没有任何限制。其主要的缺点是在一主多从的高可用复制架构中,如果主库发生宕机,此时想要自动通过从库的日志和偏移量来确定新的主库比较困难。
2.3 优缺点
GTID 复制的优点在于程序可以自动确认开始复制的 GTID 点。但其仍然存在以下限制:
-
不支持 CREATE TABLE ... SELECT 语句。 因为在 ROW 格式下,该语句将会被记录为具有不同 GTID 的两个事务,此时从服务器将无法正确处理。
-
事务,过程,函数和触发器内部的 CREATE TEMPORARY TABLE 和 DROP TEMPORARY TABLE 语句均不受支持。
三、基于 GTID 的复制
2.1 GTID 简介
MySQL 5.6 版本之后提供了一个新的复制模式:基于 GTID 的复制。GTID 全称为 Global Transaction ID,即全局事务 ID。它由每个服务节点的唯一标识和其上的事务 ID 共同组成,格式为: server_uuid : transaction_id 。通过 GTID ,可以保证在主库上的每一个事务都能在备库上得到执行,不会存在任何疏漏。
配置gtid
这里是为让第二个实例在主库宕机时做新的主库,所以也配置了二进制日志
[mysqld1]
gtid-mode=ON
enforce-gtid-consistency=ON # 强制GTID的一致性
log_timestamps=SYSTEM
log-bin=/home/mysql/3306/mysql-bin
log-error=/home/mysql/3306/mysqld.log
binlog_format=mixed
server-id = 1
expire_logs_days = 0
[mysqld2]
gtid-mode=ON
enforce-gtid-consistency=ON # 强制GTID的一致性
log_timestamps=SYSTEM
log-bin=/home/mysql/3307/mysql-bin
log-error=/home/mysql/3307/mysqld.log
binlog_format=mixed
server-id = 2
expire_logs_days = 0
relay_log = /home/mysql/3307/mysql-relay-bin
# 是否将中继节点收到的复制事件写到自己的二进制日志中
log_slave_updates = 1
# 为了保证数据的一致性,从节点应该设置为只读
read_only = 1
[mysqld3]
port = 3308
socket = /tmp/mysql3308.sock
datadir = /home/mysql/3308/
pid-file = /home/mysql/3308/mysqld.pid
skip-external-locking
character-set-server = utf8
secure_file_priv=
gtid-mode=ON
enforce-gtid-consistency=ON # 强制GTID的一致性
explicit_defaults_for_timestamp = true
log_timestamps=SYSTEM
# log-bin=/home/mysql/3308/mysql-bin
log-error=/home/mysql/3308/mysqld.log
# binlog_format=mixed
server-id = 3
expire_logs_days = 0
relay_log = /home/mysql/3308/mysql-relay-bin
# 是否将中继节点收到的复制事件写到自己的二进制日志中
# log_slave_updates = 1
# 为了保证数据的一致性,从节点应该设置为只读
read_only = 1
创建复制用户并授权(主库)
CREATE USER 'repl'@'***.***.***.***' IDENTIFIED BY '*******';
grant replication slave on *.* to 'repl'@'***.***.***.***';
开启复制(从库)
change master to master_host='***.***.***.***',master_port=****,master_user='repl',master_password='******',master_auto_position=1;
master_auto_position=1代表启用gtid复制
2.3 优缺点
GTID 复制的优点在于程序可以自动确认开始复制的 GTID 点。但其仍然存在以下限制:
-
不支持 CREATE TABLE ... SELECT 语句。 因为在 ROW 格式下,该语句将会被记录为具有不同 GTID 的两个事务,此时从服务器将无法正确处理。
-
事务,过程,函数和触发器内部的 CREATE TEMPORARY TABLE 和 DROP TEMPORARY TABLE 语句均不受支持。
为防止执行不受支持的语句,建议配置和上文配置一样,开启 enforce-gtid-consistency 属性, 开启后在主库上执行以上不受支持的语句都将抛出异常并提示。
mysql> create table test2 select * from test;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.