前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyDumper原理简介

MyDumper原理简介

原创
作者头像
ivansqwu
修改2018-06-25 22:11:20
5.1K0
修改2018-06-25 22:11:20
举报
文章被收录于专栏:云数据库云数据库

1. 简介

相对于 MySQL 官方提供的逻辑备份工具 mysqldump,mydumper 最突出的特性就是可采用多线程并行备份,极大提高了数据导出的速度。本文基于 mydumper在 github 上托管的最新源码,对其实现原理进行较详细的介绍。

2. 备份机制

与其他备份工具一样,mydumper 默认情况下是用 FTWRL (Flush Tables With Read Lock) 全局读锁来保证备份数据的一致性。FTWRL 锁对 MySQL 的杀伤力很大,特别是在读写负载比较高的场景,因而mydumper在加锁时会优先使用影响更小的备份锁,依次执行 LOCK TABLES FOR BACKUPLOCK TABLES FOR BINLOG,如果导出实例支持的话。

在进行数据备份时,mydumper 的主逻辑由一个主线程和多个备份子线程共同完成,默认情况下为四个子线程。其主线程的主要流程为:

  1. 连接数据库
  2. FLUSH TABLES WITH READ LOCK 将脏页刷新到磁盘并获得只读锁
  3. START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT /开启事务并获取一致性快照
  4. SHOW MASTER STATUS 获得binlog位点信息
  5. 创建子线程并连接数据库
  6. 为子线程分配任务并 push 到队列queue
  7. 在子线程处理完所有非 InnoDB 表之后,UNLOCK TABLES / FTWRL / 释放锁
  8. thread.join() 等待子线程结束

备份子线程的主要流程是:

  1. 连接数据库
  2. 将 session 的隔离级别设置为 Repeatable Read
  3. START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT /开启事务并获取一致性快照
  4. 从队列中 pop 任务并执行
  5. 在所有非 InnoDB 表执行完之后,将事件通知给主线程

值得注意的是,虽然 mydumper 支持表级别的并行操作,且在导出的时候会对大的表数据进行分块 chunk 导出,但是同一个表的 chunks 是在同一个线程中处理的,并非多线程并行的。

4. 备份的详细流程

mydumper执行备份的详细流程如下

mydumper flow
mydumper flow

流程图中的步骤基本与源码中的函数名称对应,可以将源码与流程图对照来看。

5. 一致性与锁

如流程图中所示,主线程会在开始时获取 FTWRL 全局只读锁,来保证确保接下来没有变更产生。

之后开启一致性读事务,创建子线程并确认子线程 session 隔离级别为 Repeatable Read、开启一致性读事务。这样保证了即使主线程在所有导出任务结束之前释放锁,子线程在处理 InnoDB 表时能利用 MySQL MVCC 特性继续执行,得到事务开启时间点的一致性数据视图。

接下来主线程会在自己的 session 里面读取数据库表结构、拆分任务,主线程UNLOCK TABLES释放锁由非 InnoDB 表都处理完的事件来触发,确保所有的非事务表的数据一致性。

mydumper通过结合以上逻辑可以保证即使在多线程处理的情形下,备份数据仍是一致的。

--trx-consistency-only 选项

这个选项与 mysqldump 的--single-transaction功能类似,将备份流程当作一个大事务来处理,可以看到流程中在主线程等待子线程创建完之后,主线程就会提前UNLOCK TABLES释放锁了。

显然,这个时候无法保证非InnoDB表的数据一致性,这是因为MyISAM等非事务并不支持MVCC特性,无法实现一致性快照读。

--less-locking 模式

mydumper有一个比较有意思的--less-locking选项,主要目的就是尽量减少 mydumper 中FTWRL整体的锁定时间。

这种模式的实现比较巧妙,在这种模式下,线程数量是用户指定线程数n的两倍,默认情况下也即是八个线程,新增的线程为专门处理非 InnoDB 表的一组线程less_locking_threads。主要的流程为:

  1. 主线程 FLUSH TABLES WITH READ LOCK 获取全局只读锁
  2. 主线程 START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT / 开启事务并获取一致性快照
  3. 主线程 SHOW MASTER STATUS获得binlog位点信息
  4. 主线程创建两组子线程并连接数据库,其中原来的一组线程threads会条件等待less_locking_threads结束才开始工作,less_locking_threads中结束一个就通知threads中的一个线程开始工作
  5. 主线程将非InnoDB表按照表中数据量均分为与n份push到queue_less_locking,其他表的导出任务还是按照原来的流程处理push到队列queue`中
  6. less_locking_threads中每个线程会拿到一个非InnoDB表任务执行,直到执行完通知threads中的一个线程开始执行queue中的任务
  7. 当所有less_locking_threads执行完时,主线程UNLOCK TABLES / FTWRL / 释放锁
  8. 主线程 thread.join() 等待子线程结束

可以看到在--less-locking模式下,mydumper 会首先集中能力处理完所有非 InnoDB 表的任务,尽快满足主线程释放锁的条件。由于每个less_locking_threads处理的任务量相当,这基本是最快的处理方式了。

参考

一致性问题

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 简介
  • 2. 备份机制
  • 4. 备份的详细流程
  • 5. 一致性与锁
    • --trx-consistency-only 选项
      • --less-locking 模式
      • 参考
      相关产品与服务
      云数据库 MySQL
      腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档