目录
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)的技术,常用于实现数据冗余备份、读写分离等。
工作原理
主库记录二进制日志:主库将所有对数据库进行修改的操作(如 INSERT、UPDATE、DELETE 等)记录到二进制日志(binary log)中。
从库请求日志:从库通过 I/O 线程连接到主库,请求主库的二进制日志。
主库发送日志:主库接收到从库的请求后,通过二进制日志转储线程(binlog dump thread)将二进制日志发送给从库。
从库接收并应用日志:从库的 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 的作用
简化主从复制配置:传统复制需要手动指定主库的二进制日志文件和偏移量,而 GTID 模式下,从库只需连接主库并启用 GTID,即可自动同步数据。
提高故障恢复效率:当主库宕机后,从库可以通过对比 GTID 集合,快速找到拥有最新数据的从库作为新主库,减少切换时间。
增强数据一致性:通过 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 |
+--------------------------------------------+-------+