MySQL主从复制

1. 概述

MySQL的主从复制功能可以帮助我们实现负载均衡读写分离
对于主服务器来说,主要负责写,从服务器主要负责读,这样的话,就会大大减轻压力,从而提高效率。

主从复制可以分为:

  • 主从同步:当用户写数据主服务器必须和从服务器同步了才告诉用户写入成功,等待时间比较长。
  • 主从异步:只要用户对主服务器写数据成功,立即返回给用户。
  • 主从半同步:当用户访问主服务器写数据成功,并同步其中一个从服务器成功就返回给用户成功。

主从架构有以下几种形式:

  • 一主一从
  • 一主多从:一主多从是我们现在见的最多的主从架构,使用起来简单有效,不仅可以实现HA,而且还能读写分离,进而提升集群的并发能力。
  • 多主一从
  • 双主复制:双主复制,也就是可以互做主从复制,每个master既是master,又是另外一台服务器的salve。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
  • 级联复制:级联复制模式下,部分slave的数据同步不连接主节点,而是连接从节点。因为如果主节点有太多的从节点,就会损耗一部分性能用于replication,那么我们可以让3~5个从节点连接主节点,其他从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,而且对数据一致性没有负面影响。
    MySQL主从复制_第1张图片

2. 工作原理

MySQL主从复制是基于主服务器在二进制日志跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。

2.1 工作过程

MySQL的主从复制工作过程大致如下:

  1. 从库生成两个线程,一个I/O线程,一个SQL线程;
  2. I/O线程去请求主库的binlog,并将得到的binlog日志写到relay(中继日志)文件中;
  3. 主库会生成一个log dump线程,用来给从库I/O线程传输binlog;
  4. SQL线程会读取中继日志文件中的日志,并解析成具体操作,来实现主从的操作一致,实现数据一致。
    MySQL主从复制_第2张图片

3. 复制方式

MySQL主从复制支持语句复制行数据复制两种不同的日志格式,这两种日志格式也对应了各自的复制方式。当然也有二者相结合的混合类型复制。

3.1 语句复制

基于语句的复制相当于逻辑复制,即二进制日志中记录了操作的语句,通过这些语句在从数据库中重放来实现复制。
这种方式简单,二进制文件小,传输带宽占用小。但是基于语句更新依赖于其他因素,比如插入数据时利用了时间戳。
因此在开发当中,我们应该尽量将业务逻辑放在代码层,而不应该放在MySQL中,不易扩展。
特点:

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

基于行的复制相当于物理复制,即二进制日志中记录的实际更新数据的每一行。
这样导致复制的压力比较大,日志占用的空间大,传输带宽占用大。但是这种方式比基于语句的复制要更加精确
特点:

  • 不需要执行查询计划。
  • 不知道执行的到底是什么语句
3.3 混合类型的复制

一般情况下,默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

3.4 配置
# 如果在双主复制结构中没有设置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

4. 主从延迟问题

解决方法:

  • 网络方面:尽量保证主库和从库之间的网络稳定,延迟较小。(最好在同一局域网内)
  • 硬件方面:配置更好的硬件,提升随机写的性能。
  • 配置方面:尽量使MySQL的操作在内存中完成,减少磁盘操作。升级MySQL5.7版本使用并行复制
  • 构建方面:在事务中尽量对主库进行读写,其他非事务的读在从库。消除一部分延迟带来的数据不一致。

并行复制
在MySQL5.6版本前,从库复制主库时,sql线程是单线程的,MySQL5.6版本后引入并行复制,并行复制就是在中间加了一个分发任务的环节,也就是说原来的SQL Thread变成了现在的Coordinator组件,当日志来了之后,Coordinator负责读取日志信息以及分发事务,真正的日志执行的过程是放在了worker线程上,由多个线程并发的去执行。并发复制可以一定程度上解决主从延时的问题。
MySQL主从复制_第3张图片

5. 数据丢失

当主机宕机后,数据可能丢失。
解决方法:
使用半同步复制,可以解决数据丢失的问题。

6. 主从复制作用

主从复制带来了很多好处,当我们的主服务器出现问题,可以切换到从服务器;可以进行数据库层面的读写分离;可以在从数据库进行日常的备份。还可以保证:

  1. 数据更安全:做了数据冗余,不会因为单台服务器的宕机而丢失数据。
  2. 性能大大提升:一主多从,不同用户从不同数据库读取,性能提升。
  3. 扩展性更优:流量增大时,可以方便的增加从服务器,不影响系统使用。
  4. 负载均衡:一主多从相当于分担了主机任务,做了负载均衡。

你可能感兴趣的:(数据库,mysql,数据库,服务器)