MySQL主从复制之原理&一主一从部署流程—2023.04

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: MySQL主从复制之原理&一主一从部署流程—2023.04

一、MySQL主从复制介绍


1、主从复制概念

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。

MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的 二进制日志 功能。就是一台或多台MySQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库)进行日志的复制,然后再解析日志并应用到自身,最终实现从库的数据和主库的数据保持一致。


2、为什么要做主从复制

  1. 在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
  2. 做数据的热备
  3. 架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。


3、主从复制原理

  • 原理
  1. master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
  2. slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件;
  3. 同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志(relay-log)中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。

e39aac7afbab418f8163b11415d462b3.png


也就是说:

从库会生成两个线程,一个I/O线程,一个SQL线程;

I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;

主库会生成一个log dump线程,用来给从库I/O线程传binlog;

SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;


具体步骤:

从库通过手工执行change master to 语句连接主库,提供了连接的用户一切条件(user 、password、port、ip),并且让从库知道,二进制日志的起点位置(file名 position 号); start slave

从库的IO线程和主库的dump线程建立连接。

从库根据change master to 语句提供的file名和position号,IO线程向主库发起binlog的请求。

主库dump线程根据从库的请求,将本地binlog以events的方式发给从库IO线程。

从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中

从库SQL线程应用relay-log,并且把应用过的记录到relay-log.info中,默认情况下,已经应用过的relay 会自动被清理purge


主从同步事件binlog模式有3种形式:statement、row、mixed。

statement: 会将对数据库操作的 sql 语句写入到 binlog 中。

row: 会将每一条数据的变化写入到 binlog 中。

mixed: statement 与 row 的混合。MySQL 决定什么时候写 statement 格式的,什么时候写 row 格式的 binlog。


注意:

①master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。

②slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。

③Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。

④Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)

⑤master和slave两节点间时间需同步


4、主从复制形式

  1. 一主多从,提高系统的读性能

c7fddca8ef78406e88fd16c60c308811.png

一主一从和一主多从是最常见的主从架构,实施起来简单并且有效,不仅可以实现HA,而且还能读写分离,进而提升集群的并发能力。

2、多主一从 (从5.7开始支持)

82e905e8d41547dd8b7590fe503d2f18.png

多主一从可以将多个mysql数据库备份到一台存储性能比较好的服务器上。

3、双主复制
双主复制,也就是互做主从复制,每个master(主)既是master,又是另外一台服务器的slave(从)。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。

4、级联复制

071d2a237d7b45e7a0b1b786ae50e9f8.png

级联复制模式下,部分slave的数据同步不连接主节点,而是连接从节点。因为如果主节点有太多的从节点,就会损耗一部分性能用于replication(复制),那么我们可以让3~5个从节点连接主节点,其它从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,并且对数据一致性没有负面影响。级联复制下从节点也要开启binary log(bin-log)功能。


5、主从复制主要用途

1、读写分离

在开发工作中,有时候会遇见某个sql 语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。

2、数据实时备份,当系统中某个节点发生故障时,可以方便的故障切换(主从切换)

提高数据安全-因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据;

3、高可用(HA)

1)因为数据库服务器中的数据都是相同的,当Master挂掉后,可以指定一台Slave充当Master继续保证服务的运行,因为数据是一致性的(如果当插入时Master就挂掉,可能不一致,因为同步也需要时间)当然这种配置不是简单的把一台Slave充当Master,毕竟还要考虑后续的Slave的数据同步到Master

2)在主服务器上执行写入和更新,在从服务器上向外提供读功能,达到读写分离的效果,也可以动态地调整从服务器的数量,从而调整整个数据库的性能。

3)在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能。

4、架构扩展

随着系统中业务访问量的增大,如果是单机部署数据库,就会导致I/O访问频率过高。有了主从复制,增加多个数据存储节点,将负载分布在多个从节点上,降低单机磁盘I/O访问的频率,提高单个机器的I/O性能。


二、MySQL一主一从搭建


1、准备工作

服务器 IP 要求
master 192.168.2.31 Docker、MySQL5.7
slave 192.168.2.32 Docker、MySQL5.7


首先在两台服务器上提前部署好docker以及MySQL5.7版本。

MySQL安装流程参考这篇文章:https://blog.csdn.net/weixin_64124795/article/details/129110551


2、MySQL主从复制部署流程

1. 关闭防火墙,两台主机都操作
systemctl stop firewalld  关闭防火墙
systemctl disable firewalld 关闭开机自启


2. 修改配置文件,两台主机都操作

mysql配置文件路径:/etc/my.cnf

增加如下内容:

# MySQL 服务的唯一编号,每个 MySQL 服务的 id 需唯一
server-id = 1
# 服务端口号,默认为 3306
port = 3306
# 是否对sql语句大小写敏感,默认值为0,1表示不敏感
lower_case_table_names=1    #1代表关闭大小写区别 0代表开启大小写
default_storage_engine=InnoDB   #存储引擎  lnnoDB
# 配置默认编码为utf8
character_set_server=utf8
init_connect='SET NAMES utf8'


最终配置文件内容:

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
# MySQL 服务的唯一编号,每个 MySQL 服务的 id 需唯一
server-id = 1
# 服务端口号,默认为 3306
port = 3306
# 是否对sql语句大小写敏感,默认值为0,1表示不敏感
lower_case_table_names=1    #1代表关闭大小写区别 0代表开启大小写
#存储引擎  lnnoDB
default_storage_engine=InnoDB   
# 配置默认编码为utf8
character_set_server=utf8
init_connect='SET NAMES utf8'


重启mysql使配置生效

systemctl restart mysqld


默认配置文件路径:

配置文件:/etc/my.cnf

日志文件:/var/log/mysqld.log

服务启动脚本:/usr/lib/systemd/system/mysqld.service

socket文件:/var/lib/mysql/mysql.sock


3. 修改主节点配置文件,主节点操作

vim /etc/my.cnf添加以下参数:

log-bin=mysql-bin #启动二进制日志系统
binlog-do-db=test #二进制需要同步的数据库名,如果需要同步多个库,例如要再同步westos库,再添加一行“binlog-do-db=westos”,以此类推
binlog-ignore-db=mysql #禁止同步 mysql 数据库

8eaf20207576417f9cab7eced1b24571.png

# 重启mysql
systemctl restart mysqld
  • 配置主服务器用户并清空日志
    进入MySQL
mysql -uroot -p


mysql> show privileges;
# 创建远程登录账户
## 注意这里的密码不能设置的太简单,否则会报错 ERROR 1819 (HY000): Unknown error 1819
mysql> grant replication client,replication slave on *.* to 'tongwz'@'192.168.2.%' identified by 'Tongwz123.';
mysql> reset master;
mysql> show binary logs;

99f0504e1d0944949651797370e3d9cd.png

4. 修改从节点配置文件,从节点操作

/etc/my.cnf中的server-id 改为2, 注意:server-id不可跟主服务器的一样

另外,加入下面一行命令,启用中继日志

#启用中继日志
relay-log=mysql-relay

582d658d57534a95b712f5ae7ea79961.png

# 重启mysql
systemctl restart mysqld

进入MySQL:

mysql -uroot -p


执行如下命令:

mysql> change master to master_host='192.168.2.31', master_user='tongwz', master_password='Tongwz123.', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=154;
说明:
# change master to master_host=‘主服务器ip’,
# master_user=‘刚在主服务器创建的用户名’,
# master_password=‘刚在主服务器创建的用户密码’, 
# master_port=3306, 
# master_log_file=‘刚查看主服务器下的File值’,
# master_log_pos=刚查看主服务器下的Position值,必须要一致


先查看slave状态:红框中显示是No,由于slave还没有开启,表示还没有加入主节点
mysql> show slave status \G;

50b4badf7d744cf0a1ce9d0751a41749.png

正式开启slave:
mysql> start slave;
再次查看状态:此时已经显示为Yes了
mysql> show slave status \G;

63830b998f4c47abb4bd301eba284007.png

注意:两个必须都显示为Yes才表示成功。如果还是显示No,就要重新执行show binary logs;命令查看master节点aster_log_pos值,再执行change master to master_host='192.168.2.31', master_user='tongwz', master_password='Tongwz123.', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=154;这段命令,然后start slave;

此时,slave已经配置好,进一步查看:

# 查看relay-log.info文件位置,进入查看
find / -name relay-log.info
cat /var/lib/mysql/relay-log.inf
# 查看master.info文件位置,进入查看
find / -name master.info
cat /var/lib/mysql/master.info

5051452400ed4493a193dd9ca72437f8.png

33209d52a637483b9dfba02f14a3b8d1.png

5. 测试

在master节点中数据库test里创建表test,插入数据;在slave节点查看数据是否同步。

因为前面配置文件中,写明了只同步test数据库。

master节点中创建:
mysql> use test;
mysql> create table test(id int(11));
mysql> insert into test values(1);
mysql> select * from test;


slave节点中查看:
mysql> use test;
mysql> show tables;
mysql> select * from test;

bd2e7a3ec27b44f5950376d2a2a09c52.png

可以看到在master节点上加入的数据,这就说明主从复制成功。


6. 特别说明
  1. 以上这种方式搭建的一主一从,主要实现读写分离,master节点上写入数据会自动同步到slave节点。如果反过来,在slave节点写入数据,是无法同步到master节点上的,反而还会中断主节点与从节点的连接。所以为了避免这个问题,一般只给slave节点只读的权限。


增加同步的数据库到slave
  1. 上面的操作我们只同步了test数据库,如果我们想要再同步一个数据库到slave节点,该怎么操作呢?

首先,我们要修改master节点的配置文件vim /etc/my.cnf,里面增加数据库test1
master节点操作:

vim /etc/my.cnf
binlog-do-db=test  #二进制需要同步的数据库名,如果需要同步多个库,例如要再同步westos库,再添加一行“binlog-do-db=westos”,以此类推
binlog-do-db=test1   # 增加这一行


然后重启

systemctl restart mysqld


然后,进入slave节点的mysql中,等待从节点同步主节点数据,待查看状态show slave status \G;后,两行都显示为Yes,表示已经连接成功;

其次,再master节点上的mysql中创建test1数据库,并往数据库内创建表,写入内容;

最后到slave节点查看是否同步即可。

注意:

必须先修改配置文件中的数据库名称,然后待slave与master连接后,再在master上创建test1数据库,顺序不能改变。

如果反过来,先在master节点上创建了test1数据库,然后修改配置文件、slave连接master,那么所创建的数据库就不会同步到slave。

所以,顺序很重要。

slave只同步连接master节点后,在master节点上执行的命令。


3、流程图

48bd0203d28d44f08f65c63985292124.png

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
7月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
4月前
|
存储 关系型数据库 MySQL
MySQL Docker 容器化部署全指南
MySQL是一款开源关系型数据库,广泛用于Web及企业应用。Docker容器化部署可解决环境不一致、依赖冲突问题,实现高效、隔离、轻量的MySQL服务运行,支持数据持久化与快速迁移,适用于开发、测试及生产环境。
754 4
|
11月前
|
自然语言处理 搜索推荐 关系型数据库
MySQL实现文档全文搜索,分词匹配多段落重排展示,知识库搜索原理分享
本文介绍了在文档管理系统中实现高效全文搜索的方案。为解决原有ES搜索引擎私有化部署复杂、运维成本高的问题,我们转而使用MySQL实现搜索功能。通过对用户输入预处理、数据库模糊匹配、结果分段与关键字标红等步骤,实现了精准且高效的搜索效果。目前方案适用于中小企业,未来将根据需求优化并可能重新引入专业搜索引擎以提升性能。
522 5
|
6月前
|
关系型数据库 MySQL 数据库
为什么 MySQL 不推荐用 Docker 部署?
本文探讨了MySQL是否适合容器化的问题,分析了Docker容器在数据安全、性能瓶颈、状态管理及资源隔离等方面的挑战,并指出目前主流分布式数据库如TDSQL和OceanBase仍倾向于部署在物理机或KVM上。
332 0
|
7月前
|
SQL 关系型数据库 MySQL
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
|
9月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
473 41
|
9月前
|
开发框架 Java 关系型数据库
在Linux系统中安装JDK、Tomcat、MySQL以及部署J2EE后端接口
校验时,浏览器输入:http://[your_server_IP]:8080/myapp。如果你看到你的应用的欢迎页面,恭喜你,一切都已就绪。
600 17
|
9月前
|
Java 关系型数据库 MySQL
在Linux操作系统上设置JDK、Tomcat、MySQL以及J2EE后端接口的部署步骤
让我们总结一下,给你的Linux操作系统装备上最强的军队,需要先后装备好JDK的弓箭,布置好Tomcat的阵地,再把MySQL的物资原料准备好,最后部署好J2EE攻城车,那就准备好进军吧,你的Linux军团,无人可挡!
217 18
|
9月前
|
开发框架 关系型数据库 Java
Linux操作系统中JDK、Tomcat、MySQL的完整安装流程以及J2EE后端接口的部署
然后Tomcat会自动将其解压成一个名为ROOT的文件夹。重启Tomcat,让新“植物”适应新环境。访问http://localhost:8080/yourproject看到你的项目页面,说明“植物”种植成功。
280 10
|
11月前
|
SQL 算法 搜索推荐
mysql 之order by工作流程
本文深入解析了MySQL中`ORDER BY`的排序机制,通过具体示例展示了排序过程及性能优化方法。文章首先分析了基于内存和磁盘的排序方式,包括`sort_buffer_size`的影响以及临时文件的使用场景。接着介绍了`rowid`排序算法,该算法通过减少参与排序的数据量来提升性能,并对比了其与传统排序的区别。此外,还探讨了随机查询`ORDER BY RAND()`的执行流程及其优化策略。最后提到了MySQL 5.6引入的优先队列排序算法,适用于仅需部分有序结果的场景。文章结合`optimizer_trace`工具详细说明了各配置参数对排序行为的影响,为优化查询提供了实用指导。
169 1
mysql 之order by工作流程

推荐镜像

更多