MySQL——主从复制、ssl主从复制、gtid主从复制

一、主从复制(Master-Slave)

MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展。多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能。

下图就描述了一个多个数据库间主从复制与读写分离的模型(来源网络):
MySQL——主从复制、ssl主从复制、gtid主从复制_第1张图片

在一主多从的数据库体系中,多个从服务器采用异步的方式更新主数据库的变化,业务服务器在执行写或者相关修改数据库的操作是在主服务器上进行的,读操作则是在各从服务器上进行。如果配置了多个从服务器或者多个主服务器又涉及到相应的负载均衡问题,关于负载均衡具体的技术细节先不说,先简单的实现一主一从的主从复制功能。

Mysql主从复制的实现原理图大致如下(来源网络):
MySQL——主从复制、ssl主从复制、gtid主从复制_第2张图片

MySQL之间数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。

实现MySQL主从复制需要进行的配置:

  • 主服务器:
    开启二进制日志
    配置唯一的server-id
    获得master二进制日志文件名及位置
    创建一个用于slave和master通信的用户账号
  • 从服务器:
    配置唯一的server-id
    使用master分配的用户账号读取master二进制日志
    启用slave服务

具体实现过程如下:

1、准备工作:

1)主从数据库版本最好一致
2)主从数据库内数据保持一致

master 192.168.1.133
slave 192.168.1.134

2、主数据库master修改:

1)修改mysql配置
找到主数据库的配置文件my.cnf(或者my.ini),我的在/etc/my.cnf,在[mysqld]部分插入如下两行:

[root@master ~]# vim /etc/my.cnf 
[mysqld]
……
server_id=1		# 设置server-id
log_bin = /usr/local/mysql/data/log-bin		# 开启二进制日志

[root@master ~]# systemctl restart mysqld		# 重启mysql

2)创建用于同步的用户账号

[root@master ~]# mysql -uroot -p123
mysql> grant replication slave on *.* to 'rep'@'192.168.1.%' identified by '123';

3)查看master状态,记录二进制文件名(log-bin.000001)和位置(458):

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| log-bin.000001 |      458 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

3、从服务器slave修改:

1)修改mysql配置
同样找到my.cnf配置文件,添加server-id

[root@slave ~]# vim /etc/my.cnf 
[mysqld]
……
server_id=2		# server_id要唯一,不能和其他 mysql 主机的重复
relay-log = /usr/local/mysql/data/relay-log-bin
relay-log-index = /usr/local/mysql/data/slave-relay-bin.index

[root@slave ~]# systemctl restart mysqld

2)执行同步SQL语句(需要主服务器主机名,登陆凭据,二进制文件的名称和位置):

[root@slave ~]# mysql -uroot -p123
mysql> change master to master_host='192.168.1.133',master_user='rep',master_password='123',master_log_file='log-bin.000001',master_log_pos=458;

3)启动slave同步进程:

mysql> start slave;

4)查看slave状态:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.133
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000001
          Read_Master_Log_Pos: 448
               Relay_Log_File: relay-log-bin.000003
                Relay_Log_Pos: 318
        Relay_Master_Log_File: log-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
        ...

当Slave_IO_Running和Slave_SQL_Running都为YES的时候就表示主从同步设置成功了。接下来就可以进行一些验证了,比如在主master数据库的test数据库的一张表中插入一条数据,在slave的test库的相同数据表中查看是否有新增的数据即可验证主从复制功能是否有效,还可以关闭slave(mysql>stop slave;),然后再修改master,看slave是否也相应修改(停止slave后,master的修改不会同步到slave),就可以完成主从复制功能的验证了。

还可以用到的其他相关参数:
master开启二进制日志后默认记录所有库所有表的操作,可以通过配置来指定只记录指定的数据库甚至指定的表的操作,具体在mysql配置文件的[mysqld]可添加修改如下选项:

# 不同步哪些数据库  
binlog-ignore-db = mysql  
binlog-ignore-db = test  
binlog-ignore-db = information_schema  
  
# 只同步哪些数据库,除此之外,其他不同步  
binlog-do-db = game  

如之前查看master状态时就可以看到只记录了test库,忽略了manual和mysql库。

二、实现基于 ssl 安全连接的主从复制

master 192.168.1.133
slave 192.168.1.134

1、在主 mysql 创建 SSL/RSA 文件

[root@master ~]# cd /usr/local/mysql/bin/
[root@master bin]# mysql_ssl_rsa_setup --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data		#创建新的 SSL 文件

[root@master bin]# ll /usr/local/mysql/data/
total 123000
-rw-r----- 1 mysql mysql       56 Nov 20 12:09 auto.cnf
-rw------- 1 mysql mysql     1676 Nov 20 12:09 ca-key.pem
-rw-r--r-- 1 mysql mysql     1112 Nov 20 12:09 ca.pem
-rw-r--r-- 1 mysql mysql     1112 Nov 20 12:09 client-cert.pem
-rw------- 1 mysql mysql     1676 Nov 20 12:09 client-key.pem
-rw-r----- 1 mysql mysql      280 Feb  9 22:16 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 Feb  9 22:16 ibdata1
-rw-r----- 1 mysql mysql 50331648 Feb  9 22:16 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Nov 20 12:09 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 Feb  9 22:16 ibtmp1
drwxr-x--- 2 mysql mysql     4096 Nov 20 12:09 mysql
-rw-r----- 1 mysql mysql    52248 Feb  9 22:16 mysql.err
drwxr-x--- 2 mysql mysql       52 Nov 20 12:45 mytest
drwxr-x--- 2 mysql mysql     8192 Nov 20 12:09 performance_schema
-rw------- 1 mysql mysql     1680 Nov 20 12:09 private_key.pem
-rw-r--r-- 1 mysql mysql      452 Nov 20 12:09 public_key.pem
-rw-r--r-- 1 mysql mysql     1112 Nov 20 12:09 server-cert.pem
-rw------- 1 mysql mysql     1680 Nov 20 12:09 server-key.pem
drwxr-x--- 2 mysql mysql     8192 Nov 20 12:09 sys

查看 server-key.pem 发现没有 r 权限

[root@master bin]# chmod +r /usr/local/mysql/data/server-key.pem

重启 mysqld 服务

[root@master bin]# systemctl restart mysqld

登录 mysql,执行 mysql>show variables like ‘%ssl%’;

[root@master bin]# mysql -uroot -p123
mysql> show variables like '%ssl%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | YES             |
| have_ssl      | YES             |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+

从上边可以看到 mysql 支持了 ssl 安全连接
注:启用 mysql 支持 ssl 安全连接主要用于 mysql 主从复制(局域网可以非 ssh 连接即明文复制,但 internet 复制建议采用 ssl 连接)

在主 mysql 上的操作完成,再生成一个复制帐号:REQUIRE SSL

mysql> grant replication slave on *.* to 'rep'@'192.168.1.%' identified by '123' require ssl;

在主 mysql 上启用二进制日志并重启 mysql 服务

[root@master bin]# vim /etc/my.cnf
server_id=1
log_bin = /usr/local/mysql/data/log-bin

[root@master bin]# systemctl restart mysqld		#重启 mysql 服务

查看主 mysql 的状态

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| log-bin.000001 |      154 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

注:要记住上边所显示的 file 和 position 的值,配置从服务器要用到防火墙允许 3306/tcp 通信

[root@master ~]# firewall-cmd --permanent --add-port=3306/tcp
success
[root@master ~]# firewall-cmd --reload
success

2、接着就去slave上配置

从 mysql 的/etc/my.cnf 文件内容

[root@slave ~]# vim /etc/my.cnf
server_id=2		# server_id 要唯一,不能和其他 mysql 主机的重复
relay-log = /usr/local/mysql/data/relay-log-bin
relay-log-index = /usr/local/mysql/data/slave-relay-bin.index

把主 mysql 生成的证书给了从服务器

[root@master bin]# cd ../data/
[root@master data]# scp ca.pem client-cert.pem client-key.pem [email protected]:/usr/local/mysql/data/
# 192.168.1.134 是从 mysql 的 IP 地址

查看从 mysql master 复制过来的证书

[root@slave ~]# cd /usr/local/mysql/data/
[root@slave data]# ll ca.pem client-cert.pem client-key.pem 
-rw-r--r-- 1 mysql mysql 1112 Feb  9 22:35 ca.pem
-rw-r--r-- 1 mysql mysql 1112 Feb  9 22:35 client-cert.pem
-rw------- 1 mysql mysql 1676 Feb  9 22:35 client-key.pem

设置 client-key.pem 的 r 权限

[root@slave data]# chmod +r client-key.pem 
[root@slave data]# ll client-key.pem 
-rw-r--r-- 1 mysql mysql 1676 Feb  9 22:35 client-key.pem

继续在从上配置 SSL:修改/etc/my.cnf 文件,添加如下内容

[root@slave data]# vim /etc/my.cnf
……
ssl-ca = /usr/local/mysql/data/ca.pem
ssl-cert = /usr/local/mysql/data/client-cert.pem
ssl-key = /usr/local/mysql/data/client-key.pem

[root@slave data]# systemctl restart mysqld		#重启 mysqld 服务

查看 SSL 是否被支持:

[root@slave data]# mysql -uroot -p123
mysql> show variables like '%ssl%';
+---------------+---------------------------------------+
| Variable_name | Value                                 |
+---------------+---------------------------------------+
| have_openssl  | YES                                   |
| have_ssl      | YES                                   |
| ssl_ca        | /usr/local/mysql/data/ca.pem          |
| ssl_capath    |                                       |
| ssl_cert      | /usr/local/mysql/data/client-cert.pem |
| ssl_cipher    |                                       |
| ssl_crl       |                                       |
| ssl_crlpath   |                                       |
| ssl_key       | /usr/local/mysql/data/client-key.pem  |
+---------------+---------------------------------------+

那么在配置主从复制之前可以在从 mysql slave 上用 SSL 连接主服务器试试:

[root@slave data]# cd /usr/local/mysql/data/
[root@slave data]# mysql -urep -p123 -h192.168.1.133 --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem
# 192.168.1.133 是主 mysql master 的 ip 地址

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.32, for Linux (x86_64) using  EditLine wrapper
Connection id:		6
Current database:	
Current user:		[email protected]
SSL:			Cipher in use is DHE-RSA-AES128-GCM-SHA256
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server version:		5.7.32-log Source distribution
Protocol version:	10
Connection:		192.168.1.133 via TCP/IP
Server characterset:	utf8
Db     characterset:	utf8
Client characterset:	utf8
Conn.  characterset:	utf8
TCP port:		3306
Uptime:			17 min 56 sec
Threads: 1  Questions: 12  Slow queries: 0  Opens: 108  Flush tables: 1  Open tables: 101  Queries per second avg: 0.011
--------------

mysql> quit

SSL 测试连接成功,并且登入的 SSL 协议是:Cipher in use is DHE-RSA-AES256-SHA 最后开始配置主从 replicate, 登录从 mysql

[root@slave data]# mysql -uroot -p123
mysql>

在从上 change master to

mysql> change master to master_host='192.168.1.133',master_user='rep',master_password='123',master_log_file='log-bin.000001',master_log_pos=154,master_ssl=1,master_ssl_ca='/usr/local/mysql/data/ca.pem',master_ssl_cert='/usr/local/mysql/data/client-cert.pem',master_ssl_key='/usr/local/mysql/data/client-key.pem';

启用从

mysql> start slave;

查看从的状态,以下两个值必须为 yes,代表从服务器能正常连接主服务器
Slave_IO_Running:Yes
Slave_SQL_Running:Yes

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.133
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: relay-log-bin.000004
                Relay_Log_Pos: 363
        Relay_Master_Log_File: log-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:

3、测试:

在主 mysql 上创建数据:

[root@master data]# mysql -uroot -p123
mysql> create database db1;
mysql> use db1;
mysql> create table test(id int);
mysql> insert into test values(1);
mysql> select * from test;
+------+
| id   |
+------+
|    1 |
+------+

在从slave上验证同步是否成功:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
……
| db1                |
+--------------------+
mysql> use db1;
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| test          |
+---------------+
mysql> select * from test;
+------+
| id   |
+------+
|    1 |
+------+

总结:SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security, TLS)是为网络通信提供安全及数据完整性的一种安全协议。复制默认是明文进行传输的,通过 SSL 加密可以大大提高数据的安全性。

error!Slave_IO_Running: No,Slave_SQL_Running: Yes

在show slave status时发现,那个表有一个单元格有错误的log信息:

                Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

分别查看两台服务器的 vim /usr/local/mysql/data/auto.cnf,果然UUIDs是相同的,随便改变一个数据库的UUIDs的数值,然后重启数据库

[root@slave ~]# vim /usr/local/mysql/data/auto.cnf
[auto]
server-uuid=35e27e10-2ae6-11eb-805f-000c2929015a		# 随便更改一个数值即可

[root@master ~]# systemctl restart mysqld
[root@slave ~]# systemctl restart mysqld

[root@slave data]# mysql -uroot -p123
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.133
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000004
          Read_Master_Log_Pos: 154
               Relay_Log_File: relay-log-bin.000006
                Relay_Log_Pos: 363
        Relay_Master_Log_File: log-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

解决问题
问题原因:克隆mysql服务器导致两台UUID相同

error!Mysql主从同步时Slave_IO_Running:Connecting ; Slave_SQL_Running:Yes的情况故障排除

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 192.168.1.133
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000001
          Read_Master_Log_Pos: 154
               Relay_Log_File: relay-log-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: log-bin.000001
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB:

可能导致错误的几种原因:
1.网络不通
2.账户密码错误
3.防火墙
4.mysql配置文件问题
5.连接服务器时语法
6.主服务器mysql权限

服务器IP:

master 192.168.1.133
slave 192.168.1.134

逐项排除:
1、因为从服务器是虚拟机,网卡选择了NAT模式,ip地址确认在同一网段中,且互ping能通,排除网络问题。
2、主服务器创建了账号rep密码123的权限账号,在主服务器可以登录slave帐号,排除帐号密码问题。
3、主从默认关闭防火墙,确认已关闭,排除防火墙原因。
4、配置文件
(1)查看主服务器配置文件:vim /etc/my.cnf,确认log_bin和server-id已经取消注释,设置无错误。

server_id=1
log_bin = /usr/local/mysql/data/log-bin

(2)查看从服务器:

server_id=2		此处server-id只需要与主服务器不同即可
relay-log = /usr/local/mysql/data/relay-log-bin
relay-log-index = /usr/local/mysql/data/slave-relay-bin.index
ssl-ca = /usr/local/mysql/data/ca.pem
ssl-cert = /usr/local/mysql/data/client-cert.pem
ssl-key = /usr/local/mysql/data/client-key.pem

5、语法:
(1)查看主服务器二进制日志信息show master status;

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| log-bin.000002 |      154 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+

(2)设置从服务器链接到master主服务器,确认语句无错误,排除。

mysql> change master to master_host='192.168.1.133',master_user='rep',master_password='123',master_log_file='log-bin.000001',master_log_pos=154,master_ssl=1,master_ssl_ca='/usr/local/mysql/data/ca.pem',master_ssl_cert='/usr/local/mysql/data/client-cert.pem',master_ssl_key='/usr/local/mysql/data/client-key.pem';
# master_host:主服务器Ubuntu的ip地址
# master_log_file: 前面查询到的主服务器日志文件名
# master_log_pos: 前面查询到的主服务器日志文件位置

6、权限:
(1)主服务器查看rep帐号,已设置登录ip为192.168.1.%

mysql> select user,host from mysql.user;
+---------------+-------------+
| user          | host        |
+---------------+-------------+
| rep           | 192.168.1.% |
| mysql.session | localhost   |
| mysql.sys     | localhost   |
| root          | localhost   |
+---------------+-------------+

(2)在从服务器上登录主服务器rep帐号测试:

[root@slave ~]# mysql -urep -p123 -h192.168.1.133
……
mysql>

如果无法登录主服务器!打开主服务器配置文件有一条绑定主机ip的语句,问题出在这里!!!给它注释掉!保存退出。重启主服务器数据库:systemctl restart mysqld
(3)重新测试从服务器上登录主服务器slave帐号:登录成功!
(4)重新进入从服务器链接master主服务器,start slave开启主从同步,输入show slave status \G查看从服务器状态,若开启不成功先stop slave,再start slave,可以看到Slave_IO_Runninghe和Slave_SQL_Running状态都是Yes,同步成功。

三、GTID 主从复制

MySQL 5.6引入的GTID(Global Transaction IDs全局事务标志)使得其复制功能的配置、监控及管理变得更加易于实现,且更加健壮

GTID的概念:
1)全局事务标识:global transaction identifiers。
2)GTID是一个事务一一对应,并且全局唯一ID。
3)一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
4)GTID用来代替传统复制方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。
5)MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。
6)在传统的slave端,binlog是不用开启的,但是在GTID中slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。

GTID组成:
GTID = source_id:transaction_id
source_id,用于鉴别原服务器,即mysql服务器唯一的的server_uuid,由于GTID会传递到slave,所以也可以理解为源ID。
transaction_id,为当前服务器上已提交事务的一个序列号,通常从1开始自增长的序列,一个数值对应一个事务。
示例:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
前面的一串为服务器的server_uuid,即3E11FA47-71CA-11E1-9E33-C80AA9429562,后面的23为transaction_id

GTID原理:
1、当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
2、binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
5、如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。

gtid 异步复制

1、配置主从节点的服务配置文件
配置master节点

[root@master ~]# vim /etc/my.cnf 
[mysqld]
……
server_id=1
log_bin = /usr/local/mysql/data/log-bin
gtid_mode=ON		# 开启gtid模式
enforce_gtid_consistency=true		# 强制gtid一直性,用于保证启动gitd后事务的安全

[root@master ~]# systemctl restart mysqld

配置slave节点

[root@slave ~]# vim /etc/my.cnf 
[mysqld]
……
server_id=2
log_bin = /usr/local/mysql/data/log-bin
gtid_mode=ON		# 开启gtid模式
enforce_gtid_consistency=true		# 强制gtid一直性,用于保证启动gitd后事务的安全

[root@slave ~]# systemctl restart mysqld

2、master 创建复制用户

[root@master ~]# mysql -uroot -p123
mysql> grant replication slave on *.* to 'rep'@'192.168.1.%' identified by '123';

3、为备节点提供初始数据集
锁定主表,备份主节点上的数据,将其还原至从节点;如果没有启用GTID,在备份时需要在master上使用show master status命令查看二进制日志文件名称及事件位置,以便后面启动slave节点时使用。

4、启动从节点的复制线程

[root@slave ~]# mysql -uroot -p123
mysql> change master to master_host='192.168.1.133',master_user='rep',master_password='123',master_auto_position=1;
mysql> start slave;
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.133
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000001
          Read_Master_Log_Pos: 446
               Relay_Log_File: slave-relay-bin.000003
                Relay_Log_Pos: 655
        Relay_Master_Log_File: log-bin.000001
             Slave_IO_Running: Yes		#这两行为yes代表连接成功
            Slave_SQL_Running: Yes		#
              Replicate_Do_DB: 

MASTER_AUTO_POSITION:该参数在mysql5.6.5版本引入,如果进行change master to时使用MASTER_AUTO_POSITION = 1,slave连接master将使用基于GTID的复制协议。使用基于GTID协议的复制,slave会告诉master它已经接收到或执行了哪些事务。使用基于GTID的复制时(MASTER_AUTO_POSITION = 1),首先要开启gtid_mode(在my.cnf中设置gtid-mode = ON),

5、验证
master插入数据

mysql> create database aaa;
mysql> use aaa;
mysql> create table a(id int);
mysql> insert into a values(1);
mysql> insert into a values(2);
mysql> select * from aaa.a;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+

slave查看

mysql> select * from aaa.a;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+

gtid 半同步复制

默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能, 主库把binlog日志发送给从库,这一动作就结束了,并不会验证从库是否接收完毕,这一过程,也就意味着有可能出现当主服务器或从服务器端发生故障的时候,有可能从服务器没有接收到主服务器发送过来的 binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失。注意:半同步复制模式必须在主服务器和从服务器端同时开启,否则主服务器默认使用异步复制模式。
1、master

mysql> show global variables like 'have_dynamic_loading';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| have_dynamic_loading | YES   |
+----------------------+-------+

mysql> show global variables like 'plugin_dir';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| plugin_dir    | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+

# 安装插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
# rpl_semi_sync_master_enabled 参数控制主节点是否开启半同步复制;
# rpl_semi_sync_master_timeout 参数控制主节点等待备节点返回确认信息的超时时间,单位为毫秒,超过这个时间后半同步复制转变成异步复制;

# 查看是否安装成功
mysql> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
+----------------------+---------------+
| plugin_name          | plugin_status |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+

# 激活插件
mysql> set global rpl_semi_sync_master_enabled=1;
或↑↓
mysql> set global rpl_semi_sync_master_enabled=ON;
或↑↓
[root@master ~]# vim /etc/my.cnf 
[mysqld]
……
rpl_semi_sync_master_enabled=ON
[root@master ~]# systemctl restart mysqld

2、slave

# 安装插件
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

# 激活插件
mysql> set global rpl_semi_sync_slave_enabled=1;	# rpl_semi_sync_master_enabled 参数控制主节点是否开启半同步复制
或↑↓
[root@slave ~]# vim /etc/my.cnf 
[mysqld]
……
rpl_semi_sync_slave_enabled=ON

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

master查看参数

mysql> show status like '%rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+

3、slave 关闭 I/O 线程

mysql> stop slave io_thread;

4、验证
master 修改数据

mysql> create database ooo;		#插入字段会有卡顿默认时间是10s,10s过后会自动变成异步复制
mysql> use ooo;
mysql> create table o(id int);
mysql> insert into o values(1);
mysql> insert into o values(2);
mysql> select * from ooo.o;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+

mysql> show status like '%rpl_semi_sync%';		#一些参数的值也会变化
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 4     |
| Rpl_semi_sync_master_status                | OFF   |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+

slave 查看;打开 io_thread;再查看

mysql> select * from ooo.o;
ERROR 1146 (42S02): Table 'ooo.o' doesn't exist

mysql> start slave io_thread;		# 打开slave io_thread

mysql> select * from ooo.o;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+

master查看信息

mysql> show processlist;
+----+------+---------------------+------+------------------+------+---------------------------------------------------------------+------------------+
| Id | User | Host                | db   | Command          | Time | State                                                         | Info             |
+----+------+---------------------+------+------------------+------+---------------------------------------------------------------+------------------+
|  2 | root | localhost           | ooo  | Query            |    0 | starting                                                      | show processlist |
|  5 | rep  | 192.168.1.134:41312 | NULL | Binlog Dump GTID |  125 | Master has sent all binlog to slave; waiting for more updates | NULL             |
+----+------+---------------------+------+------------------+------+---------------------------------------------------------------+------------------+

你可能感兴趣的:(数据库,mysql)