Mysql集成技术

发布于:2025-08-03 ⋅ 阅读:(16) ⋅ 点赞:(0)

目录

mysql的编译安装与部署

1.编译安装mysql

2.部署mysql

mysql主从复制

什么是mysql主从复制?

1.配置master

2.配置slave

3.存在数据时添加slave2

4.GTID模式

什么是GTID模式?

配置GTID

5.延迟复制

6.慢查询日志

核心作用

开启慢查询日志功能

7.并行复制

什么是并行复制?

配置并行复制

半同步模式

1.主从复制原理

2.原理架构缺陷

3.半同步模式原理

4.启动半同步模式


mysql的编译安装与部署

1.编译安装mysql

1.安装mtsql的依赖包跟依赖软件

#安装mysqld8的依赖软件
[root@mysql ~]# yum install  git bison openssl-devel ncurses-devel -y

#安装cmake3,编译时检测需要使用
[root@mysql mnt]# tar zxf cmake3.tar.gz
[root@mysql mnt]# cd make3/
[root@mysql make3]# yum install *.rpm -y
[root@mysql make3]# cmake3 -version
cmake3 version 3.14.7


#安装gcc-11,mysql源码使用了C/C++特性,安装gcc-11确保能正常编译
[root@mysql mnt]# unzip gcc-11.zip 
[root@mysql mnt]# cd gcc-11/
[root@mysql gcc-11]# yum install *.rpm -y
[root@mysql gcc-11]# source /opt/rh/devtoolset-11/enable
[root@mysql gcc-11]# gcc -v
gcc version 11.2.1 20220127 (Red Hat 11.2.1-9) (GCC)

2.源码编译安装mysql

#下载并解压源码包
[root@mysql mnt]# tar zxf mysql-boost-8.3.0.tar.gz
[root@mysql mnt]# cd mysql-8.3.0/
#创建编译目录,防止编译时与源码包混乱
[root@mysql mysql-8.3.0]# mkdir bulit					
[root@mysql mysql-8.3.0]# cd bulit
[root@mysql bulit]# cmake3 .. \				   #使用cmake3进行编译检测
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \					 #指定安装路径
-DMYSQL_DATADIR=/data/mysql \ 								 #指定数据目录
-DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock \ 					 #指定套接字文件
-DWITH_INNOBASE_STORAGE_ENGINE=1 \ 							 #指定启用INNODB存储引擎,默认用myisam
-DWITH_EXTRA_CHARSETS=all \                                  #扩展字符集
-DDEFAULT_CHARSET=utf8mb4 \                                  #指定默认字符集
-DDEFAULT_COLLATION=utf8mb4_unicode_ci \                     #指定默认校验字符集
-DWITH_SSL=system \                                          #指定MySQL 使用系统已安装的SSL库
-DWITH_BOOST=bundled \                                       #指定使用 MySQL 源码包中内置的Boost库
-DWITH_DEBUG=OFF

[root@mysqlb built]# cmake3 .. -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_EXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci -DWITH_SSL=system -DWITH_BOOST=bundled -DWITH_DEBUG=OFF

[root@mysql bulit]# make -j4				#-j4表示使用4个核心来跑编译,一个核心要使用2G运行内存
[root@mysql bulit]# make install			#安装

2.部署mysql

#创建运行mysql的用户
[root@mysqla ~]# useradd -s /sbin/nologin -M mysql

#创建存储mysql数据的目录
[root@mysqla ~]# mkdir /data/mysql -p
[root@mysqla ~]# chown mysql:mysql /data/mysql/

#添加mysql二进制启动文件到环境变量
[root@mysqla ~]# vim ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
[root@mysqla ~]# source ~/.bash_profile

#生成配置文件
[root@mysqla ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql				#指定数据目录
socket=/data/mysql/mysql.sock	#指定套接
default_authentication_plugin=mysql_native_password		#指定数据库默认使用的认证插件,传统兼容


#设置mysql启动服务
[root@mysqla ~]# cd /usr/local/mysql/support-files/
[root@mysqla support-files]# cp -p mysql.server /etc/init.d/mysqld
#开启mysql开机自启
[root@mysqla ~]# chkconfig mysqld on

#初始化mysqld
[root@mysqla ~]# mysqld --initialize --user=mysql
[root@mysqla ~]# /etc/init.d/mysqld start

#数据库安全初始化
[root@node10 ~]# mysql_secure_installation

#登录mysql
[root@mysqla mysql]# mysql -uroot -pyyy
mysql> SELECT @@SERVER_ID;
+-------------+
| @@SERVER_ID |
+-------------+
|          10 |
+-------------+
1 row in set (0.01 sec)

mysql主从复制

什么是mysql主从复制?

MySQL 主从复制是一种将一个 MySQL 数据库(主库,Master)的数据复制到一个或多个 MySQL 数据库(从库,Slave)的技术,常用于实现数据冗余备份、读写分离等。

工作原理

  1. 主库记录二进制日志:主库将所有对数据库进行修改的操作(如 INSERT、UPDATE、DELETE 等)记录到二进制日志(binary log)中。

  2. 从库请求日志:从库通过 I/O 线程连接到主库,请求主库的二进制日志。

  3. 主库发送日志:主库接收到从库的请求后,通过二进制日志转储线程(binlog dump thread)将二进制日志发送给从库。

  4. 从库接收并应用日志:从库的 I/O 线程接收主库发送的二进制日志,并将其写入到中继日志(relay log)中,然后 SQL 线程读取中继日志,在从库上执行这些日志中的操作,从而实现与主库数据的同步。

1.配置master

1.更改配置文件,添加log-bin参数

[root@mysqla mysql]# vim /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-bin=mysql-bin	#开启二进制日志,将二进制日志文件前缀改为mysql-bin
default_authentication_plugin=mysql_native_password

[root@mysqla mysql]# /etc/init.d/mysqld restart		#重启mysql

2.进入mysql,创建用户专门做主从复制,用于slave端做认证

mysql> create user fjw@'%' identified by 'fjw';		#创建用户,%:所有权限,identified by:设置密码
mysql> GRANT replication slave ON *.* to fjw@'%';	#对创建的用户进行授权

3.查看master的状态,用于作为slave服务器连接到master的相关参数

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

2.配置slave

1.在从设备上安装源码编译的mysql

#使用scp拷贝从master设备拷贝到slave
[root@mysqla mysql]# scr -r /usr/local/mysql root@172.25.254.20:/usr/local/

#slave设备也要部署一遍mysql

2.编写配置文件

[root@mysqlb mysql]# vim /etc/my.cnf
[mysqld]
server-id=20
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password

[root@mysqlb mysql]# /etc/init.d/mysqld restart

3.设置从服务器连接到主服务器的相关参数

[root@mysqlb mysql]# mysql -uroot -pyyy
mysql> CHANGE MASTER TO							#指定master
    -> MASTER_HOST='172.25.254.10',				#指定主服务器的 IP 地址
    -> MASTER_USER='fjw',						#指定用于主从复制的用户名
    -> MASTER_PASSWORD='yyy',					#指定对应用户的密码
    -> MASTER_LOG_FILE='mysql-bin.000001',		#主库二进制日志文件名
    -> MASTER_LOG_POS=437;						#指定从日志文件在哪个位置

#启服务器的复制进程
mysql> start slave;
#检查复制状态,确保 Slave_IO_Running 和 Slave_SQL_Running 都为 Yes,表示主从复制配置成功并正常运行。
mysql> SHOW SLAVE STATUS\G;
   Slave_IO_Running: Yes
   Slave_SQL_Running: Yes
   
#如果要重新填入信息
mysql> stop slave;
mysql> RESET SLAVE ALL;

4.测试,在主设备上创建数据库与表在从设备上查看是否同步上

#在master创建数据库与表
[root@mysqla mysql]# mysql -uroot -pyyy
mysql> create database fjw;
mysql> use fjw;
mysql> create table userlist( name varchar(10) not null ,id varchar(10) not null );
mysql> insert into userlist values('fjw','123');
mysql> select * from fjw.userlist;
+------+-----+
| name | id  |
+------+-----+
| fjw  | 123 |
+------+-----+

#在slave中查看数据是否有同步过来
mysql> select * from fjw.userlist;
+------+-----+
| name | id  |
+------+-----+
| fjw  | 123 |
+------+-----+

3.存在数据时添加slave2

1.完成slave2的基础配置,部署mysql

#配置文件设置
[root@mysqlc ~]# vim /etc/my.cnf
[mysqld]
server-id=30
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password

[root@mysqlc ~]# /etc/init.d/mysqld restart

2.从master节点备份数据

#在生产环境中备份需要缩表,保证备份前后的数据一致
mysql> FLUSH TABLES WITH READ LOCK;
备份后再解锁
mysql> UNLOCK TABLES;
#备份数据
[root@mysqla ~]# mysqldump -uroot -pyyy fjw  > /mnt/fjw.sql
#将备份的数据拷贝给slave2
[root@mysqla ~]# scp /mnt/fjw.sql root@172.25.254.30:/mnt/

3.在slave2导入数据

利用master节点中备份出来的lee.sql在slave2中拉平数据,只有拉平数据了才能配置组从复制

#创建与master一样的数据库
[root@mysqlc ~]# mysql -uroot -pyyy -e 'create database fjw;'
#导入数据到数据库
[root@mysqlc ~]# mysql -uroot -pyyy fjw < /mnt/fjw.sql
#查看导入的数据是否与master一样
[root@mysqlc ~]# mysql -uroot -pyyy -e 'select * from fjw.userlist;'
+------+-----+
| name | id  |
+------+-----+
| fjw  | 123 |
+------+-----+
#一样即可配置为组从复制

4.配置为slave

#在master中查询日志pos
[root@mysqla ~]# mysql -uroot -pyyy -e 'show master status;'
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |     1082 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
#在slave2进行配置
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10',MASTER_USER='fjw',MASTER_PASSWORD='fjw',MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=1082;
mysql> start slave;
mysql> show slave status\G;
 Slave_IO_Running: Yes
 Slave_SQL_Running: Yes

5.测试,在master插入新数据看是否同步到slave中

#在masger插入数据
[root@mysqla ~]# mysql -uroot -pyyy -e 'insert into fjw.userlist values("yyy","456");'
[root@mysqla ~]# mysql -uroot -pyyy -e 'select * from fjw.userlist'
+------+-----+
| name | id  |
+------+-----+
| fjw  | 123 |
| yyy  | 456 |
+------+-----+

#slave中查看

[root@mysqlc ~]# mysql -uroot -pyyy -e 'select * from fjw.userlist'
+------+-----+
| name | id  |
+------+-----+
| fjw  | 123 |
| yyy  | 456 |
+------+-----+

建议配置好组从复制后,从设备配置只读不能写

在配置文件添加参数

[root@mysqlc ~]# vim /etc/my.cnf
[mysqld]
server-id=30
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
read-noly=1				#其他用户只读
super-read-only=1		#root用户只读

[root@mysqlc ~]# /etc/init.d/mysqld restart

4.GTID模式

什么是GTID模式

        GTID(Global Transaction ID,全局事务标识符)是数据库领域中用于唯一标识数据库事务的一种机制,主要应用于 MySQL 等关系型数据库的主从复制场景,用于简化复制配置、提高故障切换效率和数据一致性保障;工作原理是基于 “为每个事务分配全局唯一标识”,通过追踪事务的生成和执行状态生产GTID集合,实现 MySQL 主从复制的自动化管理。

GTID 的作用

  1. 简化主从复制配置:传统复制需要手动指定主库的二进制日志文件和偏移量,而 GTID 模式下,从库只需连接主库并启用 GTID,即可自动同步数据。

  2. 提高故障恢复效率:当主库宕机后,从库可以通过对比 GTID 集合,快速找到拥有最新数据的从库作为新主库,减少切换时间。

  3. 增强数据一致性:通过 GTID 可以清晰追踪每个事务的执行情况,避免重复执行或遗漏事务,确保主从数据一致。

我们可以进行一个对比:

当未启用gtid时我们要考虑的问题

        在传统复制中,由于多个从库各自维护自己的 File 和 Position,当主库出现故障,从库之间的数据状态可能不一致。同时,在复制过程中,可能会因为网络问题、日志解析错误等,导致部分从库遗漏或重复执行事务,从而造成主从数据不一致。

当激活GITD之后

       

        当master出现问题后,会比较GTID集合比较出slave2和master的数据最接近,会被作为新的master slave1指向新的master,但是他不会去检测新的master的pos id,只需要继续读取自己gtid_next即可。

        GTID 的核心是通过 “全局唯一标识 + 事务级追踪”,将传统基于物理日志位置的复制,升级为基于逻辑事务的同步。主库生成 GTID 并记录事务,从库通过 GTID 自动判断是否需要执行事务,最终实现复制配置简化、故障切换自动化和数据一致性保障。

配置GTID

1.停止传统的主从复制

#slave1
[root@mysqlb ~]# mysql -uroot -pyyy -e 'stop slave;'
[root@mysqlb ~]# mysql -uroot -pyyy -e 'reset slave all;'
#slave2
[root@mysqlc ~]# mysql -uroot -pyyy -e 'stop slave;'
[root@mysqlc ~]# mysql -uroot -pyyy -e 'reset slave all;'

2.设置配置文件

#master端和slave端都要开启gtid模式
#master
[root@mysqla ~]# vim /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-bin=mysql-bin
default_authentication_plugin=mysql_native_password
gtid_mode=ON					#开启gtid模式
enforce-gtid-consistency=ON		#开启gtid的强一致性

#更改完配置文件后重启mysql
[root@mysqla ~]# /etc/init.d/mysqld restart

#slave1
[root@mysqlb ~]# vim /etc/my.cnf
[mysqld]
server-id=20
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
gtid_mode=ON					
enforce-gtid-consistency=ON

[root@mysqlb ~]# /etc/init.d/mysqld restart

#slave2
[root@mysqlc ~]# vim /etc/my.cnf
[mysqld]
server-id=30
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
gtid_mode=ON					
enforce-gtid-consistency=ON

[root@mysqlc ~]# /etc/init.d/mysqld restart

#配置完配置文件重启后,进入mysql查看gtid的状态显示是开启的
mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery      | ON        |
| enforce_gtid_consistency         | ON        |
| gtid_executed                    |           |
| gtid_executed_compression_period | 0         |
| gtid_mode                        | ON        |
| gtid_next                        | AUTOMATIC |	#自动记录追踪porid
| gtid_owned                       |           |
| gtid_purged                      |           |
| session_track_gtids              | OFF       |
+----------------------------------+-----------+

3.设置slave连接master,实现gtid模式的主从

#slave1服务器进入mysql进行配置
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='fjw', MASTER_PASSWORD='fjw', MASTER_AUTO_POSITION=1;	#使slave的porid与masger的一致

mysql> start slave;
mysql> show slave status\G;
......
             Slave_IO_Running: Yes		#显示与master主从连接成功
            Slave_SQL_Running: Yes
......
			Auto_Position: 1		#开启了与master的gtid主从模式
......

#同理salve2
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='fjw', MASTER_PASSWORD='fjw', MASTER_AUTO_POSITION=1;
mysql> start slave;
mysql> show slave status\G;

5.延迟复制

延迟复制时用来控制sql线程的,和i/o线程无关

这个延迟复制不是i/o线程过段时间来复制,i/o是正常工作的

是日志已经保存在slave端了,那个sql要等多久进行回放

延迟复制控制的是sql线程回放的过程

#在slave端
mysql> STOP SLAVE SQL_THREAD;
mysql> CHANGE MASTER TO MASTER_DELAY=60;
mysql> START SLAVE SQL_THREAD;
mysql> SHOW SLAVE STATUS\G;
             Master_Server_Id: 1
                  Master_UUID: db2d8c92-4dc2-11ef-b6b0-000c299355ea
             Master_Info_File: /data/mysql/master.info
                    SQL_Delay: 60			##延迟效果
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400

延迟复制已经在高mysql版本被取代了这里仅作了解

6.慢查询日志

        MySQL 的慢查询日志(Slow Query Log)是一种用于记录执行时间超过指定阈值的 SQL 语句的日志文件,主要用于排查和优化执行效率低下的查询,提升数据库性能。

核心作用

  • 定位低效 SQL:记录执行时间过长的查询,帮助开发者或运维人员发现耗时操作(如未优化的复杂查询、缺少索引的语句等)。

  • 性能优化依据:通过分析慢查询日志,可针对性地优化 SQL 语句、调整索引或优化数据库结构

开启慢查询日志功能

#用于临时动态开启慢查询日志(无需重启 MySQL 服务)。
mysql> SET GLOBAL slow_query_log=ON;
#永久开启,编辑配置文件
[mysqld]
slow_query_log = ON

#设置 “慢查询时间阈值” 的命令,默认是10s,超过这个阈值的命令就会被列入慢查询日志中
mysql> SET long_query_time=4;
#永久开启
[mysqld]
long_query_time = 4

mysql> SHOW VARIABLES like "slow%";
+---------------------+----------------------------------+
| Variable_name       | Value                            |
+---------------------+----------------------------------+
| slow_launch_time    | 2                                |		#慢启动的线程间隔,用于监控连接建立的效率
| slow_query_log      | ON                               |		#查看慢查询日志开启
| slow_query_log_file | /data/mysql/mysql-node1-slow.log |		#指定了慢查询日志的存储路径和文件名
+---------------------+----------------------------------+

mysql> SHOW VARIABLES like "long%";		#查看查询事件阈值
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 4.000000 |
+-----------------+----------+

测试慢查询

#用于测试sql语句
mysql> select sleep (10);

[root@mysqla ~]# cat /data/mysql/mysqla-slow.log
/usr/local/mysql/bin/mysqld, Version: 8.0.40 (Source distribution). started with:
Tcp port: 3306  Unix socket: /data/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 2025-08-02T00:42:59.892816Z
# User@Host: root[root] @ localhost []  Id:    13
# Query_time: 10.008170  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 1
SET timestamp=1754095369;
select sleep (10);

7.并行复制

什么是并行复制?

        MySQL 中的并行复制(Parallel Replication)是一种优化从库并行执行主库事务的机制,用于解决传统单线程复制(SQL 线程串行执行)导致的延迟问题,提升从库同步效率。

传统复制的瓶颈

传统主从复制中,从库有两个核心线程:

  • I/O 线程:负责接收主库的二进制日志,写入本地中继日志(relay log)。

  • SQL 线程:单线程读取中继日志进行回放,逐条执行事务。

默认情况下slave中使用的是sql单线程回放

在master中时多用户读写,如果使用sql单线程回放那么会造成组从延迟严重

开启MySQL的多线程回放可以解决上述问题。

并行复制的核心思想

        并行复制通过多线程同时执行多个事务,利用从库的多核 CPU 资源,加快中继日志读取回放的速度,减少同步延迟。

其实现依赖对事务的分组策略,核心是:多个无冲突的事务可以并行执行

配置并行复制

#在slaves中设定
[root@mysqlb ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
server-id=2
gtid_mode=ON
enforce-gtid-consistency=ON

slave-parallel-type=LOGICAL_CLOCK			#基于逻辑时钟的并行模式
slave-parallel-workers=16					#开启线程数量
relay_log_recovery=ON						#日志回放恢复功能开启

[root@mysqlb ~]# /etc/init.d/mysql restart

半同步模式

1.主从复制原理

三个线程

实际上主从同步的原理就是基于 binlog 进行数据同步的。在主从复制过程中,会基于3 个线程来操作,一个主库线程,两个从库线程。

  • 二进制日志转储线程(Binlog dump thread)是一个主库线程。当从库线程连接的时候, 主库可以将二进制日志发送给从库,当主库读取事件(Event)的时候,会在 Binlog 上加锁,读取完成之后,再将锁释放掉。

  • 从库 I/O 线程会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库的二进制日志转储线程发送的 Binlog 更新部分,并且拷贝到本地的中继日志 (Relay log)。

  • 从库 SQL 线程会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同步。

复制三步骤

步骤1:Master将写操作记录到二进制日志(binlog)。

步骤2:Slave将Master的binary log events拷贝到它的中继日志(relay log);

步骤3:Slave重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的,而且重启后从接入点开始复制。

具体操作

1.slaves端中设置了master端的ip,用户,日志,和日志的Position,通过这些信息取得master的认证及信息

2.master端在设定好binlog启动后会开启binlog dump的线程

3.master端的 dump线程把二进制的更新发送到slave端的i/o线程

4.slave端开启两个线程,一个是I/O线程,一个是sql线程,

  • i/o线程用于接收master端的二进制日志,此线程会在本地打开relaylog中继日志,并且保存到本地磁盘

  • sql线程读取本地relaylog中继日志进行回放

5.什么时候我们需要多个slave?

当读取的而操作远远高与写操作时。我们采用一主多从架构,反之写操作多时会采用多主的架构

数据库外层接入负载均衡层并搭配高可用机制

2.原理架构缺陷

从架构采用的是异步机制

master更新完成后直接发送二进制日志到slave,但是slaves是否真正保存了数据master端不会检测

master端直接保存二进制日志到磁盘

当master端到slave端的网络出现问题时或者master端直接挂掉,二进制日志可能根本没有到达slave

master出现问题slave端接管master,这个过程中数据就丢失了

这样的问题出现就无法达到数据的强一致性,零数据丢失

3.半同步模式原理

1.用户线程写入完成后master中的dump会把日志推送到slave端

2.slave中的io线程接收后保存到relaylog中继日志

3.保存完成后slave向master端返回ack

4.在未接受到slave的ack时master端时不做提交的,一直处于等待当收到ack后提交到存储引擎

5.在5.6版本中用到的时after_commit模式,after_commit模式时先提交在等待ack返回后输出ok

4.启动半同步模式

1.master配置

#master永久开启半同步功能
[root@mysqla ~]# vim /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-bin=mysql-bin
default_authentication_plugin=mysql_native_password
gtid_mode=ON
enforce-gtid-consistency=ON

emi_sync_master_enabled=1			#开启半同步功能,永久开启重启的话要在mysql安装插件不然重启会报错

[root@mysqla ~]# mysql -uroot -pyyy
#安装半同步插件,发送ACK与接收ACK都是基于插件工作
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';	#SONAME服务级别的模块,SO服务级

#查看插件运行情况
mysql> SHOW PLUGINS; 
rpl_semi_sync_master            | ACTIVE   | REPLICATION        | semisync_master.so | GPL 

#临时启动半同步功能,重启无效
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

#查看半同步功能状态
mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+-------------------------------------------+------------+
| 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 |
+-------------------------------------------+------------+

2.slave配置

#永久开启半同步功能,需要安装插件才能重启
[root@mysqlb~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
server-id=1
log-bin=mysql-bin
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_slave_enabled=1			#开启半同步功能
symbolic-links=0

[root@mysqlb ~]# mysql -uroot -pyyy
#注意安装的插件是slave与master不同
mysql>  INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';	

mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;

#重启io线程,半同步才能生效
mysql> STOP SLAVE IO_THREAD;			
mysql> START SLAVE IO_THREAD;

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

mysql>  SHOW STATUS LIKE 'Rpl_semi_sync%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
#同理多台slave也是这么配置注意安装插件跟启动功能slave端的要改为slave

3.测试

在master写入数据

mysql> insert  into fjw.userlist values ('user4','123');
#查看同步情况
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |	#slave端数量
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 1     |	#master等待salve确认的总次数
| Rpl_semi_sync_master_no_times              | 0     |	#超时切换为半同步的次数
| Rpl_semi_sync_master_no_tx                 | 0     |	#未同步数据为0笔
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 1283  |
| Rpl_semi_sync_master_tx_wait_time          | 1283  |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     |	#主库等待从库确认后成功提交的事务总数
+--------------------------------------------+-------+

 模拟故障,在salve端

[root@mysqlb ~]# mysql -pyyy
mysql> STOP SLAVE IO_THREAD;

#在master端再次写入数据
mysql> insert  into fjw.userlist values ('user5','123');
					#等待10s超时
#查看同步情况					
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| 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             | 2     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |	#显示一笔数据未同步
| Rpl_semi_sync_master_status                | OFF   |	#当超时后自动转为异步,slave恢复后转回半同步
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 1283  |
| Rpl_semi_sync_master_tx_wait_time          | 1283  |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     |	
+--------------------------------------------+-------+