1. 复制概述

MySQL 内置的复制功能是构建基于 MySQL 的大规模、高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步。接下来,我们将从复制概述及原理、复制的配置、常见的问题及解决方法来学习 MySQL 的复制功能。

1.1 复制解决的问题

下面是复制常见的用途:

  • 数据分布。Mysql 复制通常不会对带宽造成很大压力,但在 5.1 版本中引入的基于行的复制会比传统的基于语句的复制模式产生更大的带宽压力。你可以随意地停止或开始复制,并在不同的地理位置来分布数据备份,例如不同的数据中心。另外,即使在不稳定的网络环境下,远程复制也可以工作。但如果未来保存很低的复制延迟,最好有一个稳定、低延迟的连接。
  • 负载均衡。通过 Mysql 复制,可以将读操作分布到多个服务器上,实现对读密集型应用的优化,并且很容易实现,通过简单的代码修改就能实现基本的负载均衡。对应小规模的应用,可以简单的使用 DNS 轮询(将一个机器名指向多个 IP 地址)。
  • 备份。对于备份来说,负载是一项很有意义的技术补充。
  • 高可用性和故障切换。负载能够帮助应用避免 Mysql 单点失败,一个使用复制的设计良好的系统能够显著的缩短宕机时间。
  • Mysql 升级测试。这是比较常见的做法,在更新 Mysql 版本前,先使用将要更新的版本作为备库,保证更新版本不会对系统造成影响。

1.2 复制是如何工作的?

在详细介绍如何设置复制之前,让我们先看看 Mysql 实际上是如何进行数据复制的。

总的来说,复制有三个步骤:

  1. 在主库上把数据更改写入到二进制日志(Binary Log)中(这些记录被称为二进制日志事件)。
  2. 备库将主库上的日志复制到自己的中继日志(Relay Log)中。
  3. 备库读取中继日志中的事件,将其更改同步到备库。

以上是复制的简单概述,下图描述了复制的细节:

整体复制过程:

  1. 在主库上记录二进制日志。在每次准备提交事务完成 数据更新前,主库将数据更新的事件记录到二进制日志中。Mysql 会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志。在记录二进制日志后,主库会告诉存储引擎可以提交事务了。
  2. 备库将主库的二进制日志复制到其本地的中继日志中首先,备库会启动一个工作线程,称为 I/O 线程,I/O 线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储(binlog dump)线程,这个二进制转储线程会读取主库二进制日志中的事件。它不会对时间进行轮询。如果该线程“追赶”上了主库,它将进入睡眠状态,直到主库发送信号量通知它有新的事件产生才会被换新,备库 I/O 线程会将接收到的事件记录到中继日志中。
  3. 备库启动 SQL 线程,执行最后一步。该线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。当 SQL 线程追赶上 I/O 线程时,中继日志通常已经在系统缓存中,所以中继日志的开销很低。SQL 线程执行的事件也可以通过配置项来决定是否写入自身的二进制日志中,这对于备库再配置备库的常见非常有用。

这种复制架构实现了获取事件重放事件的解耦,允许这两个过程异步进行。也就是说 I/O 线程能够独立于 SQL 线程之前工作。但是,这种架构也限制了复制的过程,其中最重要的一点是,在主库上并发运行的查询在备库上只能串行化执行,因为只有一个 SQL 线程来重放中继日志中的事件。

不过值得高兴的是,5.7 版本已经支持从库的并行复制了。基于二进制日志的并行复制,是在日志内容中新增了 last_committed 和 sequence_number,分别 表示事务提交的时间和上次事务提交的编号。如果事务具有相同的时间,表示这些事务是在一组内,可以进行并行回放。

2. 复制的原理

我们已经了解了复制的一些基本概念,接下来我们要更深入的了解复制,看看复制究竟是如何工作的,有哪些优缺点。

2.1 基于语句的复制

在 Mysql 5.0 及之前的版本中只支持基于语句的复制(也称为逻辑复制)。基于语句的复制模式,主库会记录那些造成数据更改的 SQL 语句,当备库读取并重放这些事件时,实际上只是把主库执行过的 SQL 再执行一遍。这种方式既有优点,也有缺点。

优点是:

  1. 实现简单。理论上来说,只要简单地记录和执行 SQL 语句,就能够让主备保持同步。
  2. 二进制日志不会对带宽产生较大影响。二进制日志里的事件更加紧凑,占用带宽较小。

但事实上,基于语句的方式可能并不如其看起来那么便利,其缺点是:

  1. 主库上的数据除了执行的语句外,可能还依赖其他因素。当主库使用 CURRENT_USER() 函数的语句,存储过程和触发器在使用基于语句的复制模式时就可能会出现问题。

2.2 基于行的复制

Mysql 5.1 开始支持基于行的复制。这种方式会将实际数据记录在二进制日志中。同样的,它也有其自身的优缺点。

它的优点是可以更加准确的复制数据,而缺点,则是可能造成较大的开销。比如一个工资表中有一万个用户,我们把每个用户的工资+1000,那么基于行的复制则要复制一万行的内容,由此造成的开销比较大,而基于语句的复制仅仅一条语句就可以了。

由于没有哪种模式是对所有情况都是完美的,Mysql 就使复制模式可以动态切换。默认情况下使用的是基于语句的复制方式,但如果发现语句无法被正确地复制,就切换到基于行的复制模式。还可以根据需要来设置会话级别的变量 binlog_format,控制二进制日志格式。

2.3 复制文件解读

复制过程中会使用到一些文件。前面已经介绍了二进制日志文件中继日志文件,除此之外,还有其他的文件会被用到。

  1. mysql-bin.index:当在服务器上开启二进制日志时,同时会生成一个和二进制日志同名,但以 .index 作为后缀的文件,该文件用于记录磁盘上的二进制日志文件。这里的 index 并不是表的索引,而是说这个文件的每一行包含了二进制文件的文件名。Mysql 依赖这个文件识别二进制日志文件。
  2. mysql-relay-bin-index:中继日志的索引文件,和 mysql-bin.index 的作用类似。
  3. master.info:保存备库连接主库所需要的信息文件。格式为纯文本(每行一个值),不同的 Mysql 版本,记录的信息也可能不太。此文件不能删除,否则备库再重启后不能连接主库。这个文件以文本的方式记录了复制用户的密码,所以要注意此文件的权限控制。
  4. relay-log.info:记录当前备库复制的二进制日志和中继日志位置文件。

使用这些文件来记录 Mysql 复制和日志状态是一种非常粗糙的方式。更不幸的是,它们不是同步写的。如果服务器断电并且文件数据没有被刷新到磁盘,在重启服务器后,文件中记录的数据可能是错误。不过好在这些问题以及在 5.5 版本里做了改进。

2.4 发送复制事件到其它备库

log_slave_update 选项可以让备库编程其它服务器的主库。在设置该选项后,Mysql 会将其执行过的事件记录到它自己的二进制日志中。这样它的备库就可以从其日志中检索并执行事件。下图阐述了这一过程:

在这种场景下,主库将数据更新事件写入二进制日志,第一个备库提取并执行这个事件。这个时候一个事件的生命周期应该已经结束了。但由于设置了 log_slave_updates,备库会将这个事件写到它自己的二进制日志中。这样第二个备库就可以从第一个备库中,将事件提取到它的中继日志中并执行。

这意味着作为源服务器的主库可以将其数据变化传递给没有与其直接相连的备库上。默认情况下,这个选项是被打开的,这样在连接到备库时就不需要重启服务器。

当第一个备库把自主库获得的事件写入到其它二进制日志中时,这个事件在备库二进制日志中的位置与其主库二进制日志中的位置几乎肯定是不相同的,可能在不同的日志文件或文件内不同的位置。这意味着你不能假定所有拥有同一逻辑复制点的服务器拥有相同的日志坐标。

小结

  1. 复制功能是 MySQL 高扩展性的基础,常见的读写分离就使用了复制。
  2. 复制使用了三个线程。master 的日志线程,将事件写入 binlog,slave 的 IO 线程获取 binlog,并将其写入 relaylog,SQL 线程重放 relaylog 日志。
  3. 复制有基于语句复制和基于行的复制。

参考:

  1. 高性能 MySQL - 第 3 版;

转载于:https://juejin.im/post/5ca16e27e51d45074b422483

MySQL 复制 - 性能与扩展性的基石:概述及其原理相关推荐

  1. mysql 基于语句的复制_MySQL 复制 - 性能与扩展性的基石 1:概述及其原理

    1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步.接下来,我们将从复制概述及原理.复制的配置.常 ...

  2. linux下webservice压力测试,pylot压力测试支持linux及windowsWebService性能及扩展性的工具.docx...

    pylot压力测试支持linux及windowsWebService性能及扩展性的工具 下载以下软件请加群292501151,群共享有如有不便敬请谅解,执行#后面跟着(linux命令行)!普:Pylo ...

  3. MySQL复制性能优化

    MYSQL复制最容易出现的性能问题呢,就是主从延迟的问题,从前面的内容中我们可以知道,MYSQL复制是异步的,只是事务在主库上执行完,并记录到二进制日志之后,从库才能从二进制日志中取已经执行完的事务, ...

  4. 服务器双路性能提升,性能PK扩展性 入门级双路服务器比拼

    [IT168 评测]不久前,英特尔发布了新一代的至强E5v4处理器,又掀起了新一轮的服务器升级浪潮.那么其实对于许多用户来讲,在选购第一台服务器的时候往往有许多的顾虑.究竟是选择性能?还是选择扩展性? ...

  5. mysql双倍扩容_mysql扩展性架构实践N库到2N 库的扩容,2变4、4变8

    mysql扩展性架构实践N库到2N 库的扩容,2变4.4变8 http://geek.csdn.net/news/detail/52070 58同城 沈剑 http://www.99cankao.co ...

  6. Facebook 的 PHP 性能与扩展性

    炙手可热的 Facebook 是用 PHP 开发的.随着一些技术交流,逐渐能看到 Facebook 技术人员分享的经验.近期这个 geekSessions 站点上看到 Facebook 的 Lucas ...

  7. idou老师教你学Istio 04:Istio性能及扩展性介绍

    Istio的性能问题一直是国内外相关厂商关注的重点,Istio对于数据面应用请求时延的影响更是备受关注,而以现在Istio官方与相关厂商的性能测试结果来看,四位数的qps显然远远不能满足应用于生产的要 ...

  8. 对java并发性的理解,【图片】你了解过Java并发编程:性能、扩展性和响应的高端操作吗?【java吧】_百度贴吧...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 降低同步代码所带来的效果是可以测量的.在我的机器上,整个程序的执行时间从420ms降低到了370ms.看看吧,仅仅把三行代码移出同步保护块就可以将程序运行 ...

  9. asp.net的10个提升性能或扩展性的秘密(二)

    简介 Asp.net有很多值得你挖掘的"秘密",当你发现了它们,将会给你网站的性能和可扩展性带来巨大提升!例如,对于Membership以及Profile提供程序有一些秘密的瓶颈, ...

最新文章

  1. 论管理员的不作为!!!
  2. 安装ubuntu18.04虚拟机太慢
  3. Android RecyclerView封装下拉刷新与上拉加载更多
  4. $(document).ready() 与 window.onload 的区别
  5. 利用VS的代码优化和openmp并行计算提高程序运行速度
  6. Qt获取本机硬盘序列号,不受IDE硬盘与SCSI硬盘类型影响
  7. 拼多多显示内部服务器错误是怎么回事,拼多多提现出现错误怎么办?拼多多提现常见问题...
  8. bim管线插件:教你平面显示家用冷热水和卫生设备管道
  9. 成语小故事,职场必刷
  10. wordpress最佳架构_动物和宠物的24个最佳WordPress主题
  11. C++入门(六)之String
  12. 互联网dmz区_服务器设置于DMZ区,DMZ区是什么意思?
  13. 顺丰android架构师,顺丰数据库运维架构.pdf
  14. 全球土壤湿度数据获取方法
  15. ksps什么单位_IEEE754扩充精度算法异步转换速率的550KSPS
  16. context menu
  17. 一、万信金融项目——项目介绍
  18. GNU和GPL是什么?
  19. 【XJTUSE计算机图形学】第三章 几何造型技术(1)——参数曲线和曲面
  20. 主流自媒体平台优势与运营方法

热门文章

  1. Ivan Fedorov:用已知无法想象未来 - Mixin Network开发者访谈
  2. js运算符+运算方式
  3. 设计模式-行为型模式-中介者模式
  4. 2008 noip 传纸条
  5. Geek的入门神器:micropython-能跑python的stm32开发板
  6. AIX5安装bash
  7. C#中的三种委托方式:Func委托,Action委托,Predicate委托
  8. 软件开发的核心是技术人员吗?
  9. 深入理解.net服务器控件
  10. MySQL常见的主从复制架构_如何搭建经典的MySQL 主从复制架构