案例:CentOS8 在 MySQL8.0 实现半同步复制

异步复制

MySQL 默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主节点如果 crash 掉了,此时主节点上已经提交的事务可能并没有传到从库上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

案例:CentOS8 在 MySQL8.0 实现半同步复制_第1张图片

全同步复制

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

案例:CentOS8 在 MySQL8.0 实现半同步复制_第2张图片

半同步复制( 半异步复制 )

是介于全同步复制与全异步复制之间的一种,主库只需要等待至少一个从库节点收到并且 Flush Binlog 到 Relay Log 文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全完成并且提交的反馈,如此,节省了很多时间。

时间阈值概念:如果主节点服务器仅同步数据到其中一个从节点速度也很慢。( 比如设置超时阈值 10S ,从节点 10S 没有数据同步完成并反馈结果,主节点会直接将结果返回客户端。不等你从节点完成同步了。 )

案例:CentOS8 在 MySQL8.0 实现半同步复制_第3张图片

范例:CentOS8 在 MySQL8.0 实现半同步复制

注意:每个数据库版本半同步复制的方法有所不同

建议:

二进制日志格式( ROW 行类型 )

所有节点都开启二进制日志功能( 并将二进制日志文件分开存放 )

所有从节点开启只读功能( read-only )

// 前置工作
yum install mysql-server -y
systemctl enable --now mysqld

// 创建二进制日志目录
mkdir /data/log/mysql -p
chown -R mysql:mysql /data/log/mysql

// 关闭防火墙 and SELinux
setenforce 0
systemctl disable --now firewalld
# 查看插件文件 ( 库文件 )
[root@master ~] rpm -ql mysql-server | grep semisync
/usr/lib64/mysql/plugin/semisync_master.so
/usr/lib64/mysql/plugin/semisync_replica.so
/usr/lib64/mysql/plugin/semisync_slave.so
/usr/lib64/mysql/plugin/semisync_source.so

# master 服务器配置
[root@master ~] vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=8
log-bin
rpl_semi_sync_master_enabled=ON    # 修改此行, 需要先安装 semisync_master.so 插件后, 再重启, 否则无法启动 ( 开启主节点的半同步功能 )
rpl_semi_sync_master_timeout=3000  # 超时阈值: 设置 3s 内无法同步, 也将返回成功信息给客户端  ( 默认: 10S )

// 创建账户并授权
mysql> show master logs;    # 查看位置
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |       156 | No        |
+---------------+-----------+-----------+
1 row in set (0.00 sec)

mysql> create user repluser@'192.168.80.%' identified by '123456';
mysql> grant replication slave on *.* to 'repluser'@'192.168.80.%';

// slave1 服务器配置
[root@slave1 ~] vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=18
rpl_semi_sync_slave_enabled=ON    # 修改此行, 需要先安装 semisync_slave.so 插件后, 再重启, 否则无法启动 ( 插件开机自启 )

// slave2 服务器配置
[root@slave2 ~] vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=28
rpl_semi_sync_slave_enabled=ON    # 修改此行, 需要先安装 semisync_slave.so 插件后, 再重启, 否则无法启动  ( 插件开机自启 )

// 主服务器配置:
mysql> SHOW PLUGINS;    # 查看插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; # 永久安装插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled=1;        # 临时修改变量
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 3000;   # 超时长 3S, 默认值为 10s
mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 3000       |
| 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)

// 从节点连接主节点 ( "两台从节点都配置" )
mysql> CHANGE MASTER TO
  MASTER_HOST='192.168.80.8',
  MASTER_USER='repluser',
  MASTER_PASSWORD='123456',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='binlog.000001',
  MASTER_LOG_POS=156;

// 从服务器配置 ( "两个从节点都需要安装好插件" )
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;         # 临时修改变量
mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';     # 验证从服务器插件启用状态
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

// 从节点重启数据库服务
[root@slave1 ~] systemctl restart mysqld
[root@slave2 ~] systemctl restart mysqld

# 注意: 如果已经实现主从复制, 需要 stop slave;start slave;

mysql> start slave;
mysql> SHOW GLOBAL STATUS LIKE '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.01 sec)

// 主节点查看从节点状态 
mysql> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |        # 数量
| 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 slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.80.8
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000001
          Read_Master_Log_Pos: 689
               Relay_Log_File: centos8-relay-bin.000003
                Relay_Log_Pos: 854
        Relay_Master_Log_File: binlog.000001
             Slave_IO_Running: Yes                # 运行中
            Slave_SQL_Running: Yes
                # 运行中

// 验证半同步复制
mysql> create database db1;    # 主节点
mysql> show databases;         # 从节点
mysql> show databases;         # 从节点

案例:CentOS8 在 MySQL8.0 实现半同步复制_第4张图片

// "测试效果"
stop slave;        # 两个从节点停止复制线程
stop slave;        # 两个从节点停止复制线程
create database db2;    # 主节点创建数据库 ( 三秒后自动完成创建 因为超过了阈值 )

案例:CentOS8 在 MySQL8.0 实现半同步复制_第5张图片

start slave;        # 两个从节点启用复制线程
start slave;        # 两个从节点启用复制线程

 案例:CentOS8 在 MySQL8.0 实现半同步复制_第6张图片

你可能感兴趣的:(Linux,小技巧,数据库)