本文转载自:Mysql主从复制原理及同步延迟问题

主从复制解决的问题

  • 数据分布:通过复制将数据分布到不同地理位置
  • 负载均衡:读写分离以及将读负载到多台从库
  • 备份:可作为实时备份
  • 高可用性:利用主主复制实现高可用

复制原理

复制的原理其实很简单,仅分为以下三步:

  1. 在主库上把数据更改记录到二进制日志binary log中,具体是在每次准备提交事务完成数据更新前,主库将数据更新的事件记录到二进制日志中去,Mysql会按照事务提交的顺序来记录二进制日志的。日志记录好之后,主库通知存储引擎提交事务。

  2. 从库会启动一个IO线程,该线程会连接到主库。而主库上的binlog dump线程会去读取主库本地的binlog日志文件中的更新事件。发往从库,从库接收到日志之后会将其记录到本地的中继日志relay-log当中。

  3. 从库中的SQL线程读取中继日志relay-log中的事件,将其重放到从库中。(在5.6版本之前SQL线程是单线程的,使得主从之间延迟更大)

两种复制方式

日志文件中记录的到底是什么呢? mysql支持了两种日志格式,这两种日志格式也体现了各自的复制方式

基于语句复制:

基于语句的复制相当于逻辑复制,即二进制日志记录了操作的语句,通过这些语句在从库进行重放来实现复制。这种方式简单,二进制日志占用空间少,使得带宽小传输效率较高。 但是基于语句的更新依赖于其他因素,比如插入数据时利用时间戳函数调用当前时间作为时间值也会出现问题,因为由于主从之间的延迟导致时间值不一致。存储过程和触发器也可能出现问题。所以在开发当中我们应该将逻辑尽量放在代码层,而不应放到mysql中,不易扩展。

基于行复制:

基于行的复制相当于物理复制,即二进制日志记录了实际更新数据的每一行。这样导致行复制的压力比较大,因为日志占用空间较大,传输占用带宽也较高。但是比基于语句复制更加精确,可以屏蔽一些由于主库从库之间的差异导致的不一致。如刚才提到的时间戳函数。

二者对比:

  • 语句复制:

    • 传输效率高,减少延迟。
    • 在从库更新不存在的记录时,语句赋值不会失败。而行复制会导致失败,从而更早发现主从之间的不一致。
    • 设表里有一百万条数据,一条sql更新了所有表,基于语句的复制仅需要发送一条sql,而基于行的复制需要发送一百万条更新记录
  • 行复制:

    • 不需要执行查询计划。
    • 不知道执行的到底是什么语句。
    • 例如一条更新用户总积分的语句,需要统计用户的所有积分再写入用户表。如果是基于语句复制的话,从库需要再一次统计用户的积分,而基于行复制就直接更新记录,无需再统计用户积分。
因为两种方式各有优缺点,所以mysql在这两种复制模式进行动态的切换。默认是语句。

配置要点

# 如果在双主复制结构中没有设置ID的话就会导致循环同步问题
server_id=1 # 即日志中记录的是语句还是行更新或者是混合
binlog_format=mixed # 在进行n次事务提交以后,Mysql将执行一次fsync的磁盘同步指令。将缓冲区数据刷新到磁盘。
# 为0的话由Mysql自己控制频率。
sync_binlog=n # 为0的话,log buffer将每秒一次地写入log file中并且刷新到磁盘。
# mysqld进程崩溃会丢失一秒内的所有事务。
# 为1的话,每次事务log buffer会写入log file并刷新到磁盘。(较为安全)
# 在崩溃的时候,仅会丢失一个事务。
# 为2的话,每次事务log buffer会写入log file,但一秒一次刷新到磁盘
innodb_flush_logs_at_trx_commit=0 # 阻止从库崩溃后自动启动复制,给一些时间来修复可能的问题,
# 崩溃后再自动复制可能会导致更多的问题。并且本身就是不一致的
skip_slave_start=1 # 是否将从库同步的事件也记录到从库自身的bin-log中
# 允许备库将重放的事件也记录到自身的二进制日志中去,可以将备库当做另外一台主库的从库
log_slave_update # 日志过期删除时间,延迟严重的话会导致日志文件占用磁盘
expire_logs_days=7
innodb_flush_logs_at_trx_commit的三个参数很容易弄混。以下是详细的解析:

mysql先将日志写到log buffer缓冲区当中,再将log buffer缓冲区的数据写到log file日志文件中,此时写入的是内存中的log file,最终仍需操作系统将内存中的数据刷写到磁盘上。

  • 参数0:mysql每秒都会将log buffer的数据写入到log file中并且刷新到磁盘。意味着mysql崩溃的时候将会丢失一秒内的所有事务。
  • 参数1:每次事务提交都会将log buffer写入到log file并刷新到磁盘。意味着在mysql崩溃的时候,仅会丢失一个事务。
  • 参数2:每次事务提交都会将log buffer写入到log file但不同时写入到磁盘,由mysql自行控制每秒将log file刷写到磁盘上,当mysql崩溃的时候操作系统没崩溃的时候,log_file中仅会丢失一个事务,操作系统仍会将log file刷写到磁盘,而如果操作系统也崩溃或断电的话,则会丢失一秒内的事务。

推荐使用:innodb_flush_logs_at_trx_commit=2以及sync_binlog=500性能会较快。innodb_flush_logs_at_trx_commit以及sync_binlog都为1的话,较为安全。

延迟问题

延迟的产生:

  • 当主库的TPS并发较高时,由于主库上面是多线程写入的,而从库的SQL线程是单线程的,导致从库SQL可能会跟不上主库的处理速度(生产者比消费者快,导致商品堆积)。

延迟的解决:

网络方面:将从库分布在相同局域网内或网络延迟较小的环境中。

硬件方面:从库配置更好的硬件,提升随机写的性能。

配置方面:从库配置sync_binlog=0,innodb_flush_log_at_trx_commit=2,logs-slave-updates=0,增大innodb_buffer_pool_size,让更多操作在Mysql内存中完成,减少磁盘操作。或者升级Mysql5.7版本使用并行复制。

架构方面:比如在事务当中尽量对主库读写,其他非事务中的读在从库。消除一部分延迟带来的数据库不一致。增加缓存降低一些从库的负载。

 

Mysql主从复制原理及同步延迟问题的更多相关文章

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

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

  2. mysql 主从复制原理

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

  3. mysql主从复制(半同步方式)

    mysql主从复制(半同步方式) 博客分类: MySQL mysqlreplication复制  一.半同步复制原理介绍 1. 优点 当事务返回客户端成功后,则日志一定在至少两台主机上存在. MySQ ...

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

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

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

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

  6. mysql主从复制(主从同步)

    mysql主从同步 1.mysql主从同步(复制)概念 1. 将Mysql某一台主机数据复制到其它主机(slaves)上,并重新执行一遍来实现的. 2. 复制过程中一个服务器充当主服务器,而一个或多个 ...

  7. MySQL 主从复制原理不再难

    上篇我们分析过 Binlog 日志的作用以及存储原理,感兴趣的可以翻阅: 一文带你了解 Binlog 日志 Binlog 日志主要作用是数据恢复和主从复制.本身就是二进制格式的日志文件,网络传输无需进 ...

  8. MySQL(13)---MYSQL主从复制原理

    MYSQL主从复制原理 最近在做项目的时候,因为部署了 MYSQL主从复制 所以在这里记录下整个过程.这里一共会分两篇博客来写: 1.Mysql主从复制原理 2.docker部署Mysql主从复制实战 ...

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

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

随机推荐

  1. Python基础之给函数增加元信息

    1. 参数注解 当写好一个函数以后,想为这个函数的参数添加一些额外的信息,这样的话,其他的使用者就可以清楚的知道这个函数应该怎么使用,这个时候可以使用函数参数注解. 函数参数注解能提示程序员应该怎样正 ...

  2. Ubuntu14.04 软件安装卸载

    ----常用软件安装 sudo apt-get install vim-gtk //安装vim软件 sudo apt-get install zip //安装解压软件和解压文件 sudo apt-ge ...

  3. ssh sshpass随笔

    1: 当通过ssh连接远程服务器的时候,可能会出现以下繁琐场景,需要手工输入yes: ssh username@ip 这对于某些分布式集群来说是不行的,甚至导致集群都不能启动成功,对于像pssh,ps ...

  4. Tkinter 之MessageBox弹出框

    一.参数说明 语法 作用 截图 tk.messagebox.showwarning(title='提示', message='你确定要删除吗?') 警告信息弹窗   tk.messagebox.sho ...

  5. win10下子系统的倒腾记录

    本文是对于win10下安装ubuntu 18.04的安装.配置c语言开发环境的记录: 一.win10下面的设置,从win10的1709开始,可以完整的搞定linux子系统,如果win10版本不够的同学 ...

  6. routine的加载

    // Hearthbuddy.Windows.MainWindow // Token: 0x06000245 RID: 581 RVA: 0x0008C318 File Offset: 0x0008A ...

  7. 快速安装python3

    使用 rpm 包进行安装 先来介绍一下 IUS 这个社区,名字的全写是[Inline with Upstream Stable]取首字母,它主要是一个提供新版本RPM包的社区.具体使用可以查看官方文档 ...

  8. java udp通信

    package net.kkxm.kms;  import java.net.DatagramPacket; import java.net.DatagramSocket; import java.n ...

  9. 网站url路径优化方法完全讲解 (url优化、基于tp5、API接口开发)

    url优化可是网站开发的必备高阶技能,先看本实例优化前后效果比较: (同为调用前台模块下的index控制器下的index方法) 优化前:www.tp5.com/tp5/public/index.php ...

  10. python 函数、参数及参数解构

    函数 数学定义 y=f(x), y是x函数,x是自变量.y=f(x0,x1...xn) Python函数 由若干语句组成的语句块,函数名称,参数列表构成,它是组织代码的最小单位 完成一定的功能 函数作 ...