mysql的复制及备份

概述

       MySQL整体来看,其实就有两块:一块是Server层,它主要做的是MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。InnoDB引擎特有的日志是redo log,而Server层的日志称为binlog。binlog记录了对MySQL数据库执行更改的所有操作,大体作用:

  • 恢复:某些数据的恢复需要二进制日志。
  • 复制(replication):通过复制和执行二进制日志使一台远程的MySQL数据库(一般为slave或standby)与一台MySQL数据库(一般为master或primary)进行同步。(阿里cannel开源框架)
  • 审计(audit):用户可以通过二进制日志中的信息进行审计,判断是否有对数据库进行注入的攻击。

mysql复制原理在这里插入图片描述

  1. master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中,也称为二进制文件。
  2. slave开启一个I/O Thread,该线程与master建立连接,master则会启动binlog dump 线程并取binlog事件。如果读取的进度已经跟上了master,就进入睡眠状态并等待master产生新的事件。salve的I/O线程将接收到的事件写入到relay log(中继日志)中,且slave连接master的信息及同步进度数据都会保存在master.info文件中(具体内容参考下面复制方式)。
  3. slave 中的 SQL Thread会读取relay log(中继日志),并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致。

mysql复制模式

  • ROW(行模式):记录那条数据修改了,注意:记录的是这条记录的全部数据,即使只更新了一个字段,binlog里也会记录所有字段的数据
    • 优点:他不记录sql语句的上下文信息,日志内容会非常清楚的记录每条数据详细的变更细节,即使只更新了一个字段,binlog里也会记录所有字段的数据。因为可靠性强,基本选成这种
    • 缺点:binlog日志会非常大,mysql主从同步时,会产生大量磁盘IO
  • Statement(语句模式): 每一条会修改数据的sql都会记录在binlog中。
    • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
    • 缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题。
  • Mixed(混合模式):在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

MySQL主从复制方式

前提:binlog文件是顺序存储结构的。

  • 基于日志点复制
    1. 时间time,根据时间找time到binlog文件中与此时间最近的事务pos进行同步
    2. 位置pos,根据位置pos找到binlog文件中与此位置最近的事务pos进行同步
  • 基于GTID复制
    • GTID是全局事务ID,其保证为每个在master上提交的事务在复制集群中可以生产一个唯一ID。GTID的生成策略是source_id(也就是server的uuid,在auto.conf文件里面可以看到):transaction_id(自增序列)。解决Master-Master拓扑模式,binlog回路问题
    • 根据gtid,直接在binlog文件中找到进行同步

区别

  • 基于日志点复制
  1. 对sql查询没有什么限制
  2. 故障转移时重新获取master的日志点信息比较困难(因为偏移点是批量增长的,时间的话有可能一样)。如果指定错误会造成遗漏或者重复,造成主从不一致。
  • 基于GTID复制
  1. 不支持非事务引擎。对执行的sql有一定的限制。
  2. 可以很方便的进行故障转移,记录master最后事务的GTID值。(按事务分,比较清晰)

Mysql复制类型

  1. MySQL 5.5版本之前,一直采用的是这种异步复制的方式。主库的事务执行不会管备库的同步进度,如果备库落后,主库不幸crash,那么就会导致数据丢失.
  2. 在MySQL在5.5中就顺其自然地引入了半同步复制,主库在应答客户端提交的事务前需要保证至少一个从库接收并写到relay log中。
  3. MySQL在5.7.17中引入了一个全新的技术,称之为InnoDB Group Replication。目前官方MySQL 5.7.17基于Group replication的全同步技术已经问世,全同步技术带来了更多的数据一致性保障
异步复制

MySQL默认的复制即是异步的.

  1. 主库将事务Binlog事件写入到Binlog文件中
  2. 主库通知一下Dump线程发送这些新的Binlog
  3. 主库就会继续处理提交操作(sync binlog, engine Commit)
  4. 返回客户端(此时不会保证这些Binlog传到任何一个从库节点上)

在这里插入图片描述最大的问题
        master和slave事务更新的不同步,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。此时,master如果crash掉了,master上已经提交的事务可能没有传到slave上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

半同步复制

为解决异步复制的不足,MySQL 5.5~5.6可安装semisync_master.so插件,使用after_commit模式的半同步复制

  1. 主库将事务Binlog事件写入到Binlog文件中
  2. 主库通知一下Dump线程发送这些新的Binlog
  3. 主库就会继续处理提交操作(sync binlog, engine Commit),并向从库发生Event。
  4. dumper线程等待接收slave的ack工作
  5. 返回客户端在这里插入图片描述
    最大的问题
            主库将事务在存储引擎层(engine Commit)提交后,主库发生了crash,Slave端还没有读到该事务的events。此时,虽然主库没有返回当前客户端,但事务已经提交,其他客户端会读取到已提交事务。现在强行将从提升为主,那么之前读到的事务就不见了,出现了幻读。

针对上述的问题,5.7.2引入了Loss-less Semi-Synchronous插件,支持after_sync模式的半同步复制
6. 主库将事务Binlog事件写入到Binlog文件中
7. 主库通知一下Dump线程发送这些新的Binlog
8. 主库就会继续处理提交操作(sync binlog),并向从库发生Event。
9. Receiver线程等待接收slave的ack工作
10. 主库就会继续处理提交操作engine Commit
11. 返回客户端在这里插入图片描述

两者区别

  1. 独立出一个Ack Receiver线程 ,专门用于接收slave返回的ack请求,这将之前dump线程的发送和接受工作分为了两个线程来处理。
  2. 无损复制在write binlog完成后,就传输binlog,但还没有去写commit log,意味着当前这个事物对数据库的修改,其他事物也是不可见的。因此,不会出现幻读,数据丢失风险。

实际使用中还碰到一种情况从库IO线程有延迟时,主库会自动把半同步复制降为异步复制;当从库IO延迟没有时,主库又会把异步复制升级为半同步复制。

全同步复制

又称组复制。基于传统异步复制和半同步复制的缺陷——数据的一致性问题无法保证,官方在5.7.17版本正式推出组复制(MySQL Group Replication,简称MGR)。
在这里插入图片描述
MGR依靠分布式一致性Paxos协议(变体),实现了分布式下数据的最终一致性,并且所有以前特点

  1. 高可用:一台机子挂了,其它正常
  2. 可扩展:可加节点,新加节点会同步老节点数据(必须基于GTID)
  3. 容错:容忍 f 个故障机所需的服务器数量 n 为:n = 2 * f + 1。

mysql复制常用拓扑结构

在这里插入图片描述
复制的体系结构有以下一些基本原则:

  1. 每个slave只能有一个master;
  2. 每个slave只能有一个唯一的服务器ID;
  3. 每个master可以有很多slave;
  4. 如果你设置log_slave_updates,slave可以是其它slave的master,从而扩散master的更新。

常见的拓扑结构有:

  • master和slave
  • 主动-被动模式的Master-Master
  • 带从服务器的Master-Master结构
  • master和分发master和slave
  • 级联复制架构 Master –Slaves - Slaves

备份恢复

“复制是备份”是我们经常碰到一个误区,复制不是备份。如果意外发生主库"drop database",备库能否帮我们恢复所有的数据?而我们的备份方案往往是根据恢复需求而来的。

备份方案
  • 逻辑备份还是物理备份

    • 逻辑备份:由数据库服务器完成生成逻辑备份,比如dump将表以sql 的方式导出
    • 物理备份:基于文件,只需要将需要的文件复制到其他地方即可完成备份,比如binlog。InnoDB需要停止数据库服务(FLUSH TABLES WITH READ LOCK)把缓存中的数据都刷到磁盘,或者直接关停Mysql
  • 在线备份还是离线备份

    • 离线备份:将Mysql关停,备份数据(大多情况无法接受)
    • 物理备份:Mysql运行期间进行备份,大致要考虑
      1. 锁时间:需要持有锁多长时间,例如备份期间持有的全局FLUSH TABLES WITH READ LOCK。将数据导出
      2. 备份时间和负载: 复制备份到目的地需要多久及对服务器性能的影响有多少(Perconna XtraBackup工具有控流产品)
      3. 恢复时间:把备份镜像从存储位置复制到MySQL服务器,重放二进制日志需要多久
  • 快照方式

    • 复制数据文件产生副本
    • 文件系统快照,LVM
    • 硬盘快照,RAID
  • 全量备份还是增量备份
    - 全量备份:全部备份下来
    - 增量备份:上次全量备份后,所发生改变的数据进行备份

互联网复制备份架构选择

  • 复制拓扑采用主动-被动模式的Master-Master
  • 在被动Master(备库)使用 XtraBackup 进行 每周全量,第日增量的物理备份
  • 在被动Master(备库),接入canal等开源框架并向其它库分发(模拟从库)

满足以下问题:

  • 选择性复制:模拟从库可以根据自己的需要拉取相关数据
  • 分离功能:Master只做OLTP.OLAP在模拟从库做
  • 数据归档:模拟从库,可不接收Master的delete事件。Master最好保证逻辑设计,由DBA统一删除。最好使用唯一的ID,以防止归档的时间出现错误
  • 文件系统快照:停机被动Master,全量备份Mysql数据文件.然后再flush logs,将后面提交的写到新的binlog中,方便增量备份。
  • 数据一致性:binlog事件是基于事务的,不能防止逻辑设计很差的应用

主要参考

《高性能Mysql》
MySQL 5.7半同步复制技术
MySQL 8 复制(七)——组复制基本原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章