MySQL集群搭建(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL集群搭建

修改从库配置

vim /etc/mysql/mysql.conf.d/mysqld.cnf
gtid_mode=on
enforce_gtid_consistency=on
#重启服务
systemctl restart mysql
#关闭同步
stop slave;
#配置同步信息 使用MASTER_AUTO_POSITION自动获取同步信息
CHANGE MASTER TO
MASTER_HOST='192.168.1.13',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='1qaz@WSX0okm(IJN',
MASTER_AUTO_POSITION=1;
#开启同步
start slave;
#查看状态
show slave status\G

查看主库状态

mysql> show master status;
+-------------------+----------+--------------+----------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB     | Executed_Gtid_Set |
+-------------------+----------+--------------+----------------------+-------------------+
| master-bin.000004 |      154 | demo         | ignore_db,ignore_db2 |                   |
+-------------------+----------+--------------+----------------------+-------------------+

咦,咋还是没有勒?

别急,因为该同步方式是基于事务id的,我们插入一条数据试试。

insert into demo_table values (3);

查看状态

mysql> show master status;
+-------------------+----------+--------------+----------------------+------------------------------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB     | Executed_Gtid_Set                        |
+-------------------+----------+--------------+----------------------+------------------------------------------+
| master-bin.000004 |      676 | demo         | ignore_db,ignore_db2 | 7fb11262-7654-11eb-9930-0242c0296f15:1-2 |
+-------------------+----------+--------------+----------------------+------------------------------------------+
1 row in set (0.00 sec)

发现已生效!

加入新节点

安装MySQL并修改配置

  • vim /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id=3
relay-log-index=slave-relay-bin.index
relay-log=slave-relay-bin
log-bin=mysql-bin
log-slave-updates=1
gtid_mode=on
enforce_gtid_consistency=on
read_only=1
  • 重启MySQL
systemctl restart mysql

配置主从

#登陆MySQL
mysql -uroot -p
#配置主从,由于我们使用gtid同步,所以不再需要查看master节点状态
CHANGE MASTER TO
MASTER_HOST='192.168.1.13',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='1qaz@WSX0okm(IJN',
MASTER_AUTO_POSITION=1;
#开启同步
start slave;
#查看状态
show slave status\G

问题解决

查看状态会发现以下错误

Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. Replicate the missing transactions from elsewhere, or provision a new slave from backup. Consider increasing the master's binary log expiration period. The GTID set sent by the slave is '', and the missing transactions are '7fb11262-7654-11eb-9930-0242c0296f15:1-2'.'

看报错信息是因为我们清除了主库上的二进制文件,但我好像啥也没干

  • 解决办法
    在主库上执行以下命令,查询gtid_purged,记录下该值
show global variables like '%gtid%'\G
*************************** 1. row ***************************
Variable_name: binlog_gtid_simple_recovery
        Value: ON
*************************** 2. row ***************************
Variable_name: enforce_gtid_consistency
        Value: ON
*************************** 3. row ***************************
Variable_name: gtid_executed
        Value: 7fb11262-7654-11eb-9930-0242c0296f15:1-2
*************************** 4. row ***************************
Variable_name: gtid_executed_compression_period
        Value: 1000
*************************** 5. row ***************************
Variable_name: gtid_mode
        Value: ON
*************************** 6. row ***************************
Variable_name: gtid_owned
        Value: 
*************************** 7. row ***************************
Variable_name: gtid_purged
        Value: 7fb11262-7654-11eb-9930-0242c0296f15:1-2
*************************** 8. row ***************************
Variable_name: session_track_gtids
        Value: OFF
8 rows in set (0.00 sec)
  • 在从库上同样执行该命令,记录gtid_executed
show global variables like '%gtid%'\G
*************************** 1. row ***************************
Variable_name: binlog_gtid_simple_recovery
        Value: ON
*************************** 2. row ***************************
Variable_name: enforce_gtid_consistency
        Value: ON
*************************** 3. row ***************************
Variable_name: gtid_executed
        Value: 7fb11262-7654-11eb-9930-0242c0296f15:1-2
*************************** 4. row ***************************
Variable_name: gtid_executed_compression_period
        Value: 1000
*************************** 5. row ***************************
Variable_name: gtid_mode
        Value: ON
*************************** 6. row ***************************
Variable_name: gtid_owned
        Value: 
*************************** 7. row ***************************
Variable_name: gtid_purged
        Value: 7fb11262-7654-11eb-9930-0242c0296f15:1-2
*************************** 8. row ***************************
Variable_name: session_track_gtids
        Value: OFF
8 rows in set (0.00 sec)

咱这没有,就算了

  • 重置从节点
stop slave;
reset slave;
#此时会将gtid_executed置空,因为我们这里本来就是空,如果有一定要置空,不然执行下面的命令将报错
reset master;
  • 设置清除的事务id
set @@global.gtid_purged='7fb11262-7654-11eb-9930-0242c0296f15:1-2';
#再次查看
show global variables like '%gtid%'\G
#此时会发现gtid_purged多了我们加的事务id
*************************** 1. row ***************************
Variable_name: binlog_gtid_simple_recovery
        Value: ON
*************************** 2. row ***************************
Variable_name: enforce_gtid_consistency
        Value: ON
*************************** 3. row ***************************
Variable_name: gtid_executed
        Value: 
*************************** 4. row ***************************
Variable_name: gtid_executed_compression_period
        Value: 1000
*************************** 5. row ***************************
Variable_name: gtid_mode
        Value: ON
*************************** 6. row ***************************
Variable_name: gtid_owned
        Value: 
*************************** 7. row ***************************
Variable_name: gtid_purged
        Value: 
*************************** 8. row ***************************
Variable_name: session_track_gtids
        Value: OFF
8 rows in set (0.00 sec)
  • 重新开启同步
CHANGE MASTER TO
MASTER_HOST='192.168.1.13',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='1qaz@WSX0okm(IJN',
MASTER_AUTO_POSITION=1;
#开启同步
start slave;
#查看状态
show slave status\G


复制机制

以上我们已经搭建了1主2从的集群,但是仍然会有一个隐患,那就是我们常说的数据丢失问题

这是因为MySQL主从集群默认采用的是一种异步复制的机制。主服务在执行用户提交的事务后,写入binlog日志,然后就给客户端返回一个成功的响应了。而binlog会由一个dump线程异步发送给从服务。

由于这个发送binlog的过程是异步的。主服务在向客户端反馈执行结果时,是不知道binlog是否同步成功了的。这时候如果主服务宕机了,而从服务还没有备份到新执行的binlog,那就有可能会丢数据。

这时,半同步复制机制就要登场啦

半同步复制

半同步复制机制是一种介于异步复制和全同步复制之前的机制。主库在执行完客户端提交的事务后,并不是立即返回客户端响应,而是等待至少一个从库接收并写到relay log中,才会返回给客户端。MySQL在等待确认时,默认会等10秒,如果超过10秒没有收到ack,就会降级成为异步复制。

优点:相比异步复制,能够有效的提高数据的安全性。

缺点:会造成一定程度的延迟,这个延迟时间最少是一个TCP/IP请求往返的时间。整个服务的性能是会有所下降的。而当从服务出现问题时,主服务需要等待的时间就会更长,要等到从服务的服务恢复或者请求超时才能给用户响应。

配置半同步

  • 安装扩展模块
    查看扩展模块文件,一般是在/usr/lib/mysql/plugin目录下
ls /usr/lib/mysql/plugin
adt_null.so     connection_control.so  keyring_file.so  locking_service.so  mysql_no_login.so  semisync_master.so  validate_password.so
auth_socket.so  innodb_engine.so       libmemcached.so  mypluglib.so        rewriter.so        semisync_slave.so   version_token.so

会看到有两个扩展模块semisync_master.sosemisync_slave.so

  • 登陆主节点安装semisync_master.so
-- 安装扩展模块
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.17 sec)
mysql> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| 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 |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)
# 打开半同步
mysql> set global rpl_semi_sync_master_enabled=ON;
Query OK, 0 rows affected (0.00 sec)

rpl_semi_sync_master_enabled: 开启半同步

rpl_semi_sync_master_timeout:应答时间,单位毫秒,这里是10s

rpl_semi_sync_master_trace_level: 输出监控信息的级别

rpl_semi_sync_master_wait_for_slave_count: 等待的从库数量

rpl_semi_sync_master_wait_no_slave: 开启后从库同步跟上主库时,自动切换到同步模式

rpl_semi_sync_master_wait_point: 同步方式

AFTER_SYNC:默认方式,这种方式下,主库把日志写入binlog,并且复制给从库,然后开始等待从库的响应。从库返回成功后,主库再提交事务,接着给客户端返回一个成功响应。

AFTER_COMMIT:在主库写入binlog后,发送binlog复制到从库,主库就提交自己的本地事务,再等待从库返回给自己一个成功响应,然后主库再给客户端返回响应,由于主库并未等待从库同步成功就已经提交了事务,所以会造成其他会员能在主库上看到数据,在从库上却看不到数据的情况(数据不一致)。

  • 登陆从库安装扩展模块semisync_slave.so
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.02 sec)
mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.02 sec)
mysql> set global rpl_semi_sync_slave_enabled = on;
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)
-- 重新启动
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
  • 查看同步状态
    登陆主节点查看
SHOW 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             | 2     | 等待次数
| Rpl_semi_sync_master_no_times              | 0     | 关闭半同步复制的次数
| Rpl_semi_sync_master_no_tx                 | 0     | 没有成功接收slave提交的次数
| Rpl_semi_sync_master_status                | ON    | 异步模式还是半同步模式,ON为半同步
| Rpl_semi_sync_master_timefunc_failures     | 0     | 调用时间函数失败的次数
| Rpl_semi_sync_master_tx_avg_wait_time      | 381   | 事务的平均传输时间
| Rpl_semi_sync_master_tx_wait_time          | 381   | 事务的总共传输时间
| Rpl_semi_sync_master_tx_waits              | 1     | 事物等待次数
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     | 后来的先到了,而先来的还没有到的次数
| Rpl_semi_sync_master_wait_sessions         | 0     | 有多少个session因为slave的回复而造成等待
| Rpl_semi_sync_master_yes_tx                | 1     | 成功接受到slave事务回复的次数
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

数据延迟问题

在我们搭建的这个主从集群中,有一个比较隐藏的问题,就是这样的主从复制之间会有延迟。这在做了读写分离后,会更容易体现出来。即数据往主服务写,而读数据在从服务读。这时候这个主从复制延迟就有可能造成刚插入了数据但是查不到。

出现这个问题的根本在于:面向业务的主服务数据都是多线程并发写入的,而从服务是单个线程慢慢拉取binlog,这中间就会有个效率差。所以解决这个问题的关键是要让从服务也用多线程并行复制binlog数据。

登陆从节点修改配置

#停止同步
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql>  show global variables like 'slave_parallel_workers%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| slave_parallel_workers | 0     |
+------------------------+-------+
1 row in set (0.00 sec)
mysql> set global slave_parallel_workers = 4;
mysql> show global variables like 'slave_parallel_type%';
-- 默认是基于数据库的同步,即不同db下的操作可以在从库并行回放
+---------------------+----------+
| Variable_name       | Value    |
+---------------------+----------+
| slave_parallel_type | DATABASE |
+---------------------+----------+
1 row in set (0.00 sec)
-- LOGICAL_CLOCK方式,在主库对一个db或一张表并发执行的事务到slave端也可以并行回放
mysql> set global slave_parallel_type = LOGICAL_CLOCK;
mysql> start slave;
mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  8 | root        | localhost | demo | Query   |    0 | starting                                               | show processlist |
| 11 | system user |           | NULL | Connect |    7 | Waiting for master to send event                       | NULL             |
| 12 | system user |           | NULL | Connect |    7 | Slave has read all relay log; waiting for more updates | NULL             |
| 13 | system user |           | NULL | Connect |    7 | Waiting for an event from Coordinator                  | NULL             |
| 14 | system user |           | NULL | Connect |    7 | Waiting for an event from Coordinator                  | NULL             |
| 15 | system user |           | NULL | Connect |    7 | Waiting for an event from Coordinator                  | NULL             |
| 16 | system user |           | NULL | Connect |    7 | Waiting for an event from Coordinator                  | NULL             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+

可以看到现在已经有4个同步线程了

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
50 3
|
1月前
|
消息中间件 分布式计算 关系型数据库
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
47 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
87 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
40 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
48 0
|
1月前
|
SQL 关系型数据库 MySQL
mysql集群方案
mysql集群方案
42 0
|
3月前
|
负载均衡 算法 关系型数据库
MySQL集群如何实现负载均衡?
【8月更文挑战第16天】MySQL集群如何实现负载均衡?
208 6
|
3月前
|
存储 负载均衡 关系型数据库
MySQL集群
【8月更文挑战第16天】MySQL集群
50 5
|
3月前
|
SQL 负载均衡 关系型数据库
*配置MySQL集群
【8月更文挑战第16天】*配置MySQL集群
67 2
|
3月前
|
SQL 关系型数据库 MySQL
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
111 1
下一篇
无影云桌面