vlambda博客
学习文章列表

MySQL的主从复制&主从同步

MySQL 主从复制概念

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


常见的几种主从架构


单向主从模式:Master ——> Slave

双向主从模式:Master <====> Master

级联主从模式:Master ——> Slave1 ——> Slave2

一主多从模式

多主一从模式

主从复制功能


实时灾备

读写分离

高可用

从库数据统计

从库数据备份

Mysql支持哪些复制


1. 基于语句的复制: 在主服务器执行SQL语句,在从服务器执行同样语句。


注:MySQL默认采用基于语句的复制,效率较高。一旦发现没法精确复制时, 会自动选基于行的复制。


2. 基于行的复制: 把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持


3. 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。

  

主从复制原理


主从同步过程中主服务器有一个工作线程I/O dump thread,从服务器有两个工作线程I/O thread和SQL thread。


I/O线程:监听主服务器是否发生数据更改的行为

SQL线程:将主服务器数据更改的数据从中继日志文件中读取数据写入到从数据服务器中

中继日志:承接主服务器数据信息,转存在从服务器上


主库把外界接收的SQL请求记录到自己的binlog日志中,从库的I/O thread去请求主库的binlog日志,并将binlog日志写到中继日志中,然后从库重做中继日志的SQL语句。主库通过I/O dump thread给从库I/O thread传送binlog日志。(I/O线程)

1)从库会生成两个线程,一个I/O线程,一个SQL线程;

2)I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;

3)主库会生成一个log dump线程,用来给从库I/O线程传binlog;

4)SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;


复制方式的分类:


异步复制


异步复制是MySQL默认的复制方式,主库写入binlog日志后即可成功返回客户端,无须等待binlog日志传递给从库的过程,但是一旦主库宕机,就有可能出现丢失数据的情况。


半同步复制


MySQL默认的复制方式是异步复制,但是当主库宕机,在高可用架构做准备切换,就会造成新的主库丢失数据的现象。

  MySQL5.5版本之后引入了半同步复制,但是主从服务器必须同时安装半同步复制插件。在该功能下,确保从库接收完成主库传递过来的binlog内容已经写入到自己的relay log后才会通知主库上面的等待线程。如果等待超时(超时参数:rpl_semi_sync_master_timeout),则关闭半同步复制,并自动转换为异步复制模式,直到至少有一台从库通知主库已经接收到binlog信息为止。


为什么数据库要设置主服务器和从服务器?


数据库数据是一个公司或者集团企业最为重要的资产,以防数据的丢失和损坏,需要进行备份

当用户的访问量越来越高的时候,一旦查询也就是读取数据的操作太频繁了,势必网站崩掉,服务器宕机,很影响用户的体验度

提高数据库系统的可用性

mysql主从同步的原理介绍


实际开发项目中可能存在一主多从的数据库服务器,也就是一个主服务器,多个从服务器。现在就以一主一从的服务器配置来说明下数据怎么做到主从同步的,先来介绍下几个名词。


主数据服务器:主要用来从业务服务写入数据或者修改更新数据

从数据服务器:主要用来读取业务所需要的数据

二进制日志:用来存储写入以及更新的数据信息

中继日志:承接主服务器数据信息,转存在从服务器上

I/O线程:监听主服务器是否发生数据更改的行为

SQL线程:将主服务器数据更改的数据从中继日志文件中读取数据写入到从数据服务器中


主从同步原理:


当主数据服务器master进行写入数据或者更新数据操作的时候,数据更改会记录在二进制日志(binary log file)中,主服务器master与从服务器slave进行通讯的是I/O线程,它将修改的数据异步复制写入到slave服务器的中继日志(relay log file)中,从服务器slave与中继日志之间通信使用SQL线程,SQL线程可以异步从中继日志中读取数据后再写入到自己的数据库中,就完成了数据的主从同步功能。



从服务器slave为什么不能直接存储二进制日志文件里面的数据?


本来做数据的主从同步就是为了让计算机快速的进行读写操作,而且是大批量的数据,一旦大量数据进行写入或者更新数据,从数据库slave如果直接从二进制日志来接收,数据是以队列形式进行传输的,若队列的数据没有快速处理,堆积起来,从服务器可能也会崩溃宕机,所以从性能上考虑,从服务器slave创建了I/O线程对象将数据转到中继日志,起个缓存功能。


造成mysql同步延迟常见原因

1)网络:如主机或者从机的带宽打满、主从之间网络延迟很大,导致主上的binlog没有全量传输到从机,造成延迟。


2)机器性能:从机使用了烂机器?比如主机使用SSD而从机还是使用的SATA。


3)从机高负载:有很多业务会在从机上做统计,把从机服务器搞成高负载,从而造成从机延迟很大的情况


4)大事务:比如在RBR模式下,执行带有大量的delete操作,这种通过查看processlist相关信息以及使用mysqlbinlog查看binlog中的SQL就能快速进行确认


5)锁: 锁冲突问题也可能导致从机的SQL线程执行慢,比如从机上有一些select … for update的SQL,或者使用了MyISAM引擎等。


硬件方面(优化)


1.采用好服务器,比如4u比2u性能明显好,2u比1u性能明显好。


2.存储用ssd或者盘阵或者san,提升随机写的性能。


3.主从间保证处在同一个交换机下面,并且是万兆环境。


总结:硬件强劲,延迟自然会变小。一句话,缩小延迟的解决方案就是花钱和花时间。


mysql主从同步加速


1)sync_binlog在slave端设置为0


当事务提交后,Mysql仅仅是将binlog_cache中的数据写入Binlog文件,但不执行fsync之类的磁盘 同步指令通知文件系统将缓存刷新到磁盘


而让Filesystem自行决定什么时候来做同步,这个是性能最好的。


2)slave端 innodb_flush_log_at_trx_commit = 2


每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。


该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。


3)–logs-slave-updates 从服务器从主服务器接收到的更新不记入它的二进制日志。


4)直接禁用slave端的binlog