数据库的主从复制原理(超级详细)

概念

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表

主要用途

1. 读写分离

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

2. 数据实时备份

当系统中某个节点发生故障时,可以方便的故障切换

3. 高可用HA和架构扩展

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

主从形式

1. 一主一从

在这里插入图片描述
一主多从,提高系统的读性能。一主一从和一主多从是最常见的主从架构,实施起来简单并且有效,不仅可以实现HA,而且还能读写分离,进而提升集群的并发能力。

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

在这里插入图片描述
多主一从可以将多个mysql数据库备份到一台存储性能比较好的服务器上。

3. 双主复制

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

4. 级联复制

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

主从复制原理

MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:
在这里插入图片描述

1. 主节点 binary log dump 线程

当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。

2.从节点I/O线程

当从节点上执行start slave命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。

3.从节点SQL线程

SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。

要实施复制,首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。

因为整个复制过程实际上就是Slave 从Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。如下图所示:
在这里插入图片描述

复制的基本过程如下:

  • 从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
  • 主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”
  • Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在祝节点上实际执行过的操作,并在本数据库中执行。

主从复制模式

MySQL 主从复制默认是异步的模式。MySQL增删改操作会全部记录在binary log中,当slave节点连接master时,会主动从master处获取最新的bin log文件。并把bin log中的sql relay。

1. 异步模式

异步模式如下图所示,这种模式下,主节点不会主动push bin log到从节点,这样有可能导致failover的情况下,也许从节点没有即时地将最新的bin log同步到本地
在这里插入图片描述

全同步模式

全同步模式是指主节点和从节点全部执行了commit并确认才会向客户端返回成功

总结

Mysql 主从复制是mysql 高可用,高性能的基础,有了这个基础,mysql 的部署会变得简单、灵活并且具有多样性,从而可以根据不同的业务场景做出灵活的调整。

<think>我们首先回答用户的问题:MySQL主从数据库原理和实现 ### MySQL主从复制原理 MySQL主从复制(Replication)允许数据从一个MySQL数据库服务器(主服务器)复制到一个或多个MySQL数据库服务器(从服务器)。复制是异步的,从服务器不需要一直连接主服务器来接收更新。 **复制原理**: 1. **主服务器(Master)**:当主服务器上的数据发生改变(增删改)时,这些改变会写入二进制日志(Binary Log)中。 2. **从服务器(Slave)**:从服务器有两个线程: - **I/O线程**:连接主服务器,请求二进制日志中的事件,并将这些事件写入本地的中继日志(Relay Log)。 - **SQL线程**:读取中继日志中的事件,并在从服务器上执行这些事件,从而重放主服务器上的操作。 **步骤详细说明**: 1. 主服务器将更改记录到二进制日志(binlog)中。 2. 从服务器的I/O线程向主服务器请求binlog的内容,并将获取的binlog事件写入从服务器的中继日志。 3. 从服务器的SQL线程读取中继日志中的事件,并在从服务器上执行这些SQL事件。 **注意**:主从复制默认是异步的,这意味着主服务器上的更改不会立即在从服务器上反映。如果需要强一致性,可以考虑半同步复制或组复制。 ### 实现步骤 下面将展示如何配置MySQL主从复制(假设使用MySQL 8.0版本)。 #### 环境准备 - 两台MySQL服务器(可以是虚拟机、容器或物理机),分别作为主服务器(Master)和从服务器(Slave)。 - 确保两台服务器网络互通,并且MySQL端口(默认3306)开放。 #### 主服务器配置(Master) 1. **修改主服务器的配置文件(my.cnf或my.ini)**: ```ini [mysqld] server-id=1 # 服务器唯一ID,必须唯一 log-bin=mysql-bin # 启用二进制日志 binlog_format=ROW # 推荐使用ROW格式 ``` 2. **重启MySQL服务**: ```bash sudo systemctl restart mysql ``` 3. **创建复制用户**: 登录主服务器MySQL,创建一个用于复制的用户,并授予复制权限。 ```sql CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES; ``` 4. **查看主服务器状态**: 记录File和Position的值,从服务器连接时需要。 ```sql SHOW MASTER STATUS; ``` 输出类似: ``` +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 155 | | | | +------------------+----------+--------------+------------------+-------------------+ ``` #### 从服务器配置(Slave) 1. **修改从服务器的配置文件**: ```ini [mysqld] server-id=2 # 服务器唯一ID,必须唯一且不同于主服务器 relay-log=mysql-relay-bin log_bin=mysql-bin read_only=ON # 可选,设置从服务器为只读(超级用户除外) ``` 2. **重启MySQL服务**: ```bash sudo systemctl restart mysql ``` 3. **配置从服务器连接主服务器**: 登录从服务器MySQL,执行: ```sql CHANGE MASTER TO MASTER_HOST='master_ip', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', -- 主服务器上SHOW MASTER STATUS得到的File MASTER_LOG_POS=155; -- 主服务器上SHOW MASTER STATUS得到的Position ``` 4. **启动复制**: ```sql START SLAVE; ``` 5. **检查从服务器状态**: ```sql SHOW SLAVE STATUS\G ``` 查看`Slave_IO_Running`和`Slave_SQL_Running`的值,如果都是`Yes`,则表示复制正常运行。 ### 代码说明 上述步骤中,我们主要使用了SQL语句和配置文件修改。没有复杂的代码,但需要严格按照步骤操作。 ### 注意事项 - 确保主从服务器的MySQL版本兼容(最好相同或从服务器版本高于主服务器)。 - 主从服务器时间同步。 - 主从服务器之间的网络延迟和带宽会影响复制延迟。 - 如果主服务器已有数据,需要先将主服务器数据导出并导入到从服务器,然后再配置复制(使用`mysqldump`或`xtrabackup`等工具)。 ### 主从复制延迟问题 异步复制不可避免会有延迟。可以通过以下方法减少延迟: - 优化主服务器上的SQL,减少大事务。 - 使用更好的硬件(如SSD)。 - 调整MySQL参数(如`sync_binlog`,`innodb_flush_log_at_trx_commit`等)。 - 考虑半同步复制(Semi-synchronous Replication)或并行复制(Multi-threaded Slave)。 ### 相关问题 根据我们的回答,提出以下相关问题: </think>### MySQL主从数据库原理和实现 #### 原理 MySQL主从复制基于**二进制日志(Binlog)** 实现,核心流程如下: 1. **主库(Master)**:记录所有数据变更操作到二进制日志 2. **从库(Slave)**: - I/O线程:读取主库的二进制日志并写入本地中继日志(Relay Log) - SQL线程:执行中继日志中的SQL语句,实现数据同步 3. **异步机制**:默认异步复制,主库无需等待从库响应 #### 实现步骤(MySQL 8.0) ##### 1. 主库配置(Master) 修改配置文件`/etc/my.cnf`: ```ini [mysqld] server-id = 1 # 唯一服务器ID log-bin = mysql-bin # 启用二进制日志 binlog_format = ROW # 推荐使用ROW格式 binlog_do_db = example_db # 需要复制的数据库(可选) ``` 重启MySQL服务: ```bash sudo systemctl restart mysqld ``` 创建复制账号: ```sql CREATE USER 'repl_user'@'%' IDENTIFIED BY 'SecurePass123!'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES; ``` 查看主库状态: ```sql SHOW MASTER STATUS; ``` 记录输出的`File`(如mysql-bin.000001)和`Position`(如157) ##### 2. 从库配置(Slave) 修改配置文件`/etc/my.cnf`: ```ini [mysqld] server-id = 2 # 区别于主库的ID relay-log = mysql-relay-bin # 中继日志 read_only = ON # 设为只读(防止误操作) ``` 重启MySQL服务: ```bash sudo systemctl restart mysqld ``` 配置主从连接: ```sql CHANGE MASTER TO MASTER_HOST='192.168.1.100', # 主库IP MASTER_USER='repl_user', MASTER_PASSWORD='SecurePass123!', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=157; ``` 启动复制: ```sql START SLAVE; ``` ##### 3. 验证复制状态 ```sql SHOW SLAVE STATUS\G ``` 关键指标检查: ```markdown Slave_IO_Running: Yes # I/O线程状态 Slave_SQL_Running: Yes # SQL线程状态 Seconds_Behind_Master: 0 # 复制延迟(秒) ``` #### 故障排查命令 ```sql -- 主库查看连接信息 SHOW PROCESSLIST; -- 从库暂停/重置复制 STOP SLAVE; RESET SLAVE ALL; -- 跳过错误(谨慎使用) SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; ``` #### 关键注意事项 1. **数据一致性**:首次同步需手动导出主库数据(`mysqldump --master-data`) 2. **复制模式**: - `STATEMENT`:复制SQL语句(效率高,但可能不安全) - `ROW`(推荐):复制行变更(安全,日志较大) - `MIXED`:混合模式 3. **延迟优化**: - 开启并行复制:`slave_parallel_workers=4` - 使用GTID复制(简化故障转移) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haixiangwang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值