本月初,GitHub数据库基础架构组的高级软件工程师 Shlomi Noach 在GitHub Engineering网站上发文 宣告 了gh-ost的开源发布。这对MySQL社区是一件大事,宣告停滞许久的MySQL表在线修改表定义操作又有了新的解决方案。
Shlomi这样总结:
gh-ost是GitHub最近几个月开发出来的,目的是解决一个经常碰到的问题:不断变化的产品需求会不断要求更改MySQL表结构。gh-ost通过一种影响小、可控制、可审计、操作简单而且安全的方式来改变线上表结构。
目前,MySQL在线修改表定义的任务主要是通过这三种途径完成的:
在从库上修改表定义的方案耗时长,需要更多的服务器,这种方案需要非常细致的管理工作,并且修改完毕后主从切换过程也会造成短暂的停服。InnoDB在线DDL功能在主库上操作的确是可以满足需求的,但过程不可中断,并且操作完成会造成主从库之间较大的延迟,对许多高可用方案及读写分离等会造成较大困扰。被各大公司DBA广泛接受的作法主要是通过Percona公司的pt-online-schema-change和Facebook的OSC在线操作。
所有在线更改表定义的工具运行原理都是相似的:创建一张与原始表定义相同的临时表,趁上面没有数据时先把临时表改好表定义,然后慢慢地、用增量方式把数据从原始表拷到临时表,同时不断地把进行中的原始表上的数据操作(所有应用在原始表上的插入、删除、更新操作)也应用过来。当工具把所有数据都拷贝完毕,两边数据同步了之后,它就用这张临时表来替代原始表。修改过程就结束了。
像pt-online-schema-change、LHM和oak-online-alter-table这些工具用的都是同步复制的方式,对表的每一条数据修改都会立刻在同一个事务里就应用到临时表上。Facebook的OSC工具用的则是异步模式,先把修改操作都记在一张修改日志表里,然后再取出来执行,把修改操作应用到临时表上。这些工具全都使用触发器来提取那些应用在目标表上的操作。
除了在修改过程中的性能、运维等问题之外,在最后的表切换——用临时表替代原始表——的过程中也非常容易出各种问题:切换失败、丢数据、阻塞原始表业务操作过久等。为此Shlomi曾在博客上基于较优的Facebook OSC的行为连续写了三篇文章( 一 、 二 、 三 )进行分析,进行了细致讨论,并最终给出了一种比较简单而又无损的方案。
GitHub每天数据库基础架构组几乎每天都会收到几次对表结构进行修改的请求,因此各种可能的丢失数据、复杂管理、进度不可见等行为都是不可忍受的。最终他们经过周密的讨论、研发和测试,推出了自己的工具:gh-ost,这个名字是gitHub's Online Schema Transmogrifier/Transfigurator/Transformer/Thingy的缩写,读音同Ghost。
gh-ost有以下特点:
gh-ost按照 MIT许可协议 向开源社区 发布 。尽管现在已经稳定了,GitHub仍在计划继续改进它,也非常欢迎来自开源社区的力量来一起试用和提出改进意见。gh-ost是用GO语言实现的。
感谢杜小芳对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们。