简介

Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。
复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。
当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
----------------------------------------------------------------------------------------------------------
需要注意的是:
在进行mysql复制时,所有对复制中的表的更新必须在主服务器上进行。否则必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
----------------------------------------------------------------------------------------------------------

1)Mysql支持那些复制
1--基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选着基于行的复制。
2--基于行的复制: 把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
3--混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。

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

3)Mysql主从复制原理
master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件,
同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,
使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。

也就是说:
- 从库会生成两个线程,一个I/O线程,一个SQL线程;
- I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;
- 主库会生成一个log dump线程,用来给从库I/O线程传binlog;
- SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;

注意几点:
1--master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
2--slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
3--Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
4--Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)
5--master和slave两节点间时间需同步

如上图所示:
Mysql复制过程的第一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二进制日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。

第二部分就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。

此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。

4)Mysql复制的模式
1--主从复制:主库授权从库远程连接,读取binlog日志并更新到本地数据库的过程;主库写数据后,从库会自动同步过来(从库跟着主库变);
2--主主复制:主从相互授权连接,读取对方binlog日志并更新到本地数据库的过程;只要对方数据改变,自己就跟着改变;

5)Mysql主从复制的优点
1--在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)
2--在从主服务器进行备份,避免备份期间影响主服务器服务;(确保数据安全)
3--当主服务器出现问题时,可以切换到从服务器。(提升性能)

6)Mysql主从复制工作流程细节
1)MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。
因此,要进行复制,必须在主服务器上启用二进制日志。每个从服务器从主服务器接收主服务器上已经记录到其二进制日志的保存的更新。
当一个从服务器连接主服务器时,它通知主服务器定位到从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,并在本机上执行相同的更新。然后封锁并等待主服务器通知新的更新。
从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。

2)MySQL使用3个线程来执行复制功能,其中两个线程(Sql线程和IO线程)在从服务器,另外一个线程(IO线程)在主服务器。
当发出START SLAVE时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。
主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以即为主服务器上SHOW PROCESSLIST的输出中的Binlog Dump线程。
从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志。
第3个线程是SQL线程,由从服务器创建,用于读取中继日志并执行日志中包含的更新。在从服务器上,读取和执行更新语句被分成两个独立的任务。
当从服务器启动时,其I/O线程可以很快地从主服务器索取所有二进制日志内容,即使SQL线程执行更新的远远滞后。

7)几点总结
主从数据完成同步的过程:
1) 在Slave 服务器上执行sart slave命令开启主从复制开关,开始进行主从复制。

2) 此时,Slave服务器的IO线程会通过在master上已经授权的复制用户权限请求连接master服务器,并请求从执行binlog日志文件的指定位置(日志文件名和位置就是
在配置主从复制服务时执行change master命令指定的)之后开始发送binlog日志内容

3) Master服务器接收到来自Slave服务器的IO线程的请求后,其上负责复制的IO线程会根据Slave服务器的IO线程请求的信息分批读取指定binlog日志文件指定位置之后
的binlog日志信息,然后返回给Slave端的IO线程。返回的信息中除了binlog日志内容外,还有在Master服务器端记录的IO线程。返回的信息中除了binlog中的下一个
指定更新位置。

4) 当Slave服务器的IO线程获取到Master服务器上IO线程发送的日志内容、日志文件及位置点后,会将binlog日志内容依次写到Slave端自身的Relay Log(即中继日志)
文件(Mysql-relay-bin.xxx)的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取master端新binlog日志时能告诉Master服务器从
新binlog日志的指定文件及位置开始读取新的binlog日志内容

5) Slave服务器端的SQL线程会实时检测本地Relay Log 中IO线程新增的日志内容,然后及时把Relay LOG 文件中的内容解析成sql语句,并在自身Slave服务器上按解析
SQL语句的位置顺序执行应用这样sql语句,并在relay-log.info中记录当前应用中继日志的文件名和位置点.

8)主从复制条件
1)开启Binlog功能
2)主库要建立账号
3)从库要配置master.info(CHANGE MASTER to...相当于配置密码文件和Master的相关信息)
4)start slave 开启复制功能

需要了解的:
1)3个线程,主库IO,从库IO和SQL及作用
2)master.info(从库)作用
3)relay-log 作用
4)异步复制
5)binlog作用(如果需要级联需要开启Binlog)

需要注意:
1)主从复制是异步的逻辑的SQL语句级的复制
2)复制时,主库有一个I/O线程,从库有两个线程,I/O和SQL线程
3)实现主从复制的必要条件是主库要开启记录binlog功能
4)作为复制的所有Mysql节点的server-id都不能相同
5)binlog文件只记录对数据库有更改的SQL语句(来自主库内容的变更),不记录任何查询(select,show)语句

============================================================
彻底解除主从复制关系
1)stop slave;
2)reset slave; 或直接删除master.info和relay-log.info这两个文件;
3)修改my.cnf删除主从相关配置参数。
让slave不随MySQL自动启动
修改my.cnf 在[mysqld]中增加 skip-slave-start 选项。

做了MySQL主从复制以后,使用mysqldump对数据备份时,一定要注意按照如下方式:
mysqldump --master-data --single-transaction --user=username --password=password dbname> dumpfilename
这样就可以保留 file 和 position 的信息,在新搭建一个slave的时候,还原完数据库, file 和 position 的信息也随之更新,接着再start slave
就可以很迅速的完成增量同步!

需要限定同步哪些数据库,有3个思路:
1)在执行grant授权的时候就限定数据库;
2)在主服务器上限定binlog_do_db = 数据库名;
3)主服务器上不限定数据库,在从服务器上限定replicate-do-db = 数据库名;

如果想实现 主-从(主)-从 这样的链条式结构,需要设置:
log-slave-updates 只有加上它,从前一台机器上同步过来的数据才能同步到下一台机器。
当然,二进制日志也是必须开启的:
log-bin=/opt/mysql/binlogs/bin-log
log-bin-index=/opt/mysql/binlogs/bin-log.index

还可以设置一个log保存周期:
expire_logs_days=14

主从\主主复制过滤

复制过滤:
让从节点仅仅复制指定的数据库,或指定数据库的指定数据表。主服务器有10个数据库,而从节点只需要同步其中的一两个数据库。
这个时候就需要复制过滤。复制过滤器可以在主节点中实现,也可以在从节点中实现。

Mysql主从同步部分数据有两个思路:

1) master只发送需要的;

2) Slave只接收想要的

=====master主节点=====
在主节点的二进制事件日志中仅记录与指定数据库(数据表)相关的事件日志,但是主节点的二进制日志不完整,没有记录所有对主节点的修改操作。(不推荐)
如果要使用该方式,则在主节点的配置文件中添加如下参数:
binlog_do_db="***,***,***";     #数据库白名单列表,二进制日志记录的数据库(多数据库用逗号隔开或重复设置多行),即需要同步的库.不在内的不同步。(不添加这行表示同步所有)
binlog_ingore_db="***,***,***"; #数据库黑名单列表, 二进制日志中忽略的数据库 (多数据库用逗号隔开或重复设置多行),即不需要同步,要过滤掉的库.

=====slave从节点=====
从服务器的 SQL Thread在Replay中继日志中的事件时,仅读取于特定数据库(数据表)相关的事件,并应用于本地。(但是浪费I/O ,浪费带宽)推荐使用
从节点复制过滤相关设置项:
replicate_do_db ="webdb";        #复制库的白名单. 设定需要复制的数据库(多数据库使用逗号隔开或重复设置多行)
replicate_ingore_db ="mysql";    #复制库的黑名单. 设定需要忽略的复制数据库(多数据库使用逗号隔开或重复设置多行)
replicate_do_table="webdb.user"; #复制表的白名单. 设定需要复制的表(多数据库使用逗号隔开或重复设置多行)
relicate_ingore_table="webdb.uw";#复制表的黑名单. 设定需要忽略的复制的表(多数据库使用逗号隔开或重复设置多行)

replicate-wild-do-table  #同replication-do-table功能一样,但是可以通配符.更高级别的应用,通配符,应用到哪一类表的.
replicate-wild-ignore-table #同replication-ignore-table功能一样,但是可以加通配符.

当在主库存在的库而从库不存在的库同步时,会出现sql错误,这时候可以排除或者从库手动导入主库数据库;

从库可以使用通配符"库名.%"方式过滤主从同步时某个库的设置
replicate-wild-do-table=webdb.%      #只复制webdb库下的所有表
replicate-wild-ignore-table=mysql.%  #忽略mysql库下的所有表

特别注意:
生产库上一般不建议设置过滤规则, 如果非要设置, 强烈建议从库使用通配符方式过滤某个库:
replicate-wild-do-table= "库名.%"
replicate-wild-ignore-table= "库名.%"

而不建议从库使用DB方式过滤某个库:
replicate_do_db ="库名"
replicate_ingore_db ="库名"

主从\主主环境部署

更加精彩部署篇点击链接:https://www.cnblogs.com/brianzhu/p/10154446.html

MySQL主从复制--原理的更多相关文章

  1. mysql 主从复制原理

    主从形式   mysql主从复制 灵活 一主一从 主主复制 一主多从---扩展系统读取的性能,因为读是在从库读取的: 多主一从---5.7开始支持 联级复制---     用途及条件   mysql主 ...

  2. [转]MySQL主从复制原理介绍

    MySQL主从复制原理介绍 一.复制的原理 MySQL 复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新.删除等等).每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以 ...

  3. Mysql主从复制原理及配置

    Mysql主从复制原理及配置 1.复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其 ...

  4. mysql 主从复制原理(转)

    本文转自https://blog.csdn.net/php_younger/article/details/59673879 mysql 主从复制原理 主从形式   mysql主从复制 灵活 一主一从 ...

  5. 如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题?

    如何实现 MySQL 的读写分离? 其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去. MySQL 主从复制原理的是 ...

  6. Mysql主从复制原理及搭建

    ## Mysql主从复制原理 主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中.对于多级复制,数据库服务器即可充当主机,也可充当从 ...

  7. mysql主从复制原理及实践

    Mysql主从复制原理及实践 mysql主从框架       MySQL主从架构是MySQL集群中最基本也是最常用的一种架构部署,能够满足很多业务需求,常见的有一主一从或者一主多从.可以防止单一主机的 ...

  8. 深度探索MySQL主从复制原理

    深度探索MySQL主从复制原理 一 .概要 MySQL Replication (MySQL 主从复制) 是什么? 为什么要主从复制以及它的实现原理是什么? 1.1 MySQL 主从复制概念 MySQ ...

  9. Mysql主从复制原理及同步延迟问题

    本文转载自:Mysql主从复制原理及同步延迟问题 主从复制解决的问题 数据分布:通过复制将数据分布到不同地理位置 负载均衡:读写分离以及将读负载到多台从库 备份:可作为实时备份 高可用性:利用主主复制 ...

随机推荐

  1. 开发微信小程序——古龙小说阅读器

    概述 由于面试的关系接触了一下微信小程序,花了2晚上开发了一个带书签功能的古龙小说阅读器,并且已经提交审核等待发布.这篇博文记录了我的开发过程和对微信小程序的看法,供以后开发时参考,相信对其他人也有用 ...

  2. Java基本数据类型总结、类型转换、常量的声明规范,final关键字的用法

    1  Java 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过 ...

  3. Source Insight函数调用关系显示设置

    当我们需要设置source Insight的项目代码中函数调用关系时,可通过如下的设置来实现: 1.显示函数调用关系窗口 Source Insight工具栏中“View”—>“Relation  ...

  4. Django2.1发布,Django2.1新特性

    Django 2.1 现已正式发布,官方表示随着 2.1 的发布,对 2.0 系列的主流支持服务将结束,进入安全修复服务周期,直至2019年4月. 2.1新特性:https://docs.django ...

  5. 测试工具之Match Tracer(正则表达式匹配工具)

    这个工具完全界面化,非常好用,如果对自己写的正则表达式不够确定,可以使用这个软件来试水一下 从下面网址可以下载: http://www.regexlab.com/zh/mtracer/download ...

  6. Xamarin.Android 无法检索到 Resource 问题

    错误提示:当前上下文中不存在名称"Resource" 解决方法: 1.看是否有其他错误,如果有其他错误优先解决.(其他错误导致无法感知到Resource) 2.重新生成解决方案.( ...

  7. 用synchronized同时修饰父类和子类,线程是安全的。即对象锁可重入

    public class SyncDubbo { static class Main { public int i = 10; public synchronized void operationSu ...

  8. MySQL 中的数字类型

    MySQL 中数据类型常用的就三大类: 数字类型/numeric types 日期和时间/date and time types 字符类型/string (character and byte) ty ...

  9. 强制清除 gradle 依赖缓存

    今天同事误上传一个库,然后又删除了... 我刚好把他上传的库给down下来了...然后项目一直报错,clean...重新编译...删build文件....全都不管用===== 好几个人研究了好久,只能 ...

  10. 用C#学习数据结构之线性表

    什么是线性表 线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系.这种一对一的关系指的是数据元素之间的位置关 ...