MySQL--组从复制的详解及功能演练

2.MySQL的组从复制

2.1 配置mastesr

[root@mysqlaa ~]# vim /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
log-bin=mysql-bin[root@mysqlaa ~]# /etc/init.d/mysqld restart
# 进入数据库配置用户权限
[root@mysql-node10 ~]# mysql -uroot -p123456# 生成专门用来做复制的用户,此用户是用于slave端做认证用
mysql> create user dhj@'%' identified by '123456';				
mysql> grant replication slave on *.* to 'dhj'@'%';				# 对这个用户进行授权
mysql> show master status;										# 查看master的状态
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      658 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
**image-20250801141359365**
[root@mysql-node10 ~]# cd /data/mysql/
[root@mysql-node10 mysql]# mysqlbinlog mysql-bin.000001	-vv			# 查看二进制日志

2.2 配置salve

[root@mysql-node2 ~]# vim /etc/my.cnf
[mysqld]
server-id=20
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password[root@mysql-node2 ~]# /etc/init.d/mysqld restart
[root@mysqlb ~]# mysql -uroot -p123456mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10',MASTER_USER='dhj',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=658;						# 这里要去master主机中去查看一遍mysql> start slave;mysql> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for source to send eventMaster_Host: 172.25.254.10Master_User: dhjMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 1606Relay_Log_File: mysqlb-relay-bin.000002Relay_Log_Pos: 326Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: Yes						# 一定要保证此参数为yesSlave_SQL_Running: Yes						# 一定要保证此参数为yes
image-20250801152150489
# 如果上述内容输入错误可以reset重新填入信息即可
mysql> RESET SLAVE ALL;
# 测试:# 在master主机里面进行建表
[root@mysqlaa ~]# mysql -uroot -p123456mysql> create database ceshi;mysql> create table ceshi.userlist (username varchar(20) not null, password varchar(50) not null);mysql> insert into ceshi.userlist value ('dhj','123');mysql> select * from ceshi.userlist;
+----------+----------+
| username | password |
+----------+----------+
| dhj      | 123      |
+----------+----------+# 在slave中查看数据是否有同步过来
[root@mysqlb ~]# mysql -uroot -p123456mysql> select * from ceshi.userlist;
+----------+----------+
| username | password |
+----------+----------+
| dhj      | 123      |
+----------+----------+
image-20250801152710614

image-20250801152852953

2.3 当有数据时添加slave2

#完成基础配置
[root@mysql-node3 ~]# vim /etc/my.cnf
[mysqld]
server-id=30
datadir=/data/mysql                                     # 指定数据目录
socket=/data/mysql/mysql.sock           				# 指定套接字
default_authentication_plugin=mysql_native_password[root@mysql-node3 ~]# /etc/init.d/mysqld restart
#从master节点备份数据
[root@mysql-node1 ~]# mysqldump -uroot -p123456 ceshi  > /mnt/ceshi.sql

[!NOTE]

生产环境中备份时需要锁表,保证备份前后的数据一致

mysql> FLUSH TABLES WITH READ LOCK;

备份后再解锁

mysql> UNLOCK TABLES;

mysqldump命令备份的数据文件,在还原时先DROP TABLE,需要合并数据时需要删除此语句

--
-- Table structure for table `userlist`
--DROP TABLE IF EXISTS `userlist`;		#需要合并数据时需要删除此语句
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
[root@mysqlaa ~]# scp /mnt/ceshi.sql root@172.25.254.30:/mnt
root@172.25.254.30's password:
ceshi.sql                           100% 1947     2.2MB/s   00:00# 利用master节点中备份出来的lee.sql在slave2中拉平数据
[root@mysql-node3 ~]# mysql -uroot -p123456 -e "create database ceshi;"
[root@mysql-node3 ~]# mysql -uroot -p123456 ceshi </mnt/ceshi.sql
[root@mysql-node3 ~]# mysql -uroot -p123456 -e "select * from ceshi.userlist;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
+----------+----------+
#配置slave2的slave功能#在master中查询日志pos
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     3656 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+[root@mysqlc ~]# mysql -uroot -p123456
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='dhj', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=3656;mysql> start slave;
mysql> SHOW SLAVE STATUS\G;
mysql> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for source to send eventMaster_Host: 172.25.254.10Master_User: dhjMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 3656Relay_Log_File: mysqlc-relay-bin.000002Relay_Log_Pos: 326Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: YesSlave_SQL_Running: Yes

测试:

[root@mysql-node1 ~]# mysql -uroot -p123456 -e  "INSERT INTO ceshi.userlist VALUES('user2','123');"[root@mysql-node2 mysql]# mysql -uroot -p123456 -e 'select * from ceshi.userlist;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
| user3    | 123      |
+----------+----------+[root@mysql-node3 ~]# mysql -uroot -p123456 -e 'select * from ceshi.userlist;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
| user3    | 123      |
+----------+----------+
# 为slave两台主机开启只读操作+超级只读操作(root在slave里面都不能写数据)
# 以下仅为20主机的,30的在此不做演示
[root@mysqlb ~]# more /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
read-only=1
super-read-only=1[root@mysqlb ~]# /etc/init.d/mysqld restart

image-20250801164929743

2.4 延迟复制

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

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

是日志已经保存在slave端了,那个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: 1Master_UUID: db2d8c92-4dc2-11ef-b6b0-000c299355eaMaster_Info_File: /data/mysql/master.infoSQL_Delay: 60			##延迟效果SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400

测试:

在master中写入数据后过了延迟时间才能被查询到

2.5 慢查询日志

  • 慢查询,顾名思义,执行很慢的查询

  • 当执行SQL超过long_query_time参数设定的时间阈值(默认10s)时,就被认为是慢查询,这个SQL语句就是需要优化的

  • 慢查询被记录在慢查询日志里

  • 慢查询日志默认是不开启的

  • 如果需要优化SQL语句,就可以开启这个功能,它可以让你很容易地知道哪些语句是需要优化的。

mysql> SHOW variables  like "slow%";
+---------------------+----------------------------------+
| Variable_name       | Value                            |
+---------------------+----------------------------------+
| slow_launch_time    | 2                                |
| slow_query_log      | OFF                              |
| slow_query_log_file | /data/mysql/mysql-node1-slow.log |
+---------------------+----------------------------------+
3 rows in set (0.00 sec)

开启慢查询日志

mysql> SET GLOBAL slow_query_log=ON;
Query OK, 0 rows affected (0.00 sec)mysql> SET long_query_time=4;
Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES like "long%";
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 4.000000 |
+-----------------+----------+
1 row in set (0.00 sec)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 |
+---------------------+----------------------------------+
3 rows in set (0.01 sec)[root@mysql-node1 ~]# cat  /data/mysql/mysql-node1-slow.log     #慢查询日志
/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:
Tcp port: 3306  Unix socket: /data/mysql/mysql.sock
Time                 Id Command    Argument

测试慢查询

mysql> select sleep (10);[root@mysql-node1 ~]# cat  /data/mysql/mysql-node1-slow.log
/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:
Tcp port: 3306  Unix socket: /data/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 2024-07-29T17:04:07.612704Z
# User@Host: root[root] @ localhost []  Id:     8
# Query_time: 10.000773  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
SET timestamp=1722272647;
select sleep (10);

2.6 mysql的并行复制

查看slave中的线程信息

image-20250730200425000

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

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

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

# 在slaves中设定
# 以下仅为20,30不做演示[root@mysql-node2 ~]# vim /etc/my.cnf
[mysqld]
server-id=20
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
read-only=1
super-read-only=1slave-parallel-type=LOGICAL_CLOCK			#基于组提交,
slave-parallel-workers=16					#开启线程数量
master_info_repository=TABLE				#master信息在表中记录,默认记录在/data/mysql//master.info
relay_log_info_repository=TABLE				#回放日志信息在表中记录,默认记录在/data/mysql/relay-log.info
relay_log_recovery=ON						#日志回放恢复功能开启[root@mysql-node2 ~]# /etc/init.d/mysql restart# 进行测试
mysql> show processlist;

image-20250801165536603

此时sql线程转化为协调线程,16个worker负责处理sql协调线程发送过来的处理请求

[!NOTE]

MySQL 组提交(Group commit)是一个性能优化特性,它允许在一个事务日志同步操作中将多个事务的日志记录一起写入。这样做可以减少磁盘I/O的次数,从而提高数据库的整体性能。

2.7 原理刨析

image-20250730195631273 image-20250801194633466

三个线程

实际上主从同步的原理就是基于 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端的binlog dump把二进制的更新发送到slave端的

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

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

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

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

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

2.8 架构缺陷

主从架构采用的是异步机制

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

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917283.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917283.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript将String转为base64 笔记250802

JavaScript将String转为base64 笔记250802 在 JavaScript 中将字符串转换为 Base64 编码有多种方法&#xff0c;每种方法都有其适用场景。下面我将全面介绍这些方法&#xff0c;包括处理 ASCII 字符、Unicode 字符以及性能优化方案。 基础方法&#xff1a;btoa() 基本用法&a…

Unity3D数学第四篇:射线与碰撞检测(交互基础篇)

Unity3D数学第一篇&#xff1a;向量与点、线、面&#xff08;基础篇&#xff09; Unity3D数学第二篇&#xff1a;旋转与欧拉角、四元数&#xff08;核心变换篇&#xff09; Unity3D数学第三篇&#xff1a;坐标系与变换矩阵&#xff08;空间转换篇&#xff09; Unity3D数学第…

数据处理和统计分析——09 数据分组

1 聚合 1.1 简介 在SQL中我们经常使用GROUP BY将某个字段&#xff0c;按不同的取值进行分组&#xff0c;在Pandas中也有groupby()函数&#xff1b;分组之后&#xff0c;每组都会有至少1条数据&#xff0c;将这些数据进一步处理返回单个值的过程就是聚合&#xff0c;比如分组之后…

【数据结构与算法】数据结构初阶:排序内容加餐(一)——快速排序:三路划分、自省排序

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人生格言&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为…

MySqL(加餐)

范式第一范式数据库表的每一列都是不可分割的原子数据项&#xff0c;而不能是集合&#xff0c;数组&#xff0c;对象等非原子数据。在关系型数据库的设计中&#xff0c;满足第一范式是对关系模式的基本要求。不满足第一范式的数据库就不能被称为关系数据库。第一范式实际上只要…

【redis】基于工业界技术分享的内容总结

Redis 实践指南与核心概念 一、Java 中常用的 Redis 使用场景与实践 缓存&#xff08;Caching&#xff09; 场景&#xff1a;热点数据、频繁访问的数据&#xff0c;如商品详情、用户信息。通过缓存减少数据库压力&#xff0c;提高系统响应速度。 工业界实践&#xff1a; 淘宝…

服务端之nestJS常用异常类及封装自定义响应模块

MENU前言常用异常类&#xff08;由nestjs/common提供&#xff09;示例自定义异常&#xff08;可选&#xff09;自定义响应模块前言 在NestJS中&#xff0c;nestjs/common提供了大量的内置异常类&#xff0c;主要用于在控制器、服务等层抛出特定的HTTP错误响应。 常用异常类&…

数据链路层、NAT、代理服务、内网穿透

目录 一. 以太网 以太网帧格式 二. MAC地址 三. MTU 四. ARP协议 五. NAT NAPT 六. 代理服务器 正向代理 反向代理 七. 内网穿透 八. 内网打洞 一. 以太网 • "以太网" 不是一种具体的网络, 而是一种技术标准; 既包含了数据链路层的内 容, 也包含了一些物理层…

Rust在CentOS 6上的移植

Rust已不支持Cent OS 6 rhel是Redhat 发布的Red Hat Enterprise Linux的简称&#xff0c;使用rhel源代码编译的CentOS&#xff0c;最新的版本是CentOS 7&#xff0c;于2024年停止支持。而更古老的CentOS 6&#xff0c;则在2020年就已经结束了。 而面对如此老旧的系统&#xf…

C++音视频开发:基础面试题

音视频领域技术门槛高&#xff0c;学习资料稀缺&#xff0c;体系化书籍和开发工具有限&#xff0c;新手入门困难。音视频开发涉及众多任务&#xff1a;音频&#xff08;采集、编解码、降噪等&#xff09;、视频&#xff08;采集、编解码、图像处理&#xff09;、实时传输&#…

C++刷题 - 7.27

贪心算法的详细逻辑这个问题的最优解可以用 贪心算法 在 O(N) 时间 内解决。它的核心思想是&#xff1a;每次操作尽可能覆盖最长的连续非零区间&#xff0c;并通过数学分析发现&#xff1a;最小操作次数等于所有“上升台阶”的高度差之和。1. 直观理解假设 steps [1, 2, 3, 2,…

音频3A处理简介之AGC(自动增益控制)

在音频通话和视频会议中&#xff0c;音频自动增益控制AGC模块的主要作用&#xff1a;• 稳定音频信号的输出电平。无论麦克风采集信号的强弱&#xff08;如用户离麦克风远近程度不同&#xff09;&#xff0c;尽可能保证音频采集模块的输出音量保持相对一致&#xff0c;不会偏大…

web前端打包apk包

我用的是HBuilder工具,可视化更便捷&#xff0c;目前我这操作的apk包是不需要上架的&#xff0c;所以跟实际需要上架的可能还有些出入 首先先新建个项目&#xff0c;选择5App模式 把目前需要打包的内容上传到服务器&#xff0c;我们以嵌套的形式进行打包&#xff0c;找到index.…

Ansible提权sudo后执行报错

1.问题 配置了sudo提权信息后&#xff0c;执行ansible-play报错&#xff0c;报错信息如下&#xff1a;2.原因 sudo没有执行**/bin/sh的权限&#xff0c;而ansible脚本中依赖/bin/sh**&#xff0c;所以报错了&#xff1a; 查看日志sudo tail -f /var/log/secure3.解决方式 修改*…

.NET报表控件ActiveReports发布v19.0——正式兼容 .NET 9

ActiveReports 是一款专注于 .NET 和 .NET Core 平台的报表控件。通过拖拽式报表设计器&#xff0c;可以快速地设计 Excel表格、Word文档、图表、数据过滤、数据钻取、精准套打等类型报表&#xff0c;全面满足 WinForm、ASP.NET、ASP.NET MVC、WPF 平台中各种报表的开发需要。同…

SCI论文选词炼句

标准句子不能啰嗦&#xff1b;词不能有问题&#xff0c;得是SCI中经常出现的&#xff0c;符合上下文的。SCI论文中常出现的摸棱两可的词单词涵义例子Architecture指 整体系统设计方案&#xff0c;如网络层次结构、模块组合、激活函数选择等深度学习模型架构Structure更泛泛&…

Qt deleteLater 延迟删除原理

deleteLater 调用 事件发送 void QObject::deleteLater() {QCoreApplication::postEvent(this, new QDeferredDeleteEvent()); }首先该对象继承QObject调用deleteLater&#xff0c; 内部会发送删除事件QCoreApplication::postEvent(this, new QDeferredDeleteEvent()) 到事件循…

TypeScript SDK 升级:通过 Upload Relay 赋能更多应用

自 3 月主网上线以来&#xff0c;Walrus 开发者社区持续展现出强劲的发展势头&#xff1a; 当前 Walrus 已存储超 758 TB 数据&#xff0c;为数百个项目提供支持。在 2025 年 6 月举办的 Sui Overflow 黑客松上&#xff0c;Walrus 成为最受欢迎的数据层。该赛事共收到 599 个项…

C#线程同步(二)锁

目录 1.lock 2.Monitor 3.锁的其它要注意的问题 3.1同步对象的选择 3.2什么时候该上锁 3.3锁和原子性 3.4嵌套锁 3.5 死锁 3.6 性能 4.Mutex 5.Semaphore 1.lock 让我们先看一段代码&#xff1a; class ThreadUnsafe {static int _val1 1, _val2 1;static void G…

鸿蒙智能居家养老系统构思(续二)—— 适老化烹饪中心详细构思

一、背景在“写给华为鸿蒙智家 —— 智能居家养老系统构思”一文中&#xff0c;结合对居家养老的理解及个人体验&#xff0c;提出了基于鸿蒙OS实现居家养老系统的粗略构思。其中包含“吃得好”。当老人到了不能随性外出活动、只能在家消耗时光时&#xff0c;除了一些看看电视、…