文章目录

  • 主从复制原理
    • 1.主节点 binary log dump 线程
    • 2.从节点I/O线程
    • 3.从节点SQL线程
    • 主从复制过程
    • 异步模式(mysql async-mode)
    • 半同步模式(mysql semi-sync)
    • 全同步模式
  • 主从复制——异步复制实验
    • 一、实验环境
    • 二、基于日志点的主从复制——异步复制
      • server1(master)主库配置
      • server2(slave)从库配置
      • 测试
    • 三、基于GTID的主从复制——异步复制
      • 基于gtid主从复制简介
      • 基于GTID复制实现的工作原理
      • pos与gtid的区别
      • GTID master节点的配置
      • GTID slave节点的配置
      • 测试
  • 主从复制——半同步复制实验(基于GTID)
    • 半同步定义
    • 基于gtid的半同步的部署
      • master主库的配置(server1)
      • slave从端的配置(server2)
      • 测试
  • 主从复制——全同步复制实验(基于GTID)
    • Mysql的组复制(全同步复制)简介
    • 全同步复制原理
    • 全同步复制优点
    • 单主模式下的Mysql全同步复制的部署
      • 一、实验环境
      • 二、server1(Master)的部署
      • 三、server2、server3(Slave)的部署

主从复制原理

MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL
thread)运行在从节点,如下图所示:

1.主节点 binary log dump 线程

当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。

2.从节点I/O线程

当从节点上执行start slave命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。

3.从节点SQL线程

SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

主从复制过程

  • 对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。

  • 要实施复制,首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。

  • 因为整个复制过程实际上就是Slave 从Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。如下图所示:

复制的基本过程如下:

  • 1.从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
  • 2.主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”;
  • 3.Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在祝节点上实际执行过的操作,并在本数据库中执行。

异步模式(mysql async-mode)

异步模式如下图所示,这种模式下,主节点不会主动push bin log到从节点,这样有可能导致failover的情况下,也许从节点没有即时地将最新的bin log同步到本地。

半同步模式(mysql semi-sync)

这种模式下主节点只需要接收到其中一台从节点的返回信息,就会commit;否则需要等待直到超时时间然后切换成异步模式再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以提高数据安全性,确保了事务提交后,binlog至少传输到了一个从节点上,但不能保证从节点将此事务更新到db中。性能上会有一定的降低,响应时间会变长。如下图所示:


半同步模式不是mysql内置的,从mysql 5.5开始集成,需要master 和slave 安装插件开启半同步模式。

全同步模式

全同步模式是指主节点和从节点全部执行了commit并确认才会向客户端返回成功。

  • 基于日志点的主从复制、基于GTID的主从复制。
    https://www.jianshu.com/p/169315f2124a?utm_source=oschina-app
  • 主从复制的分类:异步复制、半同步复制、全同步复制(组复制)。

主从复制——异步复制实验

一、实验环境

两台rhel7.5的虚拟机,一台作为master,一台作为slave。

主机名(IP) 角色
server1 master
server2 slave

我们这里分别通过传统的基于日志点的主从复制、基于GTID的主从复制分别实现异步复制。

二、基于日志点的主从复制——异步复制

server1(master)主库配置

  • 1.官网下载并解压安装mysql
[root@server1 ~]# ls
mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
[root@server1 ~]# tar xf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
[root@server1 ~]# ls
mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
mysql-community-client-5.7.24-1.el7.x86_64.rpm
mysql-community-common-5.7.24-1.el7.x86_64.rpm
mysql-community-devel-5.7.24-1.el7.x86_64.rpm
mysql-community-embedded-5.7.24-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.24-1.el7.x86_64.rpm
mysql-community-embedded-devel-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm
mysql-community-minimal-debuginfo-5.7.24-1.el7.x86_64.rpm
mysql-community-server-5.7.24-1.el7.x86_64.rpm
mysql-community-server-minimal-5.7.24-1.el7.x86_64.rpm
mysql-community-test-5.7.24-1.el7.x86_64.rpm

我们这里安装mysql只需要一些必要的包即可,即下面这五个:

[root@server1 ~]# yum install -y mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm

因为要实现主从复制,所以server2也需要安装这些包:

[root@server1 ~]# scp mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm  root@172.25.66.2:
  • 2.启动数据库,查看密码,并进行安全初始化。
[root@server1 ~]# systemctl start mysqld
[root@server1 ~]# grep password /var/log/mysqld.log
2019-07-29T02:17:59.567048Z 1 [Note] A temporary password is generated for root@localhost: dkgi%%xeo1=A
[root@server1 ~]# mysql_secure_installation

  • 3.登录查看Mysql密码是否修改成功。
[root@server1 ~]# mysql -uroot -pWsp+123ld
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.24 MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
  • 4.编辑mysql的配置文件(为了实现主从复制)
[root@server1 ~]# vim /etc/my.cnf

文件末尾添加:

保存退出后记得重启服务:systemctl restart mysqld

  • 5.创建一个用户用来复制(Creating a User for Replication)并授权。
mysql> CREATE USER 'repl'@'172.25.66.%' IDENTIFIED BY 'Wsp+123ld';
Query OK, 0 rows affected (0.02 sec)mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.66.%';
Query OK, 0 rows affected (0.01 sec)
  • 6.查看二进制日志是否打开,以及查看主库状态。
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.00 sec)mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      615 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

server2(slave)从库配置

  • 1.安装Mysql
[root@server2 ~]# yum install -y mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm
  • 2.安全初始化
[root@server2 ~]# systemctl start mysqld
[root@server2 ~]# grep pass /var/log/mysqld.log
2019-07-29T02:46:44.242354Z 1 [Note] A temporary password is generated for root@localhost: 2pH,kaH)nI/w
[root@server2 ~]# mysql_secure_installation

这里与MASTER一致。

  • 3.修改配置文件(为了实现主从复制)
[root@server2 ~]# vim /etc/my.cnf
在文件最下写入一行:
server-id=2[root@server2 ~]# systemctl restart mysqld
  • 4.slave节点需要的设置。(设置谁是master节点信息)
mysql> CHANGE MASTER TO MASTER_HOST='172.25.66.1',-> MASTER_USER='repl',-> MASTER_PASSWORD='Wsp+123ld',-> MASTER_LOG_FILE='mysql-bin.000001',-> MASTER_LOG_POS=615;

注意:这里的Master相关信息就是我们刚刚设置主库的相关信息,其中 MASTER_LOG_FILE和MASTER_LOG_POS是我们上面通过show master status;查看到的。

  • 5.开启主从复制的slave并查看从库slave是否设置成功。
mysql> start slave;
Query OK, 0 rows affected (0.02 sec)mysql> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 172.25.66.1              # 查看是否是masterMaster_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 615Relay_Log_File: server2-relay-bin.000002Relay_Log_Pos: 320Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: Yes                 #这里IO线程、SQL线程运行,说明成功Slave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB:

如果这里Slave_IO_Running、Slave_IO_Running不全是Yes,请看这篇博客,有几种排错方法。

测试

  • 1.在主库server1中创建库和表并且插入数据
mysql> create database linux;
Query OK, 1 row affected (0.01 sec)mysql> use linux;
Database changedmysql> create table userlist(-> username varchar(10) not null,-> age int not null);
Query OK, 0 rows affected (0.18 sec)mysql> insert into userlist values('mac',23);
Query OK, 1 row affected (0.02 sec)mysql> select * from userlist;
+----------+-----+
| username | age |
+----------+-----+
| mac      |  23 |
+----------+-----+
1 row in set (0.00 sec)
  • 2.在从库server2登录查看数据是否同步
mysql> select * from linux.userlist;
+----------+-----+
| username | age |
+----------+-----+
| mac      |  23 |
+----------+-----+
1 row in set (0.00 sec)

至此,我们就用传统的主从复制方法——基于日志点的主从复制实现了异步复制。

三、基于GTID的主从复制——异步复制

基于gtid主从复制简介

mysql数据库从5.6.5开始新增一种基于gtid的复制方式。gtid(global transaction id)是对于一个已提交事务的编号。gtid实际上是由uuid+tid组成的,其中uuid是mysql实例的一个标识,tid则代表了该实例上交的事务数量,并且随着事务的提交单调递增
主从复制默认是通过pos(position)复制,就是说在日志文档里,将用户进行的每一项操作都进行编号(pos),每一个事件都有一个起始编号,一个终止编号,在配置主从复制节点时,要求其从master的pos开始同步数据库里面的数据,这也称作传统复制技术。
gtid就是类似pos的作用,不过它是整个mysql复制架构全局通用的,即在整个mysql冗余架构中,它们的日志文件里面事件的gtid的数值是一致的。
gtid是一个对于已提交的事物的编号,并且是一个全局唯一的编号
通过gtid保证每个主库上提交的事务在集群中有一个唯一的id。这种方式强化了主备的一致性,故障恢复及其容错能力。

  • @ 在传统的复制里面,当发生故障,需要主从切换,需要找到binlog和pos点,然后将主节点指向新的主节点,相对来说比较麻烦,也容易出错。在MySQL 5.6里面,不用再找binlog和pos点,我们只需要知道主节点的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步。

  • @ 多线程复制(基于库),在MySQL 5.6以前的版本,slave的复制是单线程的。一个事件一个事件的读取应用。而master是并发写入的,所以延时是避免不了的。唯一有效的方法是把多个库放在多台slave,这样又有点浪费服务器。在MySQL 5.6里面,我们可以把多个表放在多个库,这样就可以使用多线程复制。

基于GTID复制实现的工作原理

  • 主节点更新数据时,会在事务前产生GTID,一起记录到binlog日志中。
  • 从节点的I/O线程将变更的bin log,写入到本地的relay log中。
  • SQL线程从relay log中获取GTID,然后对比本地binlog是否有记录(所以MySQL从节点必须要开启binary log)。
  • 如果有记录,说明该GTID的事务已经执行,从节点会忽略。
  • 如果没有记录,从节点就会从relay log中执行该GTID的事务,并记录到bin log。
  • 在解析过程中会判断是否有主键,如果没有就用二级索引,如果有就用全部扫描。

pos与gtid的区别

俩者都是日志文件里的一个标志,如果将整个mysql集群看作一个整体,pos就是局部的,gtid就是全局的

GTID master节点的配置

  • 1.配置文件添加如下内容:
gtid_mode=ON
enforce-gtid-consistency=true

  • 2.重启服务,并查看master的uuid
[root@server1 ~]# systemctl restart mysqld
[root@server1 ~]# cat /var/lib/mysql/auto.cnf
[auto]
server-uuid=15d708f6-b1a7-11e9-9c82-525400d85f32

GTID slave节点的配置

  • 1.配置文件添加如下内容,并重启服务
gtid_mode=ON
enforce-gtid-consistency=true

systemctl restart mysqld
  • 2.先停掉slave,添加新的master模式,然后再次开启slave
mysql> stop slave;
Query OK, 0 rows affected (0.03 sec)mysql> CHANGE MASTER TO-> MASTER_HOST = '172.25.66.1',-> MASTER_USER = 'repl',->  MASTER_PASSWORD = 'Wsp+123ld',-> MASTER_AUTO_POSITION = 1;mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
  • 3.查看slave状态,注意uuid是否与master一致。
mysql> show slave status\G;
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 172.25.66.1Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000002Read_Master_Log_Pos: 154Relay_Log_File: server2-relay-bin.000002Relay_Log_Pos: 367Relay_Master_Log_File: mysql-bin.000002Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 154Relay_Log_Space: 576Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_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: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 15d708f6-b1a7-11e9-9c82-525400d85f32          # uuid与master一致Master_Info_File: /var/lib/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 1Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version:
1 row in set (0.00 sec)

测试

  • 1.在主库中插入数据
mysql> insert into linux.userlist values('hah',12);
Query OK, 1 row affected (0.03 sec)
  • 2.在从库中查看
mysql> select * from linux.userlist;
+----------+-----+
| username | age |
+----------+-----+
| mac      |  23 |
| hah      |  12 |
+----------+-----+
2 rows in set (0.00 sec)

主从复制——半同步复制实验(基于GTID)

我们这里实现Mysql的基于GTID的半同步复制实验。

半同步定义

MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果挂掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。则半同步复制就解决数据丢失的问题。半同步最少有一个slave复制完成master的所有数据后才会进行下一步事务操作。

基于gtid的半同步的部署

master主库的配置(server1)

  • 1.安装半同步的master服务插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)
  • 2.开启半同步复制,并查看半同步插件是否活跃
mysql> SET GLOBAL rpl_semi_sync_master_enabled = ON;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS->        FROM INFORMATION_SCHEMA.PLUGINS->        WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.00 sec)
  • 3.查看半同步复制相关环境变量设置,半同步复制的master的状态:
mysql> show variables like '%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 |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

这里可以看到,master的半同步已经开启,半同步的超时时间:10000ms(10s),我们在实际生产环境中为了保证数据完整性,用半同步的话,一般需要设置为无穷大;超时过后,默认变为异步复制。

mysql> show status like '%semi%';
+--------------------------------------------+-------+
| 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     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

可以看到| Rpl_semi_sync_master_status | ON |,说明已经开启成功。

slave从端的配置(server2)

  • 1.安装半同步slave的插件,并开启半同步复制
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)
  • 2.因为我们刚刚做了gtid的异步复制,所以要先关闭io线程然后再打开,如果没有进行重启io线程操作,则默认还是异步复制。
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.02 sec)mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

测试

  • 1.slave从端关掉io线程
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)
  • 2.在主端插入数据,会等待10s中,当发现slave挂掉后,10s后会自动切换为默认的异步复制,再次插入数据,速度会变快,因为此时是异步复制,不用等待同步。
mysql> insert into linux.userlist values('nv',13);
Query OK, 1 row affected (10.03 sec)mysql> insert into linux.userlist values('waaaa',43);
Query OK, 1 row affected (0.02 sec)
  • 3.在主端查看半同步复制的情况
mysql> show status like '%semi%';
+--------------------------------------------+-------+
| 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                 | 2     |
| 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     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

可以看到,其中| Rpl_semi_sync_master_no_tx | 2 |表示有两次没有半同步成功。
此时我们在从端查询不到新插入的数据。

mysql> select * from linux.userlist;
+----------+-----+
| username | age |
+----------+-----+
| mac      |  23 |
| hah      |  12 |
+----------+-----+
2 rows in set (0.00 sec)
  • 4.在从端的数据是没有同步过来的,当再次打开io线程,数据同步过来但是这是因为主从异步复制所同步的数据。
mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)mysql> select * from linux.userlist;
+----------+-----+
| username | age |
+----------+-----+
| mac      |  23 |
| hah      |  12 |
| nv       |  13 |
| waaaa    |  43 |
+----------+-----+
4 rows in set (0.00 sec)

主从复制——全同步复制实验(基于GTID)

Mysql的组复制(全同步复制)简介

组复制分单主模式和多主模式,mysql 的复制技术仅解决了数据同步的问题。但是如果 master 宕机,意味着数据库管理员需要介入,应用系统可能需要修改数据库连接地址或者重启才能实现。

组复制在数据库层面上做到了,只要集群中大多数主机可用,则服务可用。

  • 单主模型:从复制组众多个MYSQL节点中自动选举一个master节点,只有master节点可以写,其它节点自动设置为只读。当master节点故障时,会自动选举一个新的master节点,选举成功后,它将设置为可写,其它的slave将指向这个新的master。

  • 多主模型:复制组中的任何一个节点都可以写,因此没有master和slave的概念,只要突然故障的节点的数量不太多这个多主模就能继续使用。

全同步复制原理

组复制由多个mysql服务器组成,并且组中的每一个mysql服务成员可以独立的执行事务。但是所有的读写事务只有在冲突检测成功后才会提交,只读事务不需要冲突检测,可以立即提交
对于任何读写事务,提交操作并不是由始发服务单向决定的,而是由组来决定是否提交。

在始发mysql服务上,当事务准备好要提交时,该主机会广播写入值即已改变的行和对应的写入集及已更新的行的唯一标识符。然后会为该事务建立一个全局的顺序。最终,所有的server成员以相同的顺序接收同一组事务。所有的server成员以相同的顺序应用相同的更改,以保证组内一致。

全同步复制优点

  1. 组复制中即使一些server发生故障,系统仍然可用,只是在性能和伸缩性上有所降低,但是仍然可用。
  2. server故障是孤立的。它们由组成员服务来监控,组成员服务依赖于分布式的故障检测系统,其能够在任何server自愿或者由于意外停止而离开组时发出信号。

单主模式下的Mysql全同步复制的部署

一、实验环境

这里需要增加一台slave节点。

主机名(IP) 服务
server1(172.25.66.1) master
server2(172.25.66.2) slave
server3(172.25.66.3) slave

二、server1(Master)的部署

  • 1.由于在此实验之前做了mysql的其它相关应用,所以首先需要进行对数据库重新清理,以下2、3步为清理过程

  • 2.查看server1上的uuid后面组复制时的配置文件需要用到
    注意:这里需要的uuid和后面组中所有节点的uuid不能相同。

[root@server1 ~]# cat /var/lib/mysql/auto.cnf
[auto]
server-uuid=15d708f6-b1a7-11e9-9c82-525400d85f32
  • 3.数据库的文件删除恢复到初始状态,注意要先关闭数据库然后再删文件,才会生效
[root@server1 ~]# cd /var/lib/mysql
[root@server1 mysql]# systemctl stop mysqld.service
[root@server1 mysql]# ls
auto.cnf         client-key.pem  ib_logfile1       mysql-bin.000002    public_key.pem
ca-key.pem       ib_buffer_pool  linux             mysql-bin.index     server-cert.pem
ca.pem           ibdata1         mysql             performance_schema  server-key.pem
client-cert.pem  ib_logfile0     mysql-bin.000001  private_key.pem     sys
[root@server1 mysql]# rm -fr *
[root@server1 mysql]# ls
  • 4.编辑配置文件添加组复制相关配置
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROWtransaction_write_set_extraction=XXHASH64  ##指定server必须为每个事务收集写集合,并使用哈希算法将其编码为散列
loose-group_replication_group_name="15d708f6-b1a7-11e9-9c82-525400d85f32"       ##对创建的组命名,为我们之前的master的uuid
loose-group_replication_start_on_boot=off       ##不自动启动组复制
loose-group_replication_local_address= "172.25.66.1:33061"      ##本地的端口33061实现成员连接
loose-group_replication_group_seeds= "172.25.66.1:33061,172.25.66.2:33061,172.25.66.3:33061"
loose-group_replication_bootstrap_group=off      ##是否自动引导组
loose-group_replication_ip_whitelist="127.0.0.1,172.25.66.0/24"
loose-group_replication_enforce_update_everywhere_checks=ON     ##打开检查及其更新
loose-group_replication_single_primary_mode=OFF     #设置组自动选择一个server来处理读写工作
  • 5.开启数据库,查看密码并且登录,可以在登录后使用命令对其初始化及修改密码
[root@server1 mysql]# systemctl restart mysqld
[root@server1 mysql]# grep password /var/log/mysqld.log mysql> alter user root@localhost identified by 'Wsp+123ld';
Query OK, 0 rows affected (0.03 sec)
  • 6.开启组复制
mysql> SET SQL_LOG_BIN=0; ##首先在进行用户建立之前关闭二进制日志,建立好之后再打开
mysql> CREATE USER 'repl'@'%' identified by 'Wsp+123ld'; ##创建复制用户
mysql> select user from mysql.user;      # 查看用户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';      #授予用户权限
mysql> FLUSH PRIVILEGES; ##刷新数据
mysql> SET SQL_LOG_BIN=1;    ##开启日志
mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='Wsp+123ld' FOR CHANNEL 'group_replication_recovery';    ##设置如果要改变master时需要通过该通道group_replication_recovery给其master的用户名和密码mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';    ##安装组复制插件
mysql> SET GLOBAL group_replication_bootstrap_group=ON;   ##只在master上进行的操作,即自动引导组,当打开组复制之后将其再关闭
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
mysql> SHOW PLUGINS;      ##查看组复制插件,是否成功
  • 7.组复制添加完成后查看状态为online则组复制添加成功。
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | ba729a62-b1c5-11e9-8cbe-525400d85f32 | server1     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)
  • 8.创建库添加表,插入数据方便后续的测试
mysql> create database test;
Query OK, 1 row affected (0.01 sec)mysql> use test;
Database changedmysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0.14 sec)mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.04 sec)mysql> SELECT * FROM t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

三、server2、server3(Slave)的部署

  • 1.如果和server1做了相应的mysql的应用,则需要删除数据,重新开启数据库进行初始化
[root@server2 ~]# cd /var/lib/mysql
[root@server2 mysql]# ls
auto.cnf         ib_logfile0  mysql.sock.lock           server2-relay-bin.index
ca-key.pem       ib_logfile1  performance_schema        server-cert.pem
ca.pem           ibtmp1       private_key.pem           server-key.pem
client-cert.pem  linux        public_key.pem            sys
client-key.pem   master.info  relay-log.info
ib_buffer_pool   mysql        server2-relay-bin.000004
ibdata1          mysql.sock   server2-relay-bin.000005
[root@server2 mysql]# systemctl stop mysqld.service
[root@server2 mysql]# rm -fr *
[root@server2 mysql]# systemctl restart mysqld.service
[root@server2 mysql]# grep pass /var/log/mysqld.log mysql> alter user root@localhost identified by 'Wsp+123ld';
  • 2.编辑配置文件添加组复制
    注意:修改server-id和localhost本地ip地址。
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROWtransaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="15d708f6-b1a7-11e9-9c82-525400d85f32"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.66.2:33061"
loose-group_replication_group_seeds= "172.25.66.1:33061,172.25.66.2:33061,172.25.66.3:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist="127.0.0.1,172.25.66.0/24"
loose-group_replication_enforce_update_everywhere_checks=ON
loose-group_replication_single_primary_mode=OFF

保存退出后,重启服务systemctl restart mysqld

  • 3.启动组复制
mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'Wsp+123ld';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='Wsp+123ld'   FOR CHANNEL 'group_replication_recovery';
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> SET GLOBAL group_replication_allow_local_disjoint_gtids_join=on;
mysql> START GROUP_REPLICATION;
mysql> SHOW PLUGINS;

查看组成员及其状态:

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | ba729a62-b1c5-11e9-8cbe-525400d85f32 | server1     |        3306 | ONLINE       |
| group_replication_applier | cc8f4072-b1c8-11e9-a152-5254000c57b5 | server2     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+

如果出现问题,例如MEMBER_STATE 显示RECOVERING,从以下几点排错:
a.检测所有的MEMBER_ID 是否和master配置文件中loose-group_replication_group_name不同,才能进行。
b.检查解析文件/etc/hosts是否配置了和主机名一致的解析。
c.主从库的初始数据可能不一致导致。

这里可以参考博客:

  • 4.查看数据是否同步
mysql> select * from test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)
  • 5.同样的,在server3上查看组成员及其状态,以及数据是否同步。
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 881fedba-b1ce-11e9-b205-525400aaba12 | server3     |        3306 | ONLINE       |
| group_replication_applier | ba729a62-b1c5-11e9-8cbe-525400d85f32 | server1     |        3306 | ONLINE       |
| group_replication_applier | cc8f4072-b1c8-11e9-a152-5254000c57b5 | server2     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+mysql> select * from test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

至此,就完成了组复制(全同步复制)的实验。

企业级运维——Mysql主从复制(异步、半同步、全同步)相关推荐

  1. mysql 同步复制 半同步复制_一文看懂MySQL的异步复制、全同步复制与半同步复制...

    今天主要聊一下MySQL的异步复制.全同步复制与半同步复制,目前我们生产库实际上用的就是异步复制了,后面再转成半同步复制. 一.MYSQL复制架构衍生史 在2000年,MySQL 3.23.15版本引 ...

  2. Splunk企业级运维智能大数据分析平台新手入门视频课程上线

    Splunk企业级运维智能&大数据分析平台新手入门视频课程上线 http://edu.51cto.com/course/course_id-6696.html 2016年8月2日到5日,移动端 ...

  3. Linux7企业级运维高端培训视频教程

    国内首部Linux7企业级运维高端培训课程(Linux7系统.服务加固安全.虚拟化和云计算) 课程讲师:博学金牌讲师 课程分类:套餐系列 适合人群:中级 课时数量:220课时 更新程度:80% 用到技 ...

  4. MySQL主从复制异步原理以及搭建

    MySQL主从复制的原理: 1.首先,MySQL主库在事务提交时会把数据变更作为时间events记录在二进制日志文件binlog中:MySQL主库上的sync_binlog参数控制Binlog日志以什 ...

  5. 重磅!由Linux面试出发,看清华大佬教你如何企业级运维实战

    其实当时没有想到去面试,只是在智联上更新了一下简历,就陆陆续续接到很多公司的邮件和电话,闲话少说,下面就分享给大家面试Linux的经历: 首先,公司HR会把公司的介绍及岗位要求发到你邮箱(或者QQ.微 ...

  6. 10·24【运维工程师也过节】【运维MySQL大礼包】

    重点是结束语,都是前辈们总结的[运维]精华. 目录 MySQL运维环境 mysql5.7安装(centos7) mysql5.7修改密码策略 mysql初始化 mysqldump常用参数(数据备份) ...

  7. 对话 CTO | 服务万亿旅游市场,去哪儿网企业级运维的精益实践

    专栏介绍 「对话 CTO」是极客公园的一档最新专栏,以技术人的视角聊聊研发管理者的发展和成长. 本专栏由企业级研发管理工具ONES的创始人&CEO王颖奇作为特邀访谈者.王颖奇曾参与金山软件 W ...

  8. 企业级运维监控系统体系化建设指南

    监控系统的本质是通过发现故障.解决故障.预防故障来为了保障业务的稳定.而要想在企业内实现监控系统的体系化建设落地,需要从以下三个方面着手建设,分别是监控技术体系.监控指标体系.监控管理体系. 01. ...

  9. 运维mysql数据库面试题_运维面试题之数据库

    mysql篇: mysql主从复制原理? mysql的复制是基于3个线程 1.master上的binlog dump线程负责把binlog 事件传到slave 2.slave上面的IO线程负责接收bi ...

最新文章

  1. Cocos生命周期回调
  2. antd checkbox 默认选中_antd 开发的一些坑(一)
  3. mount查看linux分区大小,Linux磁盘管理----分区格式化挂载fdisk、mkfs、mount
  4. python中常见的运行时错误_17个常见Python运行时错误
  5. java 中 的 字节流!
  6. 新闻系统查询思路和步骤
  7. when busy dialog closed iDuration renderFioriFlower jQuery Animation closeL
  8. python虚拟环境另类的搭建
  9. github快速通道
  10. SimpleAjax 开发包 v3.1 (简单的Ajax)
  11. 批处理框架 Spring Batch,数据迁移量过大如何保证内存?
  12. 学点PYTHON基础的东东--数据结构,算法,设计模式---访问者模式
  13. 【Python 代码】类似SADPTool工具,搜索海康设备
  14. 面试软件测试总结(常见的面试问题)
  15. 51单片机--蜂鸣器
  16. 泡泡网 前有古人后有来者! 胶水处理器回顾
  17. Hadoop Namenode元数据文件 Fsimage、editlog、seen_txid说明
  18. java ppt转图片 解决图片不清晰问题
  19. python案例——体脂率项目
  20. 响应式网页上banner使用,unslider

热门文章

  1. 解决win10下PPT打不开,显示内容有问题,提示修复但修复不成功
  2. 互联网创业必备工具盘点
  3. win10删除*某些设置由你的组织来管理
  4. ADB命令使用大全及使用原理
  5. 整流十五—网侧低频电流谐波抑制方法及其稳定性分析
  6. Python数据特征分析1-分布分析(极差,频率直方图等)
  7. 问卷星不能复制粘贴?不存在的!
  8. 小程序客服消息推送公众号文章 引导关注公众号的操作方法
  9. LuatOS | 全新在线模拟器,随时随地发挥创意
  10. win server 2008 r2 iis+php 500错误内部服务器错误。