MySQL 8 主从配置

主从复制的工作流程:主库将用户所有的写操作(增删改,查除外)记录到 binlog 日志当中并且生成一个 log dump 线程,从库生成 I/OSQL 线程,从库的 I/O 线程向主库的 log dump 线程以 I/O 流的形式发送请求,主库的 log dump 线程收到从库 I/O 线程的请求后将 binlog 日志发送给从库,从库I/O线程收到binlog日志后将其写道relay log(中继日志)文件中再由从库的SQL线程将 relay log 文件中的日志解析成 sql 脚本,最后执行生成的 sql 脚本文件,来实现主从的操作一致,达到最终数据一致的目的。

https://img-blog.csdnimg.cn/20210511225354503.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2gxMjI4MzIyMDg4,size_16,color_FFFFFF,t_70

1.配置说明

准备两台安装了 mysql 的主机,要求存储数据完全一样

名称IP
node01(主人 master)192.168.100.112
node02(从属 slave)192.168.100.240

2.修改数据库 uuid

由于 node02 是从虚拟机克隆而来,需要更改 uuid ,否则配置过程中会报错

# cd到mysql下的data目录,修改slave主机mysql的uuid
vi auto.cnf

3.配置步骤

同时在node01node02两台机器上创建同步测试库sync,创建一张测试空表seller

create database sync;
use sync;

-- 销售表(seller)
create table seller(
	id int UNSIGNED not null auto_increment COMMENT 'ID',
	saleNo char(3) not null COMMENT '编号',
	saleName varchar(20) not null COMMENT '姓名',
	sex char(1) DEFAULT'男' COMMENT '性别', 
	birthday date COMMENT '出生年月',
	hireDate date COMMENT '雇员日期',
	address varchar(50) COMMENT '地址',
	telephone varchar(20) COMMENT '电话',
	PRIMARY KEY (id),
	UNIQUE ux_saleNo(saleNo),
	INDEX ix_saleName(saleName)
)ENGINE=INNODB DEFAULT charset=utf8mb4;

node01 主库配置

修改my.cnf文件

vi /etc/my.cnf
# 添加或修改以下内容
# 数据库id
server-id = 1

# 待同步的数据库日志
binlog-do-db = sync

# 设置无需同步的数据库日志
binlog-ignore-db = mysql

创建专门用于主从复制用户账号。因此使用root账户登录mysql,并执行一些指令:

# 登录msyql
mysql -u root -p

#创建sync_user用户用于数据同步,注意这里的ip是从库服务器的ip!
CREATE USER 'sync_user'@'192.168.100.240' IDENTIFIED WITH mysql_native_password BY '123456';

# 给主从复制账号授权
grant replication slave on *.* to 'sync_user'@'192.168.100.240';

重启主库的mysql

service mysql restart

再次登录mysql,使用如下指令查看`master的状态:

show master status;

结果类似如下:我们需要关注FilePosition的信息,后面要用到。

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |      157 | sync         | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

node02 从库配置

修改my.cnf文件

vi /etc/my.cnf
# 添加或修改以下内容

# 数据库id必须与主库不同!!!
server-id=2

# 待同步的数据库
replicate-do-db=sync

# 设置无需同步的数据库
replicate-ignore-db=mysql,information_schema,performance_schema

然后我们重启从库的mysql

service mysql restart

最后实现主从同步,在从库具体配置如下:

# 先登录mysql,然后执行后续代码
mysql -u root -p

# 关闭从库
stop slave;

# 设置同步,注意这里是主库ip,日志名称和位置是我们之前上图中看到的名称和位置
change master to master_host='192.168.100.112',master_user='sync_user',master_password='123456',master_log_file='mysql-bin.000006',master_log_pos=157;

# 开启从库
start slave; 

# 检查服务器状态
show slave status \G;

检测服务器状态正常情况下如下:

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.100.112
                  Master_User: sync_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 157
               Relay_Log_File: node01-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Master_Log_File: mysql-bin.000006
             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: 157
              Relay_Log_Space: 537
              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: 730adb84-f2da-11ec-8abe-000c290b9bf5
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica 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: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace:

Slave_IO_Running: Yes,

Slave_SQL_Running: Yes

Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates

三个项目正常说明配置成功

4.测试同步是否成功

node01sync库中的测试表插入以下数据,检验node02是否将数据同步同步过去

INSERT seller(id,saleNo,saleName,sex,birthday,hireDate,address,telephone)
VALUE(1,'s01','王强','男','1975-12-08','2002-05-01','蓝色港湾42-12','0519-85150900'),
(2,'S02','付芳芳','女','1982-02-19','2008-08-14','燕阳花园53-4','0519-85150919'),
(3,'S03','李芳','女','1983-08-30','2008-04-01','富都小区252-16','0519-85150903'),
(4,'SO4','胡宝林','男','1991-09-19','2014-05-13','燕兴小区79-42','0519-85150903'),
(5,'S05','吴韵','男','1979-07-02','2008-11-15','富琛花园3-2','0519-85150904'),
(6,'S06','陆海成','男','1990-03-17','2014-04-17','都市雅居15-10','0519-85150905'),
(7,'S07','刘洋','男','1987-12-06','2012-10-23','顺园八村59-6','0519-85150906'),
(8,'S08','吴永佳','男','1985-07-10','2012-10-23','顺园三村21-12','0519-85150907');

5.异步复制的问题

以上介绍的主从复制是 mysql 的默认复制方式:异步复制

在复制过程当中,主库不会去验证 bin-log 有没有成功复制到从库。如果主库提交一个事务并写入 bin-log 中后,由于网络原因,从库没有接收到对应的 bin-log 那从库就不会得到这个事务,也就造成了主从数据的不一致。

6.半同步复制搭建

在半同步模式中一个事务的执行流程如下:

https://img-blog.csdnimg.cn/63f494e6385e4c87ae78398389086c38.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Jyc5rGB5Z2k5Lid,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

1)主库收到客户端提交的事务。
2)主库执行事务。
3)将数据库事件写入到主库的 bin-log 日志中。
4)当从库来请求 bin-log 日志时,将其发送给从库。
5)从库的 I/O 线程获取到的 bin-log 日志写入到 relay-log 中。
6)当 relay-log 写入完成后,从库向主库发送一个写入成功的通知。
7)主库收到从库发来的成功通知后将事务的结果返回给客户端。
8)从库的SQL线程对写入成功的 relay-log 进行重放,将数据保存到数据库中。

同步体现在主库返回事务结果给客户端时,须收到从库发送的 relay-log 写入成功的通知才能返回,否则会一直等待从库发来通知,直到等待时间到了(rpl_semi_sync_master_timeout 参数设置的值)。

异步体现在主库只要收到从库发来的成功通知即可返回结果给客户端,不需要考虑从库的 relay-log 是否重放成功。

假如主库在执行第 1、2、3 步的任意一步步骤时主库宕机,事务都不会成功,自然从库也不会收到主库发送的 bin-log,所以主从的数据还是保持一致。

假如执行第 4 步时,主库宕机事务也不会提交成功,如果由于网络原因导致从库未接收到主库的 bin-log 日志,则主库会等待从库一段时间(等待从库写入 relay-log 成功的通知 ACK),然后将主从复制的模式切换到异步模式,再返回成功给客户端。

假如执行第 5 步时,主库宕机由于此时主库还在等待从库,则主库事务自然执行失败。如果从库宕机则主库会等待从库,若一段时间后未收到 ACK,则将主从复制的模式切换到异步模式,再返回成功给客户端。

安装插件

方法一:修改配置文件

主库设置

# 主库进入sql页面
install plugin rpl_semi_sync_master soname 'semisync_master.so';

# vi /etc/my.cnf添加以下参数,开启主库半同步复制
rpl_semi_sync_master_enabled=1

# 重启mysql服务
service mysql restart

从库设置

# 从库sql页面输入
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

# 开启半同步复制
rpl_semi_sync_slave_enabled=1
SET GLOBAL rpl_semi_sync_slave_enabled = on;

# 重启mysql服务
service mysql restart
方法二:mysql 用户界面调整参数

主库

# 主库进入sql页面
install plugin rpl_semi_sync_master soname 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = on;

从库

# 从库sql页面输入
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = on;

# 从节点重启IO线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

验证半同步复制

主从库分别输入show status like "%rpl_semi%";

#主库显示如下
mysql> show status like "%rpl_semi%";
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| 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)


# 从库显示如下
mysql> show status like "%rpl_semi%";
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

Rpl_semi_sync_master_clients为1

Rpl_semi_sync_master_status为ON

Rpl_semi_sync_slave_status为ON

即主从半同步复制正常启动;

常用配置

主库使用 show variables like '%Rpl%'; 查看半同步参数信息

mysql> show variables like '%Rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_read_size                             | 8192       |
| 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_stop_replica_timeout                  | 31536000   |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
9 rows in set (0.01 sec)

1)rpl_semi_sync_master_enabled=ON 表示主库开启半同步复制。默认为 OFF ,即关闭半同步复制。

2)rpl_semi_sync_master_timeout=10000 单位为毫秒,默认为 10 秒。用于配置主库等待从库写入 relay-log 日志成功的 ACK 通知的时间。若超过该时间主库将主从模式切换为异步模式,并返回事务提交成功给客户端。

3)rpl_semi_sync_master_wait_for_slave_count=1 表示主库收到 1 个从库发来的 ACK 就返回事务提交成功。默认为 1 。这个参数一般与 rpl_semi_sync_master_wait_no_slave 参数配合使用,默认为 ON。

  • rpl_semi_sync_master_wait_no_slave为OFF时,只要master发现Rpl_semi_sync_master_clients小于rpl_semi_sync_master_wait_for_slave_countmaster提交事务后所需的应答数量),则master立即转为异步模式。
  • rpl_semi_sync_master_wait_no_slave为ON时,空闲时间(无事务提交)里,即使master发现 Rpl_semi_sync_master_clients 小于rpl_semi_sync_master_wait_for_slave_count也不会做任何调整。只要保证在事务超时之前,master 收到大于等于rpl_semi_sync_master_wait_for_slave_count 值的ACK应答数量,master就一直保持在半同步模式;如果在事务提交阶段(master等待ACK)超时,master才会转为异步模式。

无论 rpl_semi_sync_master_wait_no_slave 为 ON 还是 OFF ,当 slave 上线到 rpl_semi_sync_master_wait_for_slave_count 值时, master 都会自动由异步模式转为半同步模式。

4)rpl_semi_sync_master_wait_point=AFTER_SYNC ,用于配置主库在哪个点(什么时机)等待接收从库的 ACK 通知。默认为 AFTER_SYNC

  • AFTER_SYNC 表示主库在 bin-logflush 之后,在存储引擎 commit 前进入等待,这可以保证数据在被复制到从库前不被其他会话(客户端)可见。
    • 假如现在主库有 A、B 两个会话(客户端)连接着,A 修改了一些数据,那么在主库收到从库的 ACK 前,这些数据还没有 commit 到主库的存储引擎中,所以 B 会话还看不到更改后的数据。
  • AFTER_COMMIT 表示主库 bin-logflush 之后并在存储引擎 commit 之后进入等待,尽管发起 commit 的会话还未收到 commit 成功的结果,其他的会话已经可以看到 commit 后的数据了。

参考文档

[1] MySQL8主从复制(一主一从)配置搭建详解 _ 潘子夜个人博客 (panziye.com)

[2] (34条消息) mysql8 进阶(三) 主从复制之半同步复制_蜜汁坤丝的博客-CSDN博客_mysql主从复制半同步

[3] rpl_semi_sync_master_wait_no_slave 参数研究实验 - 孔个个 - 博客园 (cnblogs.com)

[4] MySQL主从复制之半同步(semi-sync replication) (baidu.com)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值