大表的DDL的变更大部分都是使用Percona的pt-online-schema-change,但是这个是基于触发器(trigger)的。

========================
基于触发器的在线修改有哪些问题呢?
所有在线表结构修改工具的操作方式都类似:创建与原表结构一致的临时表,该临时表已经是按要求修改后的表结构了,缓慢增量的从原表中复制数据,同时记录原表的更改(所有的 INSERT, DELETE, UPDATE 操作) 并应用到临时表。当工具确认表数据已经同步完成,它会进行替换工作,将临时表更名为原表。

pt-online-schema-change, LHM 和 oak-online-alter-table 这些工具都使用同步的方式,当原表有变更操作时利用一些事务的间隙时间将这些变化同步到临时表。Facebook 的工具使用异步的方式将变更写入到changelog表中,然后重复的将changelog表的变更应用到临时表。所有的这些工具都使用触发器来识别原表的变更操作。

当表中的每一行数据有 INSERT, DELETE, UPDATE 操作时都会调用存储的触发器。一个触发器可能在一个事务空间中包含一系列查询操作。这样就会造成一个原子操作不单会在原表执行,还会调用相应的触发器执行多个操作。

在基于触发器迁移实践中,遇到了如下的问题:

触发器是以解释型代码的方式保存的。MySQL 不会预编译这些代码。 会在每次的事务空间中被调用,它们被添加到被操作的表的每个查询行为之前的分析和解释器中。

锁表:触发器在原始表查询中共享相同的事务空间,而这些查询在这张表中会有竞争锁,触发器在另外一张表会独占竞争锁。在这种极端情况下,同步方式的锁争夺直接关系到主库的并发写性能。以我们的经验来说,在生产环境中当竞争锁接近或者结束时,数据库可能会由于竞争锁而被阻塞住。触发锁的另一个方面是创建或销毁时所需要的元数据锁。我们曾经遇到过在繁忙的表中当表结构修改完成后,删除触发器可能需要数秒到分钟的时间。

不可信:当主库的负载上升时,我们希望降速或者暂停操作,但基于触发器的操作并不能这么做。虽然它可以暂停行复制操作,但却不能暂停出触发器,如果删除触发器可能会造成数据丢失,因此触发器需要在整个操作过程中都要存在。在我们比较繁忙的服务器中就遇到过由于触发器占用CPU资源而将主库拖死的例子。

并发迁移:我们或者其他的人可能比较关注多个同时修改表结构(不同的表)的场景。鉴于上述触发器的开销,我们没有兴趣同时对多个表进行在线修改操作,我们也不确定是否有人在生产环境中这样做过。

测试:我们修改表结构可能只是为了测试,或者评估其负载开销。基于触发器的表结构修改操作只能通过基于语句复制的方式来进行模拟实验,离真实的主库操作还有一定的距离,不能真实的反映实际情况。

======================
这次说明另一种工具 gh-ost的使用:

不依赖于触发器,是因为他是通过模拟从库,在row binlog中获取增量变更,再异步应用到ghost表的。

以下是该工具的工作原理

gh-ost 具有如下特性:

无触发器

轻量级

可暂停

可动态控制

可审计

可测试

值得信赖

无触发器
gh-ost 没有使用触发器。它通过分析binlog日志的形式来监听表中的数据变更。因此它的工作模式是异步的,只有当原始表的更改被提交后才会将变更同步到临时表(ghost table)

gh-ost 要求binlog是RBR格式 ( 基于行的复制);然而也不是说你就不能在基于SBR(基于语句的复制)日志格式的主库上执行在线变更操作。实际上是可以的。gh-ost 可以将从库的 SBR日志转换为RBR日志,只需要重新配置就可以了。

轻量级
由于没有使用触发器,因此在操作的过程中对主库的影响是最小的。当然在操作的过程中也不用担心并发和锁的问题。 变更操作都是以流的形式顺序的写到binlog文件中,gh-ost只是读取他们并应用到gh-ost表中。实际上,gh-ost 通过读取binlog的写事件来进行顺序的行复制操作。因此,主库只会有一个单独连接顺序的将数据写入到临时表(ghost table)。这和ETL操作有很大的不同。

可暂停
所有的写操作都是由gh-ost控制的,并且以异步的方式读取binlog,当限速的时候,gh-ost可以暂停向主库写入数据,限速意味着不会在主库进行复制,也不会有行更新。当限速时gh-ost会创建一个内部的跟踪(tracking)表,以最小的系统开销向这个表中写入心跳事件

gh-ost 支持多种方式的限速:

负载: 为熟悉 pt-online-schema-change 工具的用户提供了类似的功能,可以设置MySQL中的状态阈值,如 Threads_running=30

复制延迟: gh-ost 内置了心跳机制,可以指定不同的从库,从而对主从的复制延迟时间进行监控,如果达到了设定的延迟阈值程序会自动进入限速模式。

查询: 用户可以可以设置一个限流SQL,比如 SELECT HOUR(NOW()) BETWEEN 8 and 17 这样就可以动态的设置限流时间。

标示文件: 可以通过创建一个标示文件来让程序限速,当删除文件后可以恢复正常操作。

用户命令: 可以动态的连接到 gh-ost (下文会提到) 通过网络连接的方式实现限速。

可动态控制
现在的工具,当执行操作的过程中发现负载上升了,DBA不得不终止操作,重新配置参数,如 chunk-size,然后重新执行操作命令,我们发现这种方式效率非常低。

gh-ost 可以通过 unix socket 文件或者TCP端口(可配置)的方式来监听请求,操作者可以在命令运行后更改相应的参数,参考下面的例子:

echo throttle | socat - /tmp/gh-ost.sock 打开限速,同样的,可以使用 no-throttle 来关闭限流。

改变执行参数: chunk-size=1500, max-lag-millis=2000, max-load=Thread_running=30 这些参数都可以在运行时变更。

可审计
同样的,使用上文提到的程序接口可以获取 gh-ost 的状态。gh-ost 可以报告当前的进度,主要参数的配置以及当前服务器的标示等等。这些信息都可以通过网络接口取到,相对于传统的tail日志的方式要灵活很多。

可测试
因为日志文件和主库负载关系不大,因此在从库上执行修改表结构的操作可以更真实的体现出这些操作锁产生的实际影响。(虽然不是十分理想,后续我们会做优化工作)。

gh-ost 內建支持测试功能,通过使用 --test-on-replica 的参数来指定: 它可以在从库上进行变更操作,在操作结束时gh-ost 将会停止复制,交换表,反向交换表,保留2个表并保持同步,停止复制。可以在空闲时候测试和比较两个表的数据情况。

这是我们在GitHub的生产环境中的测试:我们生产环境中有多个从库;部分从库并不是为用户提供服务的,而是用来对所有表运行的连续覆盖迁移测试。我们生产环境中的表,小的可能没有数据,大的会达到数百GB,我们只是做个标记,并不会正在的修改表结构(engine=innodb)。当每一个迁移结束后会停止复制,我们会对原表和临时表的数据进行完整的checksum确保他们的数据一致性。然后我们会恢复复制,再去操作下一张表。我们的生产环境的从库中已经通过 gh-ost 成功的操作了很多表。

值得信赖
上文提到说了这么多,都是为了提高大家对 gh-ost 的信任程度。毕竟在业界它还是一个新手,类似的工具已经存在了很多年了。

在第一次试手之前我们建议用户先在从库上测试,校验数据的一致性。我们已经在从库上成功的进行了数以千计的迁移操作。

如果在主库上使用 gh-ost 用户可以实时观察主库的负载情况,如果发现负载变化很大,可以通过上文提到的多种形式进行限速,直到负载恢复正常,然后再通过命令微调参数,这样可以动态的控制操作风险。

如果迁移操作开始后预完成计时间(ETA)显示要到夜里2点才能完成,结束时候需要切换表,你是不是要留下来盯着?你可以通过标记文件让gh-ost推迟切换操作。gh-ost 会完成行复制,但并不会切换表,它会持续的将原表的数据更新操作同步到临时表中。你第二天来到办公室,删除标记文件或者通过接口 echo unpostpone 告诉gh-ost开始切换表。我们不想让我们的软件把使用者绑住,它应该是为我们拜托束缚。

说到 ETA, --exact-rowcount 参数你可能会喜欢。相对于一条漫长的 SELECT COUNT(*) 语句,gh-ost 会预估出迁移操作所需要花费的时间,还会根据当前迁移的工作状况更新预估时间。虽然ETA的时间随时更改,但进度百分比的显示是准确的。

gh-ost 操作模式
gh-ost 可以同时连接多个服务器,为了获取二进制的数据流,它会作为一个从库,将数据从一个库复制到另外一个。它有各种不同的操作模式,这取决于你的设置,配置,和要运行迁移环境。

a. 连接到从库,在主库做迁移
这是 gh-ost 默认的工作方式。gh-ost 将会检查从库状态,找到集群结构中的主库并连接,接下来进行迁移操作:

行数据在主库上读写

读取从库的二进制日志,将变更应用到主库

在从库收集表格式,字段&索引,行数等信息

在从库上读取内部的变更事件(如心跳事件)

在主库切换表

如果你的主库的日志格式是 SBR,工具也可以正常工作。但从库必须启用二级制日志(log_bin, log_slave_updates) 并且设置 binlog_format=ROW ( gh-ost 是读取从库的二级制文件)。

如果直接在主库上操作,当然也需要二进制日志格式是RBR。

b. 连接到主库
如果你没有从库,或者不想使用从库,你可以直接在主库上操作。gh-ost 将会直接在主库上进行所有操作。你需要持续关注复制延迟问题。

你的主库的二进制日志必须是 RBR 格式。

在这个模式中你必须指定 --allow-on-master 参数

c. 在从库迁移/测试
该模式会在从库执行迁移操作。gh-ost 会简单的连接到主库,此后所有的操作都在从库执行,不会对主库进行任何的改动。整个操作过程中,gh-ost 将控制速度保证从库可以及时的进行数据同步

–migrate-on-replica 表示 gh-ost 会直接在从库上进行迁移操作。即使在复制运行阶段也可以进行表的切换操作。

–test-on-replica 表示 迁移操作只是为了测试在切换之前复制会停止,然后会进行切换操作,然后在切换回来,你的原始表最终还是原始表。两个表都会保存下来,复制操作是停止的。你可以对这两个表进行一致性检查等测试操作。

gh-ost at GitHub
我们已经在所有线上所有的数据库在线操作中使用了gh-ost ,我们每天都需要使用它,根据数据库修改需求,可能每天要运行多次。凭借其审计和控制功能我们已经将它集成到了ChatOps流程中。我们的工程师可以清醒的了解到迁移操作的进度,而且可以灵活的控制其行为。

gh-ost 工具相关推荐

  1. mysql gh ost 对比_GitHub开源MySQL Online DDL工具gh-ost参数解析

    gh-ost版本:1.0.28 -allow-master-master 允许gh-ost运行在双主复制架构中,一般与-assume-master-host参数一起使用. -allow-nullabl ...

  2. gh ost mysql_mysql 在线修改表结构工具 gh-ost

    -allow-master-master 显式的允许在主主集群中运行-allow-on-master 允许直接运行在主机上,如果没有集群使用这个选项,推荐用在从机上-alter string(必须参数 ...

  3. gh ost mysql_MySQL DDL--gh-ost学习

    gh-ost工作原理 1.首先新建一张ghost表,结构与源表相同 2.使用alter命令修改ghost表 3.1.模拟从库命令获取主库上该表的binlog(基于全镜像的行模式的binlog包含更改前 ...

  4. mysql gh ost 对比_gh-ost和pt-osc性能对比

    基于MySQL row格式的复制现在趋于主流,因此可以使用此格式的binlog来跟踪改变而不是触发器.与percona toolkit的pt-online-schema-online相比,gh-ost ...

  5. gh ost mysql_MySQL在线DDL gh-ost 使用说明

    3)使用说明:条件是操作的MySQL上需要的binlog模式是ROW.如果在一个从上测试也必须是ROW模式,还要开启log_slave_updates.根据上面的参数说明按照需求进行调整. 环境:主库 ...

  6. mysql gh ost创建分区_gh-ost使用手册

    gh-ost实战运用 一.安装步骤 1.环境 go版本:1.10.3 gh-ost版本:1.0.46 2.安装go语言 # 安装go依赖包 yum install bison ed gawk gcc ...

  7. mysql gh 划线,gh-ost:在线DDL修改MySQL表结构工具

    在之前,我分享过一次pt-online-schema-change在线DDL的工具实践记录,在实际使用过程中,发现部门的很多老系统大量使用了触发器,从而无法使用这个工具,非常遗憾!导致很多DDL变更都 ...

  8. 一个好用的Outlook ost格式文件转pst文件的工具 (支持exchange2016)

    一个好用的Outlook ost格式文件转pst文件的工具 支持exchange2016 ops文件转换pst 下载链接https://www.datanumen.com/exchange-recov ...

  9. 一个好用的Outlook ost格式文件转pst文件的工具

    一个好用的Outlook ost格式文件转pst文件的工具.在win10上实测可以完整导出为pst.

  10. 一天1300 Star量,GitHub上新官方命令行工具

    机器之心 机器之心编辑部 不想用命令行操作 GitHub 的开发者,不是好的开发者. Git简介 小编私以为,Git 是世界上最好的代码版本控制工具,木有之一.在做项目的时候,通常我们会在本地写代码, ...

最新文章

  1. 华为“燃料”助力荣耀向上,全力冲击高端市场
  2. python划分有限元网格_有限元网格划分应该考虑些什么
  3. IIS 8.5配置.net网站[花了半个多小时]
  4. SharePoint Search之(七)Search result- 结果源
  5. Android studio http 代理设置
  6. vue 切换页面没有改变滚动条_VUE建立照片轮播功能
  7. fetchtype 动态控制_hibernate 关于 注解配置@Basic(fetch=FetchType.LAZY) 不起效果
  8. Android SqlLite数据库的创建、增、删、改、查、使用事务
  9. CSS选择器常见用法
  10. Git ssh fingerprint不一致
  11. 趣味点名软件_网传川大教授用刷脸软件点名 无人逃课
  12. C语言函数之 fabs()
  13. 移动端应该如何动态设置字体大小?
  14. 一图必通 | 计网~TCP、IP
  15. 研华PCI板卡开发(5)快速入门(5)群组操作
  16. 如果当面试官问你懂不懂npm,你知道怎么说吗?
  17. DynamicDto链式实现动态数据传输对象
  18. shader 处理cad线型 其中一小段的思路
  19. 51单片机基础之蜂鸣器
  20. 医疗大数据应用面临哪些挑战

热门文章

  1. Flink动态规则实时智能营销系统
  2. AAA:认证、审计、授权
  3. qq空间制作常用软件
  4. 班子不到位,一切都白费
  5. 从零开始的ZYNQ学习(基于矿卡EBAZ4205)(四)
  6. AI人工智能毕业设计课题:动漫网站,AI人物转动漫图像系统
  7. 计算光学和计算机科学与技术,光学计算会是未来发展方向吗?
  8. TexStudio内容字体格式设置+公式编写及排版心得
  9. SCU - 4438 Censor (KMP)
  10. 音乐制作软件Logic Pro X for Mac