半万字长文学习 MySQL 主从复制原理,面试必问,建议收藏!
Posted 陆海潘江小C
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了半万字长文学习 MySQL 主从复制原理,面试必问,建议收藏!相关的知识,希望对你有一定的参考价值。
快速导航
数据的复制作为高可用、可扩展和备份的基础,目前的各种数据库几乎都有复制这项功能,最终目的就是备份数据,以防数据丢失造成重大损失。
mysql的主从复制就是一个典型的方案,实现一个主库的数据复制到一个或多个备库,这个方案属于“水平扩展”的架构。
这篇文章将带大家学习整个MySQL主从复制的内容,比如现在你会提问:MySQL是怎么实现主从复制的?主从复制有什么用?怎么保证主库和备库的同步复制,数据一致性?如果出现网络延迟等原因,查询数据不一致怎么办?
这些问题也是在面试中经常会问到的,接下来会详细分析,完整清晰,建议收藏!
一、主从复制到底是啥
1、主库上把数据更新记录写进二进制日志(Binary Log),简称binlog。
2、备库将主库的日志复制到自己的中继日志(Relay Log)中。
3、备库读取中继日志的事件。将其重放到备库数据之上。
1、一张图过程
下图是MySQL主从复制工作细节。
- 首先,备库会启动一个I/O线程,跟主库建立一个普通的客户端连接,将主库的binlog复制到本地的中继日志。
- 然后主库启动一个binlog dump线程,读取主库上binlog事件,且不会对事件进行轮询。如果线程读取完最新的更新事件,则进入睡眠,直到主库发送信号量通知有新事件产生才被唤醒,备库I/O线程会将收到的事件记录到本地log。
- 备库SQL线程执行最后一步,读取Relay Log日志并执行数据更新。
主库上记录二进制日志,每次准备提交事务完成数据个更新之前,主库将数据更新事件写进binlog。
Mysql按事务提交的顺序而非每条语句的执行顺序记录binlog。完成记录后,主库告诉存储引擎可以提交事务。
复制架构实现了获取事件和重放事件的解耦,两个过程异步执行。也看得出,备库重放事件是SQL线程的单线程执行。
2、新的备库与主库同步方法
前面的整个主从复制过程,是假设主备库都是默认刚安装好的情况,两台服务器上的数据相同。而大多数情况,我们的主库是运行一段时间了,然后将一台新的服务器数据库跟主库进行同步。
这样,有3种方法来初始化新的备库。
1、从主库复制
2、从另一台备库克隆数据
3、使用最近一次备份启动备库
因为初始时主备库数据不同步,需要有3个条件使得主库和备库保持同步。
1、在某个时间点的主库的数据快照。
2、主库当前二进制日志文件和获得数据快照时在该binlog中的偏移量,通过这两个坐标确定二进制日志文件的位置。
3、从快照时间到现在的binlog。
下面几种备份方式可以实现数据克隆。
- 冷备份
关闭主库,把数据复制到备库,重启主库后,会使用新的binlog日志文件。缺点很明显,关闭主库,通常是实现高可用性,这种方案不推荐。 - 热备份
仅仅使用MyISAM表时,可以在主库运行时使用mysqlhotcopy
或rsync
来复制数据;
只包含InnoDB表时,可以使用以下命令来转储主库数据并将其加载到备库。
mysqldump --single-transaction --all-databases --master-data = 1 --host = serverName | mysql --host = seeverName2
--single-transaction
使得转储的数据是事务开始前的数据。
3.快照
根据二进制日志坐标,使用主库的快照来初始化备库,然后使用change master to
指定二进制日志的坐标。
- 热备份工具Percona Xtrabackup
使用开源工具也是比较好的选择,可以在不阻塞服务器的情况下克隆主库来建立备库。
3、复制配置
在主库上的binlog最重要的选项是sync_binlog = 1
表示每次提交事务前会将日志同步到磁盘,保证崩溃时不会丢失数据。而在备库,设置为0来减少不必要的开销。
MySQL5.5可以选择控制崩溃时将事件刷新到磁盘,配置如下:
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
二、主从复制有什么用
1、数据备份
很明显,第一个想到的就是作数据备份,MySQL复制不会对带宽造成很大的压力。即使有网络延迟,复制工作仍然可以进行。
2、负载均衡
主从服务器都可以分摊读操作,在读密集型的应用,可以通过负载均衡将操作分布到不同服务器上。
3、高可用性和故障切换
复制能帮助避免MySQL单点失败,作为实现高可用的基础。
4、MySQL升级测试
使用一个高版本MySQL作为备库,保证升级全部数据库之前,查询能够在备库执行。
三、复制原理有2个
前面介绍了MySQL复制的大致过程,现在已经对复制由一个整体的理解,接下来就是具体内部实现复制的细节了。
复制主要由两种模式:基于语句的复制模式、基于行的复制模式;还有一个同时使用两种模式的混合模式。
我总结下来,不同的模式的原理和优缺点如下。
1、基于语句的复制:
binlog_format = statement
该模式下,主库会记录造成数据更改的语句,当备库读取并重放这些事件时,只需要把这些SQL再执行一遍。
优点:实现简单,只需要简单记录和执行这些语句。二进制日志文件更加紧凑,占用较小带宽。
缺点:传输二进制日志时,额外要记录当前时间戳,但可能无法正确复制SQL。比如CURRENT_USER()函数、存储过程和触发器在使用该模式也会出现问题。备库更新只能串行。
2、基于行的复制:
binlog_format = row
该模式下会将实际数据记录在二进制日志中。
优点:无须重放更新主库数据的查询,可以更高效地复制数据,占用更少的CPU。
缺点: 做全表更新时,复制开销会很大,因为每一行数据都会被记录到二进制日志,文件非常庞大。并且会主库上记录日志和复制增加额外的负载,更慢的日志记录则会降低并发度。
3、Mysql权衡动态切换
binlog_format = mixed
默认使用基于语句的复制方式,如果语句无法正确复制,就切换基于行的复制模式。
以上模式通过设置会话级别的变量binlog_format来控制二进制日志格式。
4、statement和row模式的区别
1、基于row复制模式
存储过程、函数、触发器,都是将执行之后的数据行,传给slave。
2、在基于statement 的复制时,存储过程、函数、触发器可能会数据不一致的情况
存储过程和函数在定义时,有 确定性函数和非确定性函数的。比如uuid(),now()这些函数都是非确定性函数,因为它们每次执行的值是不确定的。
在master和slave上分别执行会导致数据不一致,所以在基于语句复制的环境中,函数都必须是确定性的。否则只能采用row复制格式。
四、Mysql主从同步延迟分析及解决方案
这就是开头所讲的如何保证主从复制数据的一致性。大多数情况,受网络延迟、服务器性能等影响,会存在一些不理想的情况。
1、主从复制存在的问题
主库宕机后,数据可能丢失;
主从同步延迟。
2、延迟原因
MySQL主库对所有DDL和DML产生的日志写进binlog,由于binlog是顺序写,所以效率很高。
而备库SQL线程复制都是单线程的操作,当主库的并发较高时,产生的DML数量超过slave的SQL Thread所能处理的速度,或者当slave中有大型query语句产生了锁等待那么延时就产生了。
原因总结为这几个:
Master负载过高、Slave负载过高、网络延迟、机器性能太低、MySQL配置不合理。
3、主从延时排查方法
通过监控show slave status
命令输出的Seconds_Behind_Master参数的值来判断:
- NULL,表示io_thread或是sql_thread有任何一个发生故障;
- 该值为零,表示主从复制良好;
- 正值,表示主从已经出现延时,数字越大表示从库延迟越严重。
MySQL并没有内建的方法来比较两台服务器的数据是否相同。所以需要使用第三方工具Percona Toolkit,其中pt-table-checksum
命令可以确认主备数据是否一致。
其工作原理就是在主库执行insert ... select
查询,将结果插入一个表,传递到备库,备库执行一遍后将结果进行比较,这种方法能够与复制工作同时进行。
pt-table-checksum --replicate = test.checksum <master_host>
4、解决方案
- 半同步复制
从MySQL5.5开始,MySQL已经支持半同步复制了,半同步复制介于异步复制和同步复制之间,主库在执行完事务后不立刻返回结果给客户端,需要等待至少一个从库接收到并写到relay log中才返回结果给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一个TCP/IP往返耗时的延迟。
- 主库配置
sync_binlog = 1
,innodb_flush_log_at_trx_commit = 1
sync_binlog的默认值是0,MySQL不会将binlog同步到磁盘,其值表示每写多少binlog同步一次磁盘。备库配置值为零。
innodb_flush_log_at_trx_commit = 1表示每一次事务提交或事务外的指令都需要把日志flush到磁盘。
注意:将以上两个值同时设置为1时,写入性能会受到一定限制,只有对数据安全性要求很高的场景才建议使用,比如涉及到钱的订单支付业务,而且系统I/O能力必须可以支撑!
另外,还有几个方法。
- 优化网络
- 升级Slave硬件配置
- 升级MySQL版本到5.7,使用并行复制
五、总结
本文主要介绍了MySQL主从复制
,认真看完这篇文章将会对主从复制有一个比较系统的理解,其他数据库相关原理也是类似架构,这篇作为基础可以掌握,复制原理基础知识已经完全足够。
MySQL是怎么实现主从复制的?主从复制有什么用?怎么保证主库和备库的同步复制,数据一致性?如果出现网络延迟等原因,查询数据不一致怎么办?
这些问题是否能回答了呢?
欢迎大佬们讨论指点~
那本篇文章就介绍到这里了,面试必问系列,记得收藏~
本篇内容首发我的CSDN博客:半万字长文学习《MySQL》主从复制原理,面试必问,建议收藏
以上是关于半万字长文学习 MySQL 主从复制原理,面试必问,建议收藏!的主要内容,如果未能解决你的问题,请参考以下文章
⭐Redis分布式——主从复制Sentinel集群彻底吃透⭐(看完这篇万字长文,你的Redis水平将会上升一个层次)
⭐Redis分布式——主从复制Sentinel集群彻底吃透⭐(看完这篇万字长文,你的Redis水平将会上升一个层次)
「mysql优化专题」主从复制面试宝典!面试官都没你懂得多!(11)
万字长文!全网最全最细MySQL sql语句大全(建议收藏)
❤️BitmapsHyperLogLogGeospatial❤️——Redis三大特殊数据类型详述(万字长文原理讲解,大厂面试高频知识点,一文尽收囊中)