mysql 的主从复制

(一)主从复制

在主从复制架构中,将 MySQL 服务器分为主服务器(Master)和从服务器(Slave)两种角色,主服务器负责数据写入 (insert,update,delete,create 等),从服务器负责提供查询服务(select 等)。

1.零数据一主一从实践

两个主机都是rocky的

|-----------|--------|---------|
| 主机ID | 角色 | mysql版本 |
| 10.0.0.30 | master | 8.0.41 |
| 10.0.0.31 | slave | 8.0.41 |

bash 复制代码
selinux环境关闭
[root@rocky30 ~]  vim /etc/selinux/config 
......
SELINUX=disabled
......
(1)主节点配置
bash 复制代码
安装软件
[root@rocky30 ~]  yum makecache ;yum install mysql-server -y

建立文件目录
 mkdir -p /data/mysql/logbin

赋予属性
[root@rocky30 ~]  chown -R mysql.mysql /data/mysql/

主节点mysql配置

bash 复制代码
vim /etc/my.cnf.d/mysql-server.cnf

[mysqld]
server-id=177                                             #指定server-id
log_bin=/data/mysql/logbin/mysql-bin                      #指定二进制文件路径
default_authentication_plugin=mysql_native_password       #避免出现认证问题


[root@rocky30 ~]  systemctl restart mysqld
[root@rocky30 ~]  ll /data/mysql/logbin/
总用量 12
-rw-r----- 1 mysql mysql 180 12月  4 17:18 mysql-bin.000001
-rw-r----- 1 mysql mysql 157 12月  4 17:18 mysql-bin.000002
-rw-r----- 1 mysql mysql  72 12月  4 17:18 mysql-bin.index
bash 复制代码
#创建账号并授权
mysql> create user repluser@'10.0.0.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to repluser@'10.0.0.%';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
(2)从节点配置
bash 复制代码
安装软件
[root@rocky30 ~]  yum makecache ;yum install mysql-server -y

建立文件目录
 mkdir -p /data/mysql/logbin

赋予属性
[root@rocky30 ~]  chown -R mysql.mysql /data/mysql/

从节点mysql配置

bash 复制代码
vim /etc/my.cnf.d/mysql-server.cnf

[mysqld]
server-id=177                                             #指定server-id
read-only                                                 #只读模式;根据实际情况看加不加
log_bin=/data/mysql/logbin/mysql-bin                      #指定二进制文件路径
default_authentication_plugin=mysql_native_password       #避免出现认证问题

[root@rocky30 ~]  systemctl restart mysqld
[root@rocky30 ~]  ll /data/mysql/logbin/
总用量 12
-rw-r----- 1 mysql mysql 180 12月  4 17:18 mysql-bin.000001
-rw-r----- 1 mysql mysql 157 12月  4 17:18 mysql-bin.000002
-rw-r----- 1 mysql mysql  72 12月  4 17:18 mysql-bin.index

配置账号级别的主从同步

bash 复制代码
30主机;主节点中找到相关的信息
mysql> show master logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       180 | No        |
| mysql-bin.000002 |       872 | No        |
| mysql-bin.000003 |       157 | No        |
+------------------+-----------+-----------+
3 rows in set (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      157 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

给从节点设定配置
CHANGE MASTER TO MASTER_HOST='10.0.0.30', MASTER_USER='repluser',
MASTER_PASSWORD='123456', MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=157;

查看从节点状态
show slave status\G
(3)启动同步操作

启动slave

bash 复制代码
从节点
mysql> start slave;

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
bash 复制代码
主节点上可以看到
ss -tun
Netid         State         Recv-Q         Send-Q                      Local Address:Port                         Peer Address:Port          
......
tcp           ESTAB         0              0                      [::ffff:10.0.0.30]:3306                   [::ffff:10.0.0.31]:50188    
(4)数据同步测试

在master 节点上写入数据

bash 复制代码
创建数据库并且创建表和数据
mysql> create database db1;
Query OK, 1 row affected (0.00 sec)

mysql> use db1;
Database changed
mysql> CREATE TABLE `student` (
    -> `id` int unsigned NOT NULL AUTO_INCREMENT,
    -> `name` varchar(20) NOT NULL,
    -> `age` tinyint unsigned DEFAULT NULL,
    -> `gender` enum('M','F') DEFAULT 'M',
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB;

mysql> insert into student (name,age,gender)values('user1',10,'M'),('user2',20,'F'),('user3',30,'M');

在slave节点上查看数据

bash 复制代码
已经同步过来了
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| db1;              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

注意:同步的数据非常大量的时候会出现延迟

2.有数据一主一从

如果数据库在运行了一段时间后,已经产生了大量数据,或者重置了二进制日志,刷新了二进制日志的情况下,我们要配置主从,则要保证将已有的数据先备份出来,导入到从节点之后,再开启主从同步。

|-----------|--------|---------|
| 主机ID | 角色 | mysql版本 |
| 10.0.0.30 | master | 8.0.41 |
| 10.0.0.31 | slave | 8.0.41 |

这里是连着上一个例子继续做的所以先清空一下环境

(1)清空环境

从节点清理

bash 复制代码
[root@rocky31 ~]  systemctl stop mysqld
[root@rocky31 ~]  rm -rf /var/lib/mysql/*
[root@rocky31 ~]  rm -rf /data/mysql/logbin/*
[root@rocky31 ~]  systemctl start mysqld

主节点重置

bash 复制代码
mysql> reset master;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave hosts;
Empty set, 1 warning (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      157 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
(2)全量数据同步(master节点)

从这一步开始是真的开始在主从数据不一致的情况下开始对两个主机惊醒同步

在master节点中全量备份数据

bash 复制代码
mysqldump -A -F --source-data=1 --single-transaction > all.sql

主节点确认日志效果
mysql> show master logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       204 | No        |
| mysql-bin.000002 |       157 | No        |
+------------------+-----------+-----------+
2 rows in set (0.00 sec)

把日志文件给slave主机
[root@rocky30 ~]  scp all.sql root@10.0.0.31:

主节点中确定账号,没有就创建
mysql> select user,host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| repluser         | 10.0.0.%  |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
(3)从节点配置
bash 复制代码
配置文件定制
vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=183
read-only
log-bin=/data/mysql/logbin/mysql-bin
default_authentication_plugin=mysql_native_password # 避免出现认证问题

修改备份文件(拿过来的日志文件不能直接用,要加认证信息不然别人不认为你是合法的)

bash 复制代码
[root@rocky31 ~]  vim all.sql
CHANGE MASTER TO
MASTER_HOST='10.0.0.30',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=157;

从节点加载语句

bash 复制代码
因为是导数据,所以需要关闭二进制日志
mysql> set sql_log_bin=0;

开始导入数据
mysql> source /root/all.sql

检查状态

bash 复制代码
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.0.0.30
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 157
               Relay_Log_File: rocky31-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: No                         # 主从环境导入成功了
(4) 启动同步

主角色启动同步线程

bash 复制代码
#启动同步线程
mysql> start slave;

mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 10.0.0.12
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 157
Relay_Log_File: rocky9-relay-bin.000002
Relay_Log_Pos: 326
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes # 主从环境恢复了

从节点数据库确认效果

bash 复制代码
mysql> set @@sql_log_bin=1;
mysql> use db1;
Database changed
mysql> select * from student;
+----+-------+------+--------+
| id | name | age | gender |
+----+-------+------+--------+
| 1 | user1 | 10 | M |
| 2 | user2 | 20 | F |
| 3 | user3 | 30 | M |
+----+-------+------+--------+
3 rows in set (0.00 sec)
(5)测试
bash 复制代码
主节点添加
mysql> insert into student (name,age,gender)values('user4',40,'M');

从节点查看
mysql> select * from student;
+----+-------+------+--------+
| id | name | age | gender |
+----+-------+------+--------+
| 1 | user1 | 10 | M |
| 2 | user2 | 20 | F |
| 3 | user3 | 30 | M |
| 4 | user4 | 40 | M |
+----+-------+------+--------+
4 rows in set (0.00 sec)

3.一主多从实现

环境架构

|-----------|--------|---------|
| 主机ID | 角色 | mysql版本 |
| 10.0.0.30 | master | 8.0.41 |
| 10.0.0.31 | slave | 8.0.41 |
| 10.0.0.32 | slave | 8.0.41 |

同样的先把selinux关了

vim /etc/selinux/config

关闭防火墙

systemctl disable --now firewalld.service

(1)新增从节点配置
bash 复制代码
安装软件
yum install mysql-server -y

创建目录
mkdir -p /data/mysql/logbin

修改属主属组
chown -R mysql.mysql /data/mysql/

从节点mysql配置

bash 复制代码
配置文件
vim /etc/my.cnf.d/mysql-server.cnf
server-id=186                                             #指定server-id
read-only                                                 #只读模式
log-bin=/data/mysql/logbin/mysql-bin                      #指定二进制文件路径
default_authentication_plugin=mysql_native_password       #避免出现认证问题

启动服务
systemctl start mysqld.service

基础数据同步

bash 复制代码
主节点导出备份数据,复制到新增节点
mysqldump -A --source-data=1 --single-transaction >all.sql
scp all.sql 10.0.0.32:
(2)从节点同步账号配置
bash 复制代码
在从节点上修改备份文件
vim all.sql
CHANGE MASTER TO
 MASTER_HOST='10.0.0.30',
 MASTER_USER='repluser',
 MASTER_PASSWORD='123456',
 MASTER_PORT=3306,
 MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=1722;

从节点启动服务,导入备份

bash 复制代码
关闭从节点的二进制日志
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

导入日志文件
mysql> source /root/all.sql;

查看
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.0.0.30
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 1722
               Relay_Log_File: rocky32-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: No
            Slave_SQL_Running: No
(3)启动同步操作
bash 复制代码
从节点
mysql> start slave;


恢复二进制文件
set sql_log_bin=1;

查看
show processlist\G
*************************** 3. row ***************************
     Id: 12
   User: repluser
   Host: 10.0.0.31:56416
     db: NULL
Command: Binlog Dump
   Time: 10270
  State: Source has sent all binlog to replica; waiting for more updates
   Info: NULL
*************************** 4. row ***************************
     Id: 14
   User: repluser
   Host: 10.0.0.32:38078
     db: NULL
Command: Binlog Dump
   Time: 360
  State: Source has sent all binlog to replica; waiting for more updates
   Info: NULL
4 rows in set, 1 warning (0.00 sec)

4.级联复制实现

环境架构

|-----------|--------------|---------|
| 主机ID | 角色 | mysql版本 |
| 10.0.0.30 | master | 8.0.41 |
| 10.0.0.31 | middle-slave | 8.0.41 |
| 10.0.0.32 | slave | 8.0.41 |

级联同步架构中,有一个中间节点的角色,该节点从主节点中同步数据,并充当其它节点的数据源,所以在此情况下,我们需要保证中间节点从主节点中同步过来的数据,同样也要写二进制日志,否则后续节点无法获取数据。(相当于31主机是32的主)

在31主机的配置文件中要开启 log_slave_updates 选项

(1)中间节点配置

注意:中间节点要保证: 1.开启二进制日志
2.从主节点上同步过来的数据,要能写到二进制日志中

bash 复制代码
mysql> select @@log_slave_updates;
+---------------------+
| @@log_slave_updates |
+---------------------+
|                   1 |
+---------------------+
bash 复制代码
vim /etc/my.cnf.d/mysql-server.cnf
......
[mysqld]
server-id=183
read-only
log_slave_updates                             # 增加此选项
log-bin=/data/mysql/logbin/mysql-bin

重启服务器环境
[root@rocky31 ~]  systemctl restart mysqld.service

确认中间节点上有同步过来的账号信息, 如果没有的话,需要自己单独创建即可。

bash 复制代码
mysql> select user,host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| repluser         | 10.0.0.%  |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |

拷贝数据

bash 复制代码
导出中间节点数据
mysqldump -A -F --single-transaction --source-data=1 > middle-all.sql

拷贝到32主机
[root@rocky31 ~]  scp middle-all.sql 10.0.0.32:
(2)从节点配置

将10.0.0.32 节点的环境清理完毕

bash 复制代码
mysql> stop slave;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> reset slave all;
Query OK, 0 rows affected, 1 warning (0.01 sec)

[root@rocky32 ~]  systemctl stop mysqld
[root@rocky32 ~]  rm -rf /var/lib/mysql/*
[root@rocky32 ~]  rm -rf /data/mysql/logbin/*
[root@rocky32 ~]  systemctl start mysqld.service
bash 复制代码
修改配置
[root@rocky32 ~] cat /etc/my.cnf
......
[mysqld]
server-id=186
read-only
log-bin=/data/mysql/logbin/mysql-bin

临时关闭二进制日志
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@sql_log_bin;
+---------------+
| @@sql_log_bin |
+---------------+
| 0 |
+---------------+
(3)从节点导入数据
bash 复制代码
导入备份数据
mysql> source /root/middle-all.sql

开启二进制日志
mysql> set sql_log_bin=1;

查看主从状态
mysql> show slave status\G

启动同步
mysql> start slave;

查看状态
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
(4)数据同步测试
bash 复制代码
mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
|  2 | user2 |   20 | F      |
|  3 | user3 |   30 | M      |
+----+-------+------+--------+
3 rows in set (0.00 sec)

mysql> insert into student (name,age,gender)values('user6',60,'M');
Query OK, 1 row affected (0.00 sec)

mysql> delete from student where id=2;
Query OK, 1 row affected (0.01 sec)

mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
|  3 | user3 |   30 | M      |
|  4 | user6 |   60 | M      |
+----+-------+------+--------+

中间节点10.0.0.31查看数据

bash 复制代码
mysql> use db1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
|  3 | user3 |   30 | M      |
|  4 | user6 |   60 | M      |
+----+-------+------+--------+

从节点查看

bash 复制代码
mysql> use db1;
Database changed

mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
|  3 | user3 |   30 | M      |
|  4 | user6 |   60 | M      |
+----+-------+------+--------+

5.主主复制实现(互为主从)

环境架构

|-----------|-----------|---------|
| 主机ID | 角色 | mysql版本 |
| 10.0.0.30 | master-1 | 8.0.41 |
| 10.0.0.31 | masterr-2 | 8.0.41 |

根据前面的实验,master-2 己经是 master-1 的从节点了,此处只需要把 master-1 配置为 master-2 的从节点即可。

将前面10.0.0.32节点的数据清理

bash 复制代码
10.0.0.32中清理
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> reset slave all;
Query OK, 0 rows affected, 1 warning (0.01 sec)

10.0.0.31中验证
mysql> show slave hosts;
Empty set, 1 warning (0.00 sec)
(1)准备工作

master1节点配置

bash 复制代码
[mysqld]
server-id=177
log_bin=/data/mysql/logbin/mysql-bin
default_authentication_plugin=mysql_native_password

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql/mysqld.log
pid-file=/run/mysqld/mysqld.pid

master2配置

bash 复制代码
master2配置需要修改,去掉read-only
cat /etc/my.cnf.d/mysql-server.cnf
......
[mysqld]
server-id=183                          #ID 不要相同
# log_slave_updates                    #停掉
log-bin=/data/mysql/logbin/mysql-bin
default_authentication_plugin=mysql_native_password

重启
[root@rocky31 ~]  systemctl restart mysqld

注意:去掉read-only

查看master-2的 bin-log

bash 复制代码
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000009 |      157 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
(2)配置master-1主机为从角色

因为经过上面的实验两台主机的数据都是一样的,所以,无需重新加载数据服务了;首次配置要先把两个主机的数据同步

在master-1上配置

bash 复制代码
mysql> CHANGE MASTER TO
    -> MASTER_HOST='10.0.0.31',
    -> MASTER_USER='repluser',
    -> MASTER_PASSWORD='123456',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE='mysql-bin.000009',
    -> MASTER_LOG_POS=157;

在master-1上配置从角色
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.04 sec)
(3)测试同步效果

master-1进行写操作,master-2上查看

bash 复制代码
mysql> insert into student (name,age,gender)values('user7',70,'F');
Query OK, 1 row affected (0.01 sec)

mysql> insert into student (name,age,gender)values('user7',70,'F');
Query OK, 1 row affected (0.00 sec)

查看10.0.0.31
mysql> select * from db1.student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
|  3 | user3 |   30 | M      |
|  4 | user6 |   60 | M      |
|  5 | user7 |   70 | F      |
|  6 | user7 |   70 | F      |
+----+-------+------+--------+

master-2中删除数据,在master-1中查看效果

bash 复制代码
mysql> delete from db1.student where id in (1,3,4);

查看10.0.0.30
mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  5 | user7 |   70 | F      |
|  6 | user7 |   70 | F      |
+----+-------+------+--------+
(4)双主架构的注意事项

解析: 双主架构在实际生产环境中,并不会配置为两个节点都去写数据

可能会发生:如果同时在两个节点执行写操作,就可能会导致数据冲突,从而影响主从同步。

解决方式: 1.master1 通过忽略来解决问题

bash 复制代码
master-1上执行
停止主从
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

跳过1个错误事件
mysql> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

再次开启主从同步
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.03 sec)

2.根源修复

上述跳过事务的方法只是临时解决办法,可能会造成主从数据不一致。为了避免后续再次出现类似问题,你需要找出导致复制错误的根源并进行修复。以下是一些常见的原因及解决办法:

表结构不一致:

主从库的表结构可能存在差异,比如主库有某个字段,从库却没有。你需要确保主从库的表结构完全一致,可以通过 SHOW CREATE TABLE 语句查看表结构,并使用 ALTER TABLE 语句进行调整。

数据类型不匹配:

主从库的数据类型可能不同,导致复制时出现错误。要保证主从库的数据类型一致。

数据缺失或损坏:

主库中的某些数据在从库中缺失或者损坏,可能会引发复制错误。你可以通过备份恢复数据,或者手动同步缺失的数据。

3.没法了就只有把从节点破坏,再重新同步数据

6.半同步复制

主节点中数据落盘,写入binlog日志,然后将binlog日志中的新事件发送给从节点 ,等待所有从节点中有一个从节点返回同步成功之后,主节点就向客户端返回写入成功。

环境架构

|-----------|---------|---------|
| 主机ID | 角色 | mysql版本 |
| 10.0.0.30 | master | 8.0.41 |
| 10.0.0.31 | slave-1 | 8.0.41 |
| 10.0.0.32 | slave-2 | 8.0.41 |

官方帮助文档:

mysql 8.0:https://dev.mysq1.com/doc/refman/8.0/en/replication-semisync.html

mysql 5.7:https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html

mariadb:https://mariadb.com/kb/en/library/semisynchronous-replication/

将10.0.0.30 主机上的从角色清理掉

bash 复制代码
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> reset slave all;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show slave status;
Empty set, 1 warning (0.00 sec)
(1)在 MySQL8.0 中配置半同步需要安装插件支持
bash 复制代码
安装MySQL8.0中己有相关插件的支持文件
[root@rocky30 ~]  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

查看当前MySQL服务插件,如果没有semisync_master,则需要手动安装
mysql> show plugins;

安装插件

bash 复制代码
mysql>  INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

持久化加载插件的方法,修改配置文件
[mysqld]
plugin_load = "rpl_semi_sync_master=semisync_master.so"

安装完成后还需要手动开启插件

bash 复制代码
mysql>  select @@rpl_semi_sync_master_enabled;
+--------------------------------+
| @@rpl_semi_sync_master_enabled |
+--------------------------------+
|                              0 |
+--------------------------------+
(2)修改配置文件,开启插件
bash 复制代码
[root@rocky30 ~]  vim /etc/my.cnf.d/mysql-server.cnf
......
[mysqld]
server-id=177
log_bin=/data/mysql/logbin/mysql-bin
default_authentication_plugin=mysql_native_password
rpl_semi_sync_master_enabled                         # 增加功能,注意是 master关键字

重启服务
systemctl restart mysqld.service

查看是否开启
mysql>  select @@rpl_semi_sync_master_enabled;
+--------------------------------+
| @@rpl_semi_sync_master_enabled |
+--------------------------------+
|                              1 |
+--------------------------------+
(3)slave 节点配置插件

和上面的master节点配置是一样的,只是在安装的时候是:INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';在配置文件中增加的是:rpl_semi_sync_slave_enabled 属性

(4)slave-2节点配置
bash 复制代码
清理环境
[root@rocky32 ~]  systemctl stop mysqld.service
[root@rocky32 ~]  rm -rf /var/lib/mysql/*
[root@rocky32 ~]  rm -rf /data/mysql/logbin/*
[root@rocky32 ~]  systemctl start mysqld.service
bash 复制代码
[root@rocky32 ~]  vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=186
read-only
log-bin=/data/mysql/logbin/mysql-bin
default_authentication_plugin=mysql_native_password
rpl_semi_sync_slave_enabled                            # 增加该条属性

重启应用
[root@rocky32 ~]  systemctl restart mysqld.service
(5)在slave节点上开启主从
bash 复制代码
首先从10.0.0.30处同步数据到10.0.0.31和10.0.0.32
mysqldump -A -F --source-data=1 --single-transaction > all.sql
scp all.sql root@10.0.0.31:
scp all.sql root@10.0.0.32:

slave节点修改配置

bash 复制代码
vim all.sql
CHANGE MASTER TO
MASTER_HOST='10.0.0.30',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=157;

在slave节点上开启主从

bash 复制代码
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> source /root/all.sql;

mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
(6) master确认信息
bash 复制代码
mysql> show global variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |                #己开启
| rpl_semi_sync_master_timeout | 10000 |             #超时时长,1W毫秒,10S
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |    #指定几台slave节点收到binlog后就给客户端返回
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |     #当前同步策略
+-------------------------------------------+------------+


mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |    #有两个从节点
......
(7)数据同步测试
bash 复制代码
测试,在master节点上写入数据
mysql> create database db2;
Query OK, 1 row affected (0.00 sec)

mysql> use db2;
Database changed

创建数据表并增加数据
mysql> CREATE TABLE `student` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` tinyint unsigned DEFAULT NULL,
`gender` enum('M','F') DEFAULT 'M',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

mysql> insert into student(name,age,gender)values('user1',10,'M');
Query OK, 1 row affected (0.00 sec)

mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
+----+-------+------+--------+

从节点上查看效果

bash 复制代码
slave-1上查看
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| db2                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> use db2;

mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
+----+-------+------+--------+
1 row in set (0.00 sec)

在 slave-2 上查看
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| db2                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> use db2

mysql> select * from student;
+----+-------+------+--------+
| id | name  | age  | gender |
+----+-------+------+--------+
|  1 | user1 |   10 | M      |
+----+-------+------+--------+
1 row in set (0.00 sec)

可以停掉一个slave服务器测试能否在master上返回成功

7.GTID 复制

GTID(global transaction ID):全局事务ID

在mysql环境下,每一个数据级别的操作,都有一个全局唯一的定位值,定位的动作是自动的

(1)恢复环境

关闭所有的从角色

bash 复制代码
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> reset slave all;
Query OK, 0 rows affected, 1 warning (0.01 sec)

systemctl stop mysqld.service
rm -rf /var/lib/mysql/*
rm -rf /data/mysql/logbin/*
(2)slave配置修改
bash 复制代码
[root@rocky31 ~]  vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
server-id=183
read-only
# log_slave_updates
log-bin=/data/mysql/logbin/mysql-bin
default_authentication_plugin=mysql_native_password
# rpl_semi_sync_slave_enabled
gtid_mode=ON
enforce_gtid_consistency=ON

重启 mysql服务
systemctl restart mysqld.service
(3)master节点配置
bash 复制代码
[root@rocky30 ~] vim /etc/my.cnf.d/mysql-server.cnf
[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON
#增加这两行

重启
systemctl restart mysqld.service

把以前的数据库删除
mysql> drop database db1;
Query OK, 1 row affected (0.01 sec)

mysql> drop database db2;
Query OK, 1 row affected (0.01 sec)

重置mysql日志
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      157 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
(4) slave设置主从同步
bash 复制代码
在salve节点上设置主从同步
mysql> CHANGE MASTER TO
    -> MASTER_HOST='10.0.0.30',
    -> MASTER_USER='repluser',
    -> MASTER_PASSWORD='123456',
    -> MASTER_PORT=3306,
    -> MASTER_AUTO_POSITION=1; 
Query OK, 0 rows affected, 8 warnings (0.02 sec)

mysql> start slave;
bash 复制代码
主节点中查看从节点
mysql> SHOW SLAVE HOSTS;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|       183 |      | 3306 |       177 | 8b5154cc-d5a5-11f0-946b-000c29ab9d72 |
+-----------+------+------+-----------+--------------------------------------+
(5)测试数据同步
bash 复制代码
主节点中
mysql> create database db1;
Query OK, 1 row affected (0.00 sec)

mysql> use db1;
Database changed
mysql> CREATE TABLE `stu` (
    -> `id` int unsigned NOT NULL AUTO_INCREMENT,
    -> `name` varchar(20) NOT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into stu(name)values('user1');
Query OK, 1 row affected (0.01 sec)

mysql> select * from stu;
+----+-------+
| id | name  |
+----+-------+
|  1 | user1 |
+----+-------+
bash 复制代码
从节点中
mysql> show databases like '%db%';
+-----------------+
| Database (%db%) |
+-----------------+
| db1             |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from db1.stu;
+----+-------+
| id | name  |
+----+-------+
|  1 | user1 |
+----+-------+
1 row in set (0.00 sec)

8.MySQL 主从复制总结性步骤

一、前期准备(基础保障)

  1. 环境统一:主从 MySQL 版本尽量一致(避免兼容性问题),OS 时区 / 字符集统一;

  2. 网络放行:主库防火墙 / 安全组放行 3306 端口(仅允许从库 IP 访问),从库能 ping 通主库且 telnet 主库 3306 端口通;

  3. ID 规划 :主从server-id全局唯一(主库建议设 1,从库设 2/3...,不可重复)。
    二、主库配置(核心:开启 binlog + 创建复制用户)

  4. 修改配置文件/etc/my.cnf/etc/my.cnf.d/mysql-server.cnf),添加 / 修改:

    复制代码
    [mysqld]
    log_bin = mysql-bin       # 开启二进制日志(主从核心)
    server-id = 1             # 唯一ID
    bind-address = 0.0.0.0    # 允许从库访问(生产可限制网段)
    binlog_format = ROW       # 推荐行格式,复制更安全

    重启主库:systemctl restart mysqld

  5. 验证 binlog :登录主库执行show master status;,记录File(如 mysql-bin.000001)和Position(如 156);

  6. 创建复制用户 (最小权限原则):

    bash 复制代码
    CREATE USER 'repluser'@'从库网段' IDENTIFIED WITH mysql_native_password BY '强密码'; -- 8.0需指定插件,5.7可省略
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repluser'@'从库网段'; -- 仅授予复制必需权限
    FLUSH PRIVILEGES;

三、从库配置(核心:关联主库 + 启动复制)

  1. 修改配置文件 ,添加 / 修改:

    复制代码
    [mysqld]
    server-id = 2             # 唯一ID(≠主库)
    relay-log = relay-bin     # 开启中继日志(默认开启,显式配置更稳)
    read_only = 1             # 可选,普通用户只读(root不受限)

    重启从库:systemctl restart mysqld

  2. 全量同步主库数据(可选) :若主库已有数据,先通过mysqldump/xtrabackup将主库全量数据导入从库,保证数据基线一致;

  3. 配置主从关联

    复制代码
    STOP SLAVE; -- 若已有旧配置,先停止
    CHANGE MASTER TO
      MASTER_HOST='主库IP',
      MASTER_PORT=3306,
      MASTER_USER='repluser',
      MASTER_PASSWORD='复制密码',
      MASTER_LOG_FILE='主库binlog文件名', -- 主库show master status的File值
      MASTER_LOG_POS=主库binlog位置;     -- 主库show master status的Position值
    START SLAVE;

四、核心验证(确认复制生效)

  1. 从库执行show slave status\G,核心指标需满足:
    • Slave_IO_Running: Yes(IO 线程正常,能连接主库拉取 binlog);
    • Slave_SQL_Running: Yes(SQL 线程正常,能执行中继日志);
    • Slave_IO_State: Waiting for source to send event(IO 线程处于等待主库发送日志状态);
  2. 数据验证:主库创建库 / 表 / 插入数据,从库查询确认数据同步成功。
相关推荐
二二牧人1 小时前
qemu arm64 linux开发环境搭建
linux·运维·数据库
北龙云海2 小时前
从宕机到智变:2025数据中心进化启示录,数智运维如何定义未来
运维·ai·数据中心·智算·数智运维·数据中心规划
茁壮成长的露露2 小时前
导出导入工具mongoexport、mongoimport
数据库·mongodb
wm10432 小时前
大模型学习day01 python基础
学习
吉吉612 小时前
Docker拉取镜像解决办法
运维·docker·容器
馨谙2 小时前
Linux面试题----文件权限,chmod,chown,suid,sgid,粘滞位,umask
linux·运维·服务器
Hello_Embed2 小时前
RS485 双串口通信 + LCD 实时显示(DMA+IDLE 空闲中断版)
笔记·单片机·学习·操作系统·嵌入式·freertos
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-考试系统DDD(领域驱动设计)实现步骤详解
java·数据库·人工智能·spring boot
徐子元竟然被占了!!2 小时前
常用端口学习
运维·网络·学习