前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL 主从复制原理与问题

MySQL 主从复制原理与问题

作者头像
恋喵大鲤鱼
发布2024-05-24 14:42:35
640
发布2024-05-24 14:42:35
举报
文章被收录于专栏:C/C++基础C/C++基础

1.目的

MySQL 主从复制(Master-Slave Replication)是一种常见的数据库复制技术,它在数据库管理中发挥着重要的作用,有以下几个主要用途:

  • 高可用:主从复制通过在多个服务器之间复制数据,提供了数据冗余和高可用。如果主数据库发生故障,从数据库可以接管,确保系统继续运行。
  • 高性能:主从复制支持读写分离,即读操作可以路由到从服务器,而写操作仍然由主服务器处理。这有助于提高读操作的性能,减轻主服务器的负载。
  • 备份容灾:从服务器可以用于数据库备份目的。备份可以在不影响主服务器性能的情况下进行,而且备份可以是实时的,以确保数据安全。

MySQL 主从复制提供了高可用性、高性能、备份灾难等关键功能,使其成为许多企业和组织在数据库管理中的重要工具。有了主从复制,MySQL 的部署会变得简单、灵活并且具有多样性,从而可以根据不同的业务场景做出灵活调整。

2.主从架构

  • 一主一从
  • 一主多从

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

  • 多主一从

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

  • 双主复制

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

  • 级联复制

级联复制模式下,部分 slave 的数据同步不连接主节点,而是连接从节点。

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

级联复制解决了一主多从场景下多个从库复制对主库的压力,带来的弊端就是数据同步延迟比较大。

3.主从复制原理

要实施主从复制,必须打开 Master 端的 Binlog 功能,否则无法实现。

整个复制过程实际上就是 Slave 从 Master 获取 binlog 后,再顺序地执行(重放)日志记录的各种操作。

主从复制过程如下:

  1. master 将变更记录到二进制日志(binary log)。
  2. slave 通过 I/O 线程与 maste 建立长连接,master 为 slave 创建 log dump 线程,将 binlog 发送给 slave。
  3. 后续当 binlog 有变动时,log dump 线程会将变动通过 I/O 线程推给 slave。
  4. slave I/O 线程将 binlog 写入它的中继日志(relay log)。
  5. slave SQL 线程解析中继日志(relay log),将变更应用到从数据库。

主从复制涉及三个线程:

  • 主节点 log dump 线程

当从节点连接主节点时,主节点会为其创建一个 log dump 线程,用于发送和读取 Binlog 的内容。在读取 Binlog 中的操作时,dump 线程会对主节点上的 Binlog 加锁;当读取完成发送给从节点之前,锁会被释放。主节点会为每一个从节点创建一个 dump 线程。

  • 从节点 I/O 线程

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

  • 从节点 SQL 线程

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

对于每一个主从连接,都需要这三个线程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个 log dump 线程,而每个从节点都有自己的 I/O 线程和 SQL 线程。

从节点将从主库拉取更新和执行分成独立的两个任务,使用两个线程来完成,这样在执行数据同步任务的时候,不会降低读操作的性能。比如,如果从节点 SQL 线程没有运行,此时 I/O 线程可以很快从主节点获取更新。如果在 SQL 线程执行之前从节点服务停止,至少 I/O 线程已经从主节点拉取到了最新的变更并且保存在本地 relay log 中,当服务再次起来之后就可以完成数据的同步。

4.binlog 三种格式

STATEMENT

STATEMENT 格式 Binlog 记录的是 SQL 语句,而不是行数据。

优点:

  • Binlog 文件相对较小。当更新或删除影响许多行时,这将大大减少日志文件所需的存储空间。这也意味着从备份中获取和恢复可以更快地完成。
  • 日志文件包含所有变更语句,因此它们可用于审计数据库。

缺点:

  • 不够精确,因为某些操作可能无法精确还原。比如使用随机函数或非确定性存储过程。
  • 某些 SQL 在恢复时会,需要更多的行级锁,影响恢复效率。
代码语言:javascript
复制
INSERT ... SELECT
UPDATE ... WHERE 没有命中索引导致锁表

ROW

在 ROW 模式下,Binlog 记录的是实际行数据的更改。具体来说,它会记录哪些行被插入、更新或删除,以及这些行的新值。

优点:

  • 复制数据非常精确,不会出现非确定函数或存储过程、存储函数、触发器的调用导致数据不一致。
  • 某些类型的语句,恢复时需要更少的行锁,从而实现更高的并发性。
代码语言:javascript
复制
INSERT ... SELECT
INSERT statements with AUTO_INCREMENT
UPDATE or DELETE statements with WHERE clauses that do not use keys or do not change most of the examined rows.

缺点:

  • 但生成的 Binlog 文件通常较大,比如 UPDATE 或 DELETE 操作。
  • 在某些情况下可能会影响主库的性能,尤其是在大量更新操作时。

MIXED

STATEMENT 和 ROW 格式各有优缺点,MIXED 格式结合了二者的优点,在保证「数据完整性」的情况下提供最佳的「复制性能」。

MIXED 格式会根据具体情况来选择使用 ROW 记录或 STATEMENT 记录。这意味着对于某些更改,它将记录每一行数据的变化;而对于其他更改,它将记录执行的 SQL 语句。

这种模式在保持精确的同时,可以减小 Binlog 文件的大小。

从 MySQL 5.1 版本开始,MIXED 成为了默认的 binlog 格式,以兼顾 STATEMENT 和 ROW 两种格式的优点。

5.主从复制方式

5.1 异步复制

MySQL 主从复制默认是异步复制。

主数据库执行写操作后,并将变更写入 binlog,不等待从数据库应用这些变更,而是立即向客户端返回结果。

后续 master 通过 log dump 线程将 binlog 并发送给 slave。slave 把 binlog 存储到本地的 relay log 中,然后执行 relay log 的更新内容。

这个过程是异步的,所以称为异步复制。

这样就会有一个问题,主节点崩溃,此时主节点上已经提交的事务可能并没有传到从节点上。如果此时强行将从提升为主,可能导致新主节点上的数据不完整。

5.2 全同步复制

当主库执行完一个事务,然后所有的从都复制了该事务的 binlog 并写到 relay log,主库才返回成功信息给客户端。

因为需要等待所有从库执行完该事务才能返回成功,所以全同步复制的性能必然会受到严重的影响。

5.3 半同步复制

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回客户端,而是等待至少一个从库接收到 binlog 并写到 relay log 中才返回成功信息给客户端,保证主库的 binlog 至少传输到了一个从节点上。

相对于异步与同步复制,半同步复制是对性能与数据一致性的权衡,保证主从最终一致。

半同步复制提高了数据的安全性,一定程度上保证了数据能成功备份到从库,同时它也造成了一定程度的延迟,但是比全同步模式延迟要低,这个延迟最少是一个 TCP/IP 往返的时间。所以,半同步复制最好在低延时的网络中使用。

半同步模式不是 MySQL 内置的,从 MySQL 5.5 开始集成,需要 master 和 slave 安装插件开启半同步模式。

6.主从复制问题

数据丢失

当主库宕机后,数据可能丢失。

解决方法:使用半同步复制方式,可以解决数据丢失的问题。

同步延迟

主从延迟来自两个方面:从库进行 binlog 复制,从库日志回放。

从库复制 binlog 这个主要影响是网络带宽和网络稳定性,只能提高带宽来解决,没有什么更好的方式,所以这里更多讨论从库回放日志阶段导致的主从延迟。

从库一般是单线程重放 relay log,所以如果主库写并发较大,可能导致从库单线程重放 SQL 压力较大,主从复制延迟较高。

所以优化思路就有2个,降低主库写并发和多线程重放 SQL,提高重放效率。

(1)水平分库(降低主库写并发)

水平分库后单个分库的数据量降低,单个分库的写并发降低,从而降低从库重放 SQL 的排队时延,因而降低延迟。

(2)从库并行复制

升级至 MySQL 5.7 版本使用并行复制,官方称为 Enhanced Multi-threaded Slaves,即多线程重放 SQL,提高重放效率。

读写分离问题

主从同步有延迟,这个延迟期间读从库,会读到不一致的数据。

方法一:忽略。

大觉部分业务场景对主从同步延迟不敏感,如果业务可以接受,直接忽略。

方法二:放弃读写分离,强制读主。

读和写都落到主库上,在业务层面采用缓存来提升系统读性能。

方法三:选择性读主。

可以利用一个缓存 key 标记那些不容许主从不一致,也就是必须读主的数据,发生了更新,且设置缓存 key 的超时时间,超时时间设置为“主从同步时延”。同步延迟期间读主,同步完成后读从。

7.主从复制是推还是拉?

binlog 的同步可以是 slave 向 master 拉取(pull),也可以是 master 向 slave 推送(push),应该选择哪种方式?

“推”是指 MySQL 主库在有数据更新时推送变更给从库,这种方式只有在数据有变更的时候才会发生,资源消耗少,同步及时。

“拉”是指 MySQL 从库定期询问主库是否有数据更新,这种方式频繁询问,资源消耗多,效率低且同步延迟大。

那么 MySQL 具体是怎么同步 binlog 的呢?

slave 与 master 建立连接之后,会把当前哪个 binlog 文件(MASTER_LOG_FILE)和具体偏移位置(MASTER_LOG_POS) 告诉 master。对应的,主库会启动一个 log dump 线程,根据传过来的(file,pos)在本地的binlog中查找,并把剩下的 binlog 发送给slave。这个过程是 pull 模式。

当主从数据一致之后,master 收到的修改类操作,都会实时传播(propagate)给 slave,此时属于 push 模式。

所以 MySQL 主从复制是推拉结合。

参考文献

17.2 Replication Implementation - MySQL 看完这篇还不懂MySQL主从复制,可以回家躺平了 - 腾讯云 主从同步中的关键技术解析 - 腾讯云 主从不一致解决方案&& 如何降低主从延迟 - 阿里云 MySQL主从不一致情形与解决方法原创 - CSDN

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.目的
  • 2.主从架构
  • 3.主从复制原理
  • 4.binlog 三种格式
    • STATEMENT
      • ROW
        • MIXED
        • 5.主从复制方式
          • 5.1 异步复制
            • 5.2 全同步复制
              • 5.3 半同步复制
              • 6.主从复制问题
                • 数据丢失
                  • 同步延迟
                    • 读写分离问题
                    • 7.主从复制是推还是拉?
                    • 参考文献
                    相关产品与服务
                    云数据库 MySQL
                    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档