数据库
首页 > 数据库> > MySQL主从复制最全面理解笔记(原因 原理 步骤 同步模式 GTID)

MySQL主从复制最全面理解笔记(原因 原理 步骤 同步模式 GTID)

作者:互联网

简介

常见模式
常见的主从模式有如下几种,具体的模式也得看实际的业务需要。根据实际的情况,选择合适的一种架构模式。

配置流程
在本文演示中,采用一主一从的架构模式。

角色IP 地址端口号server-id
master192.168.0.11233041
slave192.168.0.11233052

要开启主从复制,首先要遵循下面几种条件。

master 操作
将下面的一段配置添加到 master 配置文件中,重启服务让配置生效。

server_id               = 1
log_bin                 = mysql-bin
binlog_format           = ROW

接下来登录到 master 命令行操作界面,创建一个主从复制的账号。这里创建一个账号为 slave_user,密码为 123456 的账号。

grant replication slave on *.* to 'slave_user'@'%' identified by '123456';
flush privileges;

查看 master 的 binary log 文件和 postion。记录下来待会在 slave 上设置主节点信息时需要使用。

mysql root@127.0.0.1:(none)> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000062 | 728      |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set
Time: 0.011s

slave 操作
将下面的配置项添加到 slave 配置文件中,重启服务让配置生效。

server_id               = 2
log_bin                 = mysql-bin
binlog_format           = ROW
log_slave_updates		= ON
read_only				= ON
super_read_only			= ON

接下来登录到 slave 命令行操作界面,设置主节点信息。

change master to master_host='192.168.0.112',master_port=3304,master_user='slave_user',master_password='123456',master_log_file='mysql-bin.000062',master_log_pos=728;
start slave;
stop slave;

配置主节点的信息之后,还不能进行主从复制,还需要我们开启主从复制。

效果演示
在配置之前,在 master 上实现有这样一张表,表结构如下:

CREATE TABLE `mysql_test`.`master_slave_demo`  (
  `id` int(10) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

在配置主从复制之前,我们在从服务器上也同样创建一张这样的表,库名和表名与 master 保持一致。
假设你都做好了这些工作,此时我们在 master 上 insert 一条数据,然后去 slave 查看是否有新的数据。

mysql root@127.0.0.1:mysql_test> insert into `master_slave_demo` (`name`) value ('FFFFFF');
Query OK, 1 row affected
Time: 0.016s
mysql root@127.0.0.1:mysql_test> select * from `master_slave_demo`;
+----+--------+
| id | name   |
+----+--------+
| 1  | 张三   |
| 2  | 李四   |
| 3  | 王五   |
| 4  | 赵六   |
| 5  | AA     |
| 6  | BB     |
| 7  | CC     |
| 8  | DD     |
| 9  | EE     |
| 10 | FFFFFF |
+----+--------+
10 rows in set
Time: 0.011s

此时登录到 slave 查看是否有新的数据。

mysql root@127.0.0.1:mysql_test> select * from master_slave_demo;
+----+--------+
| id | name   |
+----+--------+
| 1  | 张三   |
| 2  | 李四   |
| 3  | 王五   |
| 4  | 赵六   |
| 7  | CC     |
| 8  | DD     |
| 9  | EE     |
| 10 | FFFFFF |
+----+--------+
8 rows in set
Time: 0.013s

此时发现我们的数据已经自动同步过来了,到此我们的主从复制也配置完成了。

同步模式
上面总结了同步的原理、同步的配置流程和同步的实际效果,下面针对主从复制的同步模式进行深一步的探索。为什么会有不同的同步模式呢?这肯定是因为某种模式存在缺陷,默认的同步模式使用的是异步同步模式,在下面的示例中,我们就不在演示了,直接演示半同步模式。

同步模式分类
同步模式主要分为异步同步和半同步模式(还有一种 GTID 模式,就单独做讲解,因为它不是基于这种 binary + Log 的简单形式),两者实现的方式如下图:
在这里插入图片描述
异步同步模式
异步同步模式是 MySQL 默认的同步策略模式。客户端在向服务端发送请求后,master 处理完之后,直接返回客户端结果,接着在将对应的 log 信息发送给 slave 节点。

上面的演示步骤就是属于异步同步模式,因此这里不做再次演示。

半同步模式
半同步模式与异步同步的模式最大的区别在于 master 处理完自身操作,将对应的 binary log 发送给从服务器,从服务器通过 io thread 写入到 relay log 中,然后将结果返回给 master,master 在收到 salve 的响应之后在返回给客户端。
半同步模式也是基于异步复制的基础上进行的,无非是半同步模式需要安装异步插件完成。
半同步模式具体操作流程:
在这里插入图片描述
半同步实现流程

mysql root@127.0.0.1:(none)> select @@have_dynamic_loading
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set
Time: 0.016s
mysql root@127.0.0.1:(none)> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected
Time: 0.015s
mysql root@127.0.0.1:(none)> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set
Time: 0.015s
mysql root@127.0.0.1:(none)> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected
Time: 0.006s
mysql root@127.0.0.1:(none)> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_semi_sync_slave_enabled               | OFF        |
| rpl_semi_sync_slave_trace_level           | 32         |
+-------------------------------------------+------------+
8 rows in set
Time: 0.012s
mysql root@127.0.0.1:(none)> set global rpl_semi_sync_master_enabled=ON;
Query OK, 0 rows affected
Time: 0.004s
mysql root@127.0.0.1:(none)> set global rpl_semi_sync_slave_enabled=ON;
Query OK, 0 rows affected
Time: 0.002s
mysql root@127.0.0.1:(none)> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_semi_sync_slave_enabled               | ON         |
| rpl_semi_sync_slave_trace_level           | 32         |
+-------------------------------------------+------------+
8 rows in set
Time: 0.013s
stop slave io_thread;
start slave io_thread;

在该步骤中,省略了配置主从关系的一步,因为上面在演示主从复制时,已经建立了一个主从复制关系了并且半同步模式也是基于异步同步模式进行的,所以你只需按照上面主从复制操作的流程进行即可。

mysql root@127.0.0.1:(none)> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_status                | ON    |
+--------------------------------------------+-------+
15 rows in set
Time: 0.011s

半同步问题总结

slave 节点响应 master 延迟。
当 master 发送给 slave 节点 binary log 之后,需要等待 slave 的响应。有时可能 slave 节点响应很慢,master 不能一直等待,这样会导致客户端请求超时情况,可以通过下面的参数进行设置。该参数的单位是毫秒,默认是 10 秒,推荐设置大一点。因为超时之后,master 会自动切换为异步复制。

rpl_semi_sync_master_timeout

半同步模式自动转为异步同步模式。
当面 1 中提到了,如果超时之后,半同步模式会自动切换为异步复制模式。因此设置该参数即可。

master 接收 slave 节点数量,响应客户端。
当 master 需要将 binary log 发送给多个 slave 节点时,如果 slave 节点存在多个,master 都要等待 slave 一一响应之后才回复客户端,这也是一个特别耗时的过程,可以通过下面的参数进行设置。该参数的意义就是,只要 master 接收到 n 个 slave 的响应之后,就可以返回给客户端了。默认是 1。

rpl_semi_sync_master_wait_for_slave_count

当半同步模式自动切换为异步之后,如何切换为半同步模式。
这时候需要手动切换模式。就是关闭 io_thread,再开启 io_thread。

start slave io_thread;

半同步一致性

半同步复制模式极大程度上提高了主从复制的一致性。同时在 MySQL5.7+的版本增加了另外一个参数,让复制的一致性更加可靠。这个参数就是rpl_semi_sync_master_wait_point,需要在 master 上执行。

set global rpl_semi_sync_master_wait_point = 'x';

该参数有两个值。一个值是 AFTER_SYNC,一个值是 AFTER_COMMIT。默认是 AFTER_SYNC。

AFTER_SYNC

master 在将事务写入 binary log 之后,然后发送给 slave。同时也会自动提交 master 的事务。等 slave 响应之后,master 接着响应给客户端信息。

AFTER_SYNC

master 在将事务写入 binary log 之后,然后发送给 slave。等待 slave 响应之后,才会提交 master 的事务,接着响应给客户端信息。

两者对比
异步同步模式,是直接返回给客户端在处理 slave 的问题,如果 master 响应给客户端成功信息,在处理 slave 问题时,服务挂掉了,此时就会出现数据不一致。
半同步模式,需要等待 slave 节点做出响应,master 才会响应客户端,如果 salve 响应较慢就会造成客户端等待时间较长。
半同步模式,master 等待 slave 响应之后才会响应给客户端,此方式极大程度的保证了数据的一致性,为主从复制的数据一致性提供了更可靠的保证。也推荐使用该方式进行主从复制操作。
GTID同步
什么是GTID同步
GTID是一种全局事务ID,它是在master上已经提交的事务,slave直接根据该ID进行复制操作。该操作替代了binary log + postion的方式。使得主从复制的配置操作更加简单。
该模式需要MySQL>=5.6版本。

GTID组成部分
GTID = server-id + transaction-id组成。server-id不是MySQL配置文件中id,而是每一个MySQL服务在启动时,都会生成一个全局随机唯一的ID。transaction-id则是事务的ID,创建事务是会自动生成一个ID。

配置流程
master的配置文件增加如下配置。

server_id               = 1
log_bin                 = ON
binlog_format           = ROW
gtid_mode				= ON
enforce_gtid_consistency = ON

slave的配置文件增加如下配置。

server_id               = 2
log_bin                 = mysql-bin
binlog_format           = ROW
gtid_mode				= ON
enforce_gtid_consistency = ON
log_slave_updates		= ON

配置好之后,一定记得重启master和salve服务。重启好之后,登录master,使用show master status;查看一下GTID。会看到如下的信息。

mysql root@127.0.0.1:(none)> show master status;
+-----------+----------+--------------+------------------+------------------------------------------+
| File      | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+-----------+----------+--------------+------------------+------------------------------------------+
| ON.000005 | 729      |              |                  | a9cf78c4-257f-11eb-94e0-0242ac120007:1-2 |
+-----------+----------+--------------+------------------+------------------------------------------+
1 row in set
Time: 0.011s

slave服务建立连接关系。下面的操作都是在slave节点进行。

# 重置所有的复制关系。
mysql root@127.0.0.1:(none)> reset slave all;
Query OK, 0 rows affected
Time: 0.056s


# 查看主从复制状态,发现没有任何信息了,则表示重置成功了。
mysql root@127.0.0.1:(none)> show slave status\G;
0 rows in set
Time: 0.005s


# 设置master信息。
change master to master_host='192.168.0.112',master_port=3304,master_user='slave_user',master_password='123456',master_auto_position=1;
Query OK, 0 rows affected
Time: 0.048s


# 启动复制。
start slave;
mysql root@127.0.0.1:(none)> start slave;
Query OK, 0 rows affected
Time: 0.007s


# 查看复制状态。
mysql root@127.0.0.1:(none)> stop slave io_thread;
***************************[ 1. row ]***************************
Slave_IO_State                | Waiting for master to send event
Master_Host                   | 192.168.0.112
Master_User                   | slave_user
Master_Port                   | 3304
Connect_Retry                 | 60
Master_Log_File               | ON.000005
Read_Master_Log_Pos           | 729
Relay_Log_File                | aa7863c59748-relay-bin.000002
Relay_Log_Pos                 | 928
Relay_Master_Log_File         | ON.000005
Slave_IO_Running              | Yes
Slave_SQL_Running             | Yes
Replicate_Do_DB               |
..........

需要测试结果,可以直接在master插入数据,看slave数据是否已经发生变化。
通过上面的演示,你已经基本掌握了主从复制的原理、配置流程

参考来源:https://cloud.tencent.com/developer/article/1832929

标签:主从复制,同步,slave,semi,sync,master,MySQL,rpl,GTID
来源: https://blog.csdn.net/qq_38925911/article/details/117958414