MySQL中主从复制原理

本文主要根据已有博客对MySQL中的主从复制知识点进行一个复习与总结,感觉收获很多。将文章发表出去以便我在后面的复习。

一、概念:

mysql从3.23版本开始提供复制功能,复制是将主库的DDL和DML操作通过二进制日志传递到复制服务器(从库)上,然后从库对这些日志重新执行(重做),从而使得主库和从库保持数据一致。

优点:

1、如果主库出现问题,可以快速地切换到从库提供服务。
2、可以在从库上执行查询操作,减轻主库的访问压力。
3、可以在从库上进行备份操作,防止备份操作影响主库服务。

解决的问题:

1、数据分布(Data distribution)
2、负载平衡(load balancing)
3、数据备份(Backups),保证数据安全
4、高可用和容错行(High availability and failover)
5、实现读写分离,缓解数据库压力

注意:由于MySQL实现的异步复制,所以主库与从库的数据存在差异。在从库执行查询操作时需要考虑数据的差异,一般只有更新不频繁和对实时性要求不高的数据可用从库执行查询操作。

MySQL主从复制的概念

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

MySQL主从复制的主要用途

1、读写分离
在开发过程中,有时会遇到某个sql语句需要锁表操作,导致暂时不能使用读的操作。使用主从复制,让主库负责写,让从库负责读。这样即使主库出现锁表场景,也会有从库负责读取操作,保证业务正常用作。
2、数据实时备份,当系统中某个节点发生故障,可以进行故障切换操作(主从切换)
提高数据安全。因为数据已经从主库上复制到从库上,就算主库发生故障也可以由从库代替主库的作用。从数据库服务器可以终止复制进程。
3、高可用(High Availability)

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

在主服务器上提供存入和更新功能,在从服务器上提供读取功能,达到读写分离的效果,也可以动态的调整从服务器的数量,从而调整整个服务器的性能。

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

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

二、 MySQL的主从形式

1、一主一从和一主多从

是最常用的主从架构,实施起来简单有效。不仅可以实现高可用,还能实现读写分离提升系统读性能,进而提升集群的并发能力。

2、多主一从

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

3、双主复制

是指两个服务器间相互做主从复制,每个Master(主)既是Master,也是另一台服务器的Slave(从)。这样任何一方做出更改都会同步到另一方的数据库中。

4、级联复制

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

三、MySQL主从复制原理

MySQL主从复制涉及三个线程,一个运行在主节点(log dump thread),其余两个运行在从节点(I/O thread和SQL thread)。
当write命令发送到Master服务器时

1、主节点(log dump thread)线程

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

2、从节点I/O 线程

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

3、从节点的SQL线程

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

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

要实施复制,必须打开Master端的binary log(bin-log)功能,否则无法实现。
因为整个复制过程实际上就是Slave从Master端获取该日志,然后再自己身上完全顺序的执行该日志文件中所记录的各种操作。

开始——Master更新数据——写bin-log——Slave线程——I/O thread——relay-log更新——SQL thread——执行更新。

4、复制的基本过程

  1. 在从节点上执行sart slave命令开启主从复制开关,开始进行主从复制。从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
  2. 主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程(log dump 线程)根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position(bin-log中的下一个指定更新位置);
  3. 从节点的I/O进程接收到主节点发送过来的日志内容、日志文件及位置点后,将接收到的日志内容更新到本机的relay-log(中继日志)的文件(Mysql-relay-bin.xxx)的最末端,并将读取到的binary log(bin-log)文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”;
  4. Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在主节点上实际执行过SQL语句,然后在本数据库中按照解析出来的顺序执行,并在relay-log.info中记录当前应用中继日志的文件名和位置点。

四、MySQL主从复制的模式

主从复制的模式有:异步模式、半同步模式、全同步模式、GTID(global transaction identifier)模式、多线程模式。
MySQL 主从复制默认是异步的模式。MySQL增删改操作会全部记录在bin-log(binary log)中,当slave节点连接master时,会主动从master处获取最新的bin-log文件。并把bin-log存储到本地的relay-log中,然后去执行relay-log的更新内容。

五、MySQL主从复制的方式

MySQL 主从复制有三种方式:基于SQL语句的复制(statement-based replication,SBR),基于行的复制(row-based replication,RBR),混合模式复制(mixed-based replication,MBR)。对应的bin-log文件的格式也有三种:STATEMENT, ROW, MIXED。

六、总结

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