转自:http://www.ywnds.com/?p=14265python
1、背景mysql
GitHub正式宣布以开源的方式发布gh-ost:GitHub的MySQL无触发器在线更改表定义工具!下面是官方给出gh-ost产生的背景。linux
gh-ost是GitHub在2016年5月份开源的,目的是解决一个常常碰到的问题:不断变化的产品需求会不断要求更改MySQL表结构。gh-ost经过一种影响小、可控制、可审计、操做简单的方案来改变线上表结构。git
在介绍gh-ost以前,咱们先了解一下各类现有方案,以及为何要本身开发一个新工具。github
已有的在线修改表定义方案?算法
目前,在线修改表定义的任务主要是经过这三种途径完成的:sql
还有其它的好比Galera Cluster的Rolling Schema Upgrade,或者非InnoDB引擎的表等。GitHub的MySQL数据库用的都是主从复制架构,使用可靠的InnoDB引擎。shell
为何咱们决定去设计一个新解决方案,而不是直接从上面的几种方案中选一个用?现有的解决方案都有着自身的局限性,下面就对它们的不足之处作个简单分析。咱们会主要深刻地分析基于触发器的在线修改表定义工具的不足之处。数据库
基于触发器的解决方案有什么很差?服务器
全部在线修改表定义的工具运行原理都是类似的:建立一张与原始表定义相同的临时表,趁上面没有数据时先改好表定义,而后慢慢地、用增量方式把数据从原始表拷到临时表,同时不断的把进行中的原始表上的数据操做(全部应用在原始表上的插入、删除、更新操做)也应用过来。当工具把全部数据都拷贝完毕,两边数据同步了以后,它就用这张临时表来替代原始表。修改过程就结束了。
像pt-online-schema-change、LHM和oak-online-alter-table这些工具用的都是同步复制的方式,对表的每一条数据修改都会马上在同一个事务里就应用到临时表上。Facebook的工具用的则是异步模式,先把修改操做都记在一张修改日志表里,而后再取出来执行,把修改操做应用到临时表上。这些工具全都使用触发器来提取那些应用在目标表上的操做。
触发器都是存储过程,在表上有插入、删除、修改操做时就会被触发。触发器可能包括好多条语句,这些语句都是和引起触发器的那条操做在相同的事务空间内运行的,所以保证了这些操做的原子性。
通常意义上的触发器,尤为是基于触发器的表定义修改操做,都有以下问题:
2、gh-ost介绍
gh-ost是gitHub’s Online Schema Transmogrifier/Transfigurator/Transformer/Thingy的缩写,意思是GitHub的在线表定义转换器。抛弃了pt-online-schema-change使用trigger来同步增量数据的方法,而经过模拟slave获取row格式的binlog的方式来获取增量数据。思路也很新颖,做者很厉害,也是是openark kit工具集的做者(主要是用python写的一套工具集)。具体的数据流图能够看下图。
由于binlog中记录的是full image,因此binlog中的数据是最权威的,并且读取的binlog在应用的时候作了以下转化,并且copy old data是insert ignore,所以会以binlog的优先级为最高,所以不会有问题。
源类型
|
目标类型
|
insert
|
replace
|
update
|
update
|
delete
|
delete
|
对与insert和update是没有问题的,由于不管copy old row和apply binlog的前后顺序,若是apply binlog在后,会覆盖掉copy old row,若是apply binlog在前面,copy old row由于使用insert ignore,所以会被ignore掉;
对与delete数据,咱们能够演算一下,abc三个操做,可能存在三种状况(b确定在a的后面):
a. delete old row
b. delete binlog apply
c. copy old row
1. cab,c会将数据copy到ghost表,最后b会把ghost表中的数据delete掉;
2. acb,c空操做,b也是空操做;
3. abc,b空操做,c也是空操做;
大概看完了gh-ost工做原理后,既然牵扯到了replace语句,天然表就必需要有一个主键或惟一键。若是没有的状况下执行gh-ost,天然会获得gh-ost的一个错误提供:FATAL No PRIMARY nor UNIQUE key found in table! Bailing out.
gh-ost有如下特色:
gh-ost不使用触发器,它跟踪二进制日志文件,在对原始表的修改提交以后,用异步方式把这修改内容应用到临时表中去。
gh-ost但愿二进制文件使用基于行的日志格式,但这并不表示若是主库上使用的是基于语句的日志格式,就不能用它来在线修改表定义了。事实上,咱们经常使用的方式是用一个从库把日志的语句模式转成行模式,再从这个从库上去读日志。搭一个这样的从库并不复杂。
由于不须要使用触发器,gh-ost把修改表定义的负载和正常的业务负载解耦开了。它不须要考虑被修改的表上的并发操做和竞争等,这些在二进制日志中都被序列化了,gh-ost只操做临时表,彻底与原始表不相干。事实上,gh-ost也把行拷贝的写操做与二进制日志的写操做序列化了,这样,对主库来讲只是有一条链接在顺序的向临时表中不断写入数据,这样的行为与常见的ETL至关不一样。
由于全部写操做都是gh-ost生成的,而读取二进制文件自己就是一个异步操做,因此在暂停时,gh-ost是彻底能够把全部对主库的写操做全都暂停的。暂停就意味着对主库没有写入和更新。不过gh-ost也有一张内部状态跟踪表,即便在暂停状态下也会向那张表中不断写入心跳信息,写入量能够忽略不计。
gh-ost提供了比简单的暂停更多的功能,除了暂停以外还能够作:
负载:与pt-online-schema-change相近的一个功能,用户能够设置MySQL指标的阈值,好比设置Threads_running=30。
复制延迟:gh-ost内置了心跳功能来检查复制延迟。用户能够指定查看哪一个从库的延迟,gh-ost默认是直接查看它连上的那个从库。
命令:用户能够写一些命令,根据输出结果来决定要不要开始操做。好比:SELECT HOUR(NOW()) BETWEEN 8 and 17.
上述全部指标即便在修改表定义的过程当中也能够动态修改。
标志位文件:生成一个标志位文件,gh-ost就会马上暂停。删除文件,gh-ost又会恢复工做。
用户命令:经过网络连上gh-ost,经过命令让它暂停。
若是别的工具在修改过程当中产生了比较高的负载,DBA只好把它停掉再修改配置,好比把一次拷贝的数据量改小些,而后再从头开始修改过程。这样的反复操做代价很是大。
gh-ost经过监听TCP或者unix socket文件来获取命令。即便有正在进行中的修改工做,用户也能够向gh-ost发出命令修改配置,好比能够这样作:
echo throttle | nc -U /tmp/gh-ost.sock:这是暂停令, 也能够输入no-throttle取消暂停。
修改运行参数,gh-ost能够接受这样的修改方式来改变它的行为:chunk-size=1500, max-lag-millis=2000, max-load=Thread_running=30。
用上面所说的相同接口也能够查看gh-ost的状态,查看当前任务进度、主要配置参数、相关MySQL实例的状况等。这些信息经过网络发送命令就能够获得,所以就给了运维人员极大的灵活性,若是是使用别的工具的话通常只能是经过共享屏幕或者不断跟踪日志文件最新内容。
读取二进制文件内容的操做彻底不会增长主库的负载,在从库上作修改表结构的操做也和在主库上作是很是相象的(固然并不彻底同样,但主要来讲仍是差很少的)。
gh-ost自带了–test-on-replica选项来支持测试功能,它容许你在从库上运行起修改表结构操做,在操做结束时会暂停主从复制,让两张表都处于同步、就绪状态,而后切换表、再切换回来。这样就可让用户从容不迫地对两张表进行检查和对比。
咱们在GitHub是这样在生产环境测试gh-ost的:咱们有许多个指定的生产从库,在上面不提供服务,只是周而复始地不断地把全部表定义都改来改去。对于咱们生产环境地每一张表,小到空表,大到几百GB,都会经过修改存储引擎的方式来进行修改(engine=innodb),这样并不会真正修改表结构。在每一次这样的修改操做最后咱们都会停掉主从复制,再把原始表和临时表的全量数据都各作一次校验和,而后比较两个校验和,要求它们是一致的。而后咱们恢复主从复制,再继续测试下一张表。咱们生产环境的每一张表都这样用gh-ost在从库上作过好屡次修改测试。
全部上述讲到的和没讲到的内容,都是为了让你对gh-ost的能力创建信任。毕竟,你们在作这件事的时候已经使用相似工具作了好多年,而gh-ost只是一个新工具。
咱们在从库上对gh-ost进行测试,在去主库上作第一次真正改动以前咱们在从库上成功地试了几千次。因此,请你也在从库上开始测试,验证数据是无缺无损的,而后再把它用到生产环境。咱们但愿你能够放手去试。
当你执行了gh-ost以后,也许你会看见主库的负载变高了,那你能够发出暂停命令。用echo throttle命令生成一个文件,看看主库的负载会不会又变得正常。试一下这些命令,你就能够知道你能够怎样控制它的行为,你的内心就会安定许多。
你发起了一次修改操做,而后估计完成时间是凌晨2点钟,但是你又很是关心最后的切换操做,很是想看着它切换,这可怎么办?只须要一个标志位文件就能够告诉gh-ost推迟切换了,这样gh-ost会只作完拷贝数据的操做,但不会切换表。它还会仍然继续同步数据,保持临时表的数据处于同步状态。等次日早上你回到办公室以后,删除标志位文件或者向gh-ost发送命令echo unpostpone,它就会作切换了。咱们不但愿软件强迫咱们看着它作事情,它应该把咱们解放出来,让人去作人该作的事。
谈到估计完成时间,–exact-rowcount选项很是有用。在最开始时要在目标表上作个代价比较大的SELECT COUNT(*)操做查出具体要拷多少行数据,gh-ost就会对它要作多少工做有了一个比较准确的估计。接下来在拷贝的过程当中,它会不断地尝试更新这个估计值。由于预计完成的时间点老是会不断变化,因此已经完成的百分比就反而比较精确。若是你也曾经有过很是痛苦的经历,看着已经完成99%了但是剩下的一点操做却继续了一个小时也没完,你就会很是喜欢咱们提供的这个功能。
3、gh-ost工做模式
gh-ost工做时能够连上多个MySQL实例,同时也把本身以从库的方式连上其中一个实例来获取二进制日志事件。根据你的配置、数据库集群架构和你想在哪里执行修改操做,能够有许多种不一样的工做模式。
一、连上从库,在主库上修改
这是gh-ost默认的工做模式,它会查看从库状况,找到集群的主库而且链接上去。修改操做的具体步骤是:
A. 在主库上读写行数据;
B. 在从库上读取二进制日志事件,将变动应用到主库上;
C. 在从库上查看表格式、字段、主键、总行数等;
D. 在从库上读取gh-ost内部事件日志(好比心跳);
E. 在主库上完成表切换;
若是主库的二进制日志格式是Statement,就可使用这种模式。但从库就必须配成启用二进制日志(log_bin, log_slave_updates),还要设成Row格式(binlog_format=ROW),实际上gh-ost会在从库上帮你作这些设置。
事实上,即便把从库改为Row格式,这仍然是对主库侵入最少的工做模式。
二、连上主库
若是没有从库,或者不想在从库上操做,那直接用主库也是能够的。gh-ost就会在主库上直接作全部的操做。仍然能够在上面查看主从复制延迟。
A. 主库必须产生Row格式的二进制日志;
B. 启动gh-ost时必须用–allow-on-master选项来开启这种模式;
三、在从库上修改和测试
这种模式会在从库上作修改。gh-ost仍然会连上主库,但全部操做都是在从库上作的,不会对主库产生任何影响。在操做过程当中,gh-ost也会不时地暂停,以便从库的数据能够保持最新。
A. –migrate-on-replica选项让gh-ost直接在从库上修改表。最终的切换过程也是在从库正常复制的状态下完成的。
B. –test-on-replica代表操做只是为了测试目的。在进行最终的切换操做以前,复制会被中止。原始表和临时表会相互切换,再切换回来,最终至关于原始表没被动过。主从复制暂停的状态下,你能够检查和对比这两张表中的数据。
三种方法各有优缺点,这里只说缺点,先说第一种的缺点,因为会在从上面读取binlog,但有可能主库的binlog没有彻底在从库执行,因此我的感受第一种方法有丢失数据的风险。第二种方法任何操做都会再主库操做,或多或少会对主库负载形成影响,可是能够经过调整一些参数下降和时刻关注这些影响,因此我的推荐使用第二种方法。至于第三种方法是偏向测试用的,这里不作过多介绍,可是第三种方法里有一个细节,cut-over阶段有会stop slave一个操做,其实这个操做风险特别高,有时stop slave时间会很长,务必会对线上数据库使用形成影响,因此若是使用第三种方法作测试也要在线下数据库。
限制
5、gh-ost参数介绍
经常使用参数介绍
--host
--port
--user
--password
--database
--table
--alter
--allow-on-master
--max-load
迁移过程当中,gh-ost会时刻关注负载状况,负载阀值是使用者本身定义,好比数据库的最大链接数,若是超过阀值,gh-ost不会退出,会等待到负载在阀值如下继续执行。
--critical-load
这个指的是gh-ost退出阀值,当负载超过这个阀值,gh-ost会中止并退出。
--max-lag-millis
会监控从库的主从延迟状况,若是延迟秒数超过这个阀值,迁移不会退出,等待延迟秒数低于这个阀值继续迁移。这个是迁移中很大的一个问题,特别是在从库迁移时。
gh-ost监控复制延迟是经过检查gh-ost自己在实用程序更新日志表中注入的心跳事件来衡量的。也就是说,为了测量这个复制延迟,gh-ost不须要发出show slave status命令,也没有任何外部心跳机制。
当提供–throttle-control-replicas时,限流还会考虑指定主机上的延迟。经过查询gh-ost的更新日志表(其中gh-ost注入心跳)完成列出的主机上的延迟时间测量。
gh-ost可以利用毫秒测量复制延迟,当–max-lag-millis小于1000,即小于1秒时,gh-ost将进行限流。
--throttle-control-replicas
和–max-lag-millis参数相结合,这个参数指定主从延迟的数据库实例。
--initially-drop-ghost-table
gh-ost执行前会建立两张_xx_ghc和_xx_gho表,若是这两张表存在,且加上了这个参数,那么会自动删除原gh表,从新建立,不然退出。_xx_gho表至关于老表的全量备份,_xx_ghc表数据是数据更改日志,理解成增量备份。
--initially-drop-ghost-table
gh-ost操做以前,检查并删除已经存在的ghost表。该参数不建议使用,请手动处理原来存在的ghost表。默认不启用该参数,gh-ost直接退出操做。
--initially-drop-socket-file
gh-ost执行时会建立socket文件,退出时不会删除,下次执行gh-ost时会报错,加上这个参数,gh-ost会强制删除已经存在的socket文件。该参数不建议使用,可能会删除一个正在运行的gh-ost程序,致使DDL失败。
--initially-drop-old-table
gh-ost操做以前,检查并删除已经存在的旧表。该参数不建议使用,请手动处理原来存在的ghost表。默认不启用该参数,gh-ost直接退出操做。
--ok-to-drop-table
gh-ost执行完之后是否删除老表,加上此参数会自动删除老表。
--cut-over
自动执行rename操做,选择cut-over类型:atomic/two-step,atomic(默认)类型的cut-over是github的算法,two-step采用的是facebook-OSC的算法。
--cut-over-lock-timeout-seconds
gh-ost在cut-over阶段最大的锁等待时间,当锁超时时,gh-ost的cut-over将重试。(默认值:3)
--switch-to-rbr
让gh-ost自动将从库的binlog_format转换为ROW格式。
--assume-rbr
确认gh-ost链接的数据库实例的binlog_format=ROW的状况下,能够指定–assume-rbr,这样能够禁止从库上运行stop slave,start slae,执行gh-ost用户也不须要SUPER权限。
--panic-flag-file
这个文件被建立,迁移操做会被当即终止退出。
--throttle-flag-file
此文件存在时操做暂停,删除文件操做会继续。
--postpone-cut-over-flag-file
当这个文件存在的时候,gh-ost的cut-over阶段将会被推迟,直到该文件被删除。
--concurrent-rowcount
该参数若是为True(默认值),则进行row-copy以后,估算统计行数(使用explain select count(*)方式),并调整ETA时间,不然,gh-ost首先预估统计行数,而后开始row-copy。
--exact-rowcount
准确统计表行数(使用select count(*)的方式),获得更准确的预估时间。
--execute
若是肯定执行,加上这个参数。
可选参数介绍
--default-retries
各类操做在panick前重试次数。(默认为60)
--chunk-size
迁移过程是一步步分批次完成的,这个参数是指事务每次提交的行数,默认是1000。
--timestamp-old-table
使旧表包含时间戳值,旧表是在成功迁移结束时将原始表从新命名的内容。例如,若是表是gh_ost_test,那么旧表一般是_gh_ost_test_del。使用–timestamp-old-table后,它将是_gh_ost_test_20170221103147_del。
--throttle-http
提供一个HTTP端点,gh-ost将在给定的URL上发出HEAD请求,并在响应状态码不是200时进行限流。URL能够经过交互式命令动态查询和更新,空的URL表示禁用HTTP检查。
--approve-renamed-columns
当作(change old_name new_name …)动做时,gh-ost分析语句以尝试将旧列名称与新列名称相关联,若是它检测到确实是重命名操做,默认状况下将会打印出信息并退出。但除非你提供–approve-renamed-columns,强制发出迁移操做。
若是你认为gh-ost解析错误,而且实际上而且没有重命名,你能够改成传入–skip-renamed-columns,这将致使gh-ost取消关联列值,数据将不会在这些列之间复制。
--skip-foreign-key-checks
默认状况下,gh-ost会验证迁移表中存不存在外键,若是存在就会报错并退出;在具备大量表的服务器上,此检查可能须要很长时间。若是你肯定没有外键存在(表没有引用其余表,也没有被其余表引用)并但愿保存检查时间,可使用–skip-foreign-key-checks。但若是表上有外键,使用这个参数则会清除外键,千万注意。
--discard-foreign-keys
该操做很危险,意味着将默默丢弃表上存在的任何外键。目前,gh-ost不支持迁移表上的外键(当它在迁移表上注意到外键时,它会保留)。可是,它可以支持经过此标志删除外键,若是你想这么干,这是一个有用的选项。使用下来感受跟–skip-foreign-key-checks参数做用同样。
--replica-server-id
gh-ost原理是经过模拟slave从而得到binlog,其默认server-id为99999,若是你运行多个迁移,那么你必须为每一个gh-ost进程提供一个不一样的,惟一的server-id。也可使用进程ID当作server-id,例如:–replica-server-id = $((1000000000 + ))。
--migrate-on-replica
一般,gh-ost用于在主服务器上迁移表。若是你只但愿在从库上执行所有迁移,使用–migrate-on-replica参数将gh-ost链接到从库进行迁移。
--assume-master-host
默认状况下,gh-ost更倾向链接从库来进行迁移。gh-ost经过爬取复制拓扑来推断主服务器的身份,你能够经过–assume-master-host = the.master.com明确告诉gh-ost主服务器的身份。这在如下方面颇有用:
主 – 主拓扑结构(与–allow-master-master一块儿使用),其中gh-ost能够随意选择其中一个主协同者,这种状况你能够选择一个特定的主库。
tungsten复制器拓扑结构(与–tungsten一块儿使用),其中gh-ost没法抓取并检测主节点。
--dml-batch-size
gh-ost从二进制日志读取事件,并将它们应用到ghost表上。它采用的方式是将多个事件分组应用于单个事务中。这能够提供更好的写入吞吐量,由于咱们不须要将每一个事务日志同步到的磁盘。
此选项就是控制批量写入的大小,容许的值是1 – 100,其中1表示不分组处理(二进制日志中的每一个事件在其本身的事务中应用到ghost表上)。默认值是10。
--heartbeat-interval-millis
用来控制注入心跳事件的频率(就是_xx_ghc表),用来测量主从延迟。你应该设置heartbeat-interval-millis <= max-lag-millis。不然,将失去粒度和效果。默认值100。其–max-lag-millis值应该在300-500之间。
--conf
指定gh-ost凭据的文件,以下格式。
[client]
user=gromit
password=123456
--debug
输出详细日志。
--verbose
执行过程输出日志。
6、安装使用gh-ost
直接使用二进制安装便可
1
2
3
|
$ tar xvf /tmp/gh-ost-release/gh-ost-binary-linux-20180601054532.tar.gz -C /tmp
$ mv /tmp/gh-ost /usr/bin
$ gh-ost -version
|
若是你安装有什么问题直接借助搜索引擎应该就能够解决。
而后在使用上,下面是一些通用的配置(采起在主库进行DDL操做模式),你也能够尝试不一样的配置根据上面配置的介绍来使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
$ gh-ost \
--max-load=Threads_running=25 \
--critical-load=Threads_running=64 \
--chunk-size=1000 \
--throttle-control-replicas="10.10.0.110:3306" \
--max-lag-millis=1000 \
--initially-drop-old-table \
--initially-drop-ghost-table \
--initially-drop-socket-file \
--ok-to-drop-table \
--host="10.10.0.109" \
--port=3306 \
--user="root" \
--password="123456" \
--database="test" \
--table="test" \
--verbose \
--alter="add index idx1_k(k)" \
--switch-to-rbr \
--allow-on-master \
--cut-over=default \
--default-retries=120 \
--execute
|
7、gh-ost交互式命令
gh-ost被设计为操做友好。为此,它容许用户即便在运行时也能够控制其行为。gh-ost提供两种方式来进行动态控制。
Unix套接字文件:经过–serve-socket-file提供或由gh-ost默认设置,该接口老是处于启动状态。当gh-ost自我设定时,gh-ost将在启动时和整个迁移过程当中公布套接字文件的标识文件。默认在/tmp下面,由gh-ost.库名.代表.sock组成。
TCP:由–serve-tcp-port选项提供,默认没有。
两个接口能够同时使用,二者都响应简单的文本命令,这使得经过shell进行交互变得容易。
命令介绍:
help:显示可用命令的简要列表。
status:返回迁移进度和配置的详细状态摘要。
sup:返回迁移进度的简要状态摘要。
coordinates:返回检查服务器的最近(尽管不是最新的)二进制日志位置。
chunk-size=<newsize>:修改chunk大小,适用于下一刻数据复制。
dml-batch-size=<newsize>:适用于下一次应用二进制日志事件数量。
max-lag-millis=<max-lag>:修改最大复制延迟阈值(毫秒,最小值是100,即0.1秒)。
max-load=<max-load-thresholds>:修改最大负载配置,适用于下一刻数据复制。如“max-load=Threads_running=50,threads_connected=1000”。
critical-load=<critical-load-thresholds>:修改临界负载配置(超过这些阈值会停止操做)。
nice-ratio=<ratio>:修改nice比例,0表示不设置nice就是不睡眠线程。若是为1则表示gh-ost检测到复制行花费了1ms后将进行1*1ms睡眠;若是花费100ms,nice值为0.5,则会睡眠50ms,以此类推。默认为0。
throttle-http:改变HTTP端点。
throttle-query:改变查询。
throttle-control-replicas=’replica1,replica2’:更改副本的列表,这些副本是gh-ost会检查的,这须要用逗号分隔的副本列表来检查并替换先前的列表。
throttle:强制迁移暂停。
no-throttle:取消强制迁移暂停。
unpostpone:在gh-ost推迟cut-over阶段,指示gh-ost中止推迟并当即进行切换。
panic:理解放弃操做,意味着gh-ost将中断全部操做。
下面给一些样例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
$ echo "status" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
# Migrating `sbtest`.`sbtest1`; Ghost table is `sbtest`.`_sbtest1_gho`
# Migrating localhost.localdomain:3306; inspecting localhost.localdomain:3306; executing on localhost.localdomain
# Migration started at Thu Jun 07 03:37:12 -0400 2018
# chunk-size: 250; max-lag-millis: 1500ms; dml-batch-size: 10; max-load: Threads_running=25; critical-load: Threads_running=64; nice-ratio: 0.000000
# throttle-additional-flag-file: /tmp/gh-ost.throttle
# throttle-control-replicas count: 1
# Serving on unix socket: /tmp/gh-ost.sbtest.sbtest1.sock
Copy: 1612500/2607971 61.8%; Applied: 0; Backlog: 0/1000; Time: 4m24s(total), 4m24s(copy); streamer: mysql-bin.000033:180729376; State: migrating; ETA: 2m43s
$ echo "sup" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
Copy: 1655750/2607971 63.5%; Applied: 0; Backlog: 0/1000; Time: 4m36s(total), 4m36s(copy); streamer: mysql-bin.000033:189291849; State: migrating; ETA: 2m38s
$ echo "coordinates" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
mysql-bin.000033:140582919
$ echo "chunk-size=500" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
$ echo "chunk-size=?" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
500
$ echo "dml-batch-size=?" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
10
$ echo "max-lag-millis=?" | nc -U /tmp/gh-ost.sbtest.sbtest1.sock
1000
|