玖叶教程网

前端编程开发入门

什么是DDL Online

关注我,获取更多分享。

  • 什么是DDL Online
  • 为什么要Online
  • DDL Online的方法
    • 官方自带DDL
    • Onlinept-online-schema-change工具
    • gh-ost工具
  • 总结

什么是DDL Online

DDL Online:在线执行DDL语句,也就是在线修改表结构。所谓在线的意思就是保证在执行DDL语句的过程中,表仍然可以提供正常的读写服务,不会中断。

这就像飞机在不降落的情况下,在空中给飞机加油的操作。

你可能会想我执行一个DDL语句很快的呀,不会导致表不能正常读写吧?那是因为你操作的表是一个数据量比较小的表,或者不是一个被频繁访问的业务表,对于这些表,执行DDL语句确实很快,不会对业务造成很大的影响。但是,你如果对一个几百万、甚至上千万的大表进行DDL语句的修改,这个DDL语句执行的过程,可能会持续几十秒、甚至几分钟,此时的这个过程不会像操作小表那么快。


为什么要Online

我们在生产环境中,难免要遇到对表结构的修改。而此时线上的表正在为后端提供各种请求访问的服务,如果此时我们直接进行对表结构的更改,可能导致后端的SQL请求被阻塞,不能正常访问,进而导致服务异常或不可用。所以,在我们对在线的表进行DDL操作的时候,要格外的注意。要选择合适的方式、合适的时间进行,尽量避免这些问题的发生。

那么为什么增加给表增加一个字段会导致锁表呢?

当我们对表增加字段的时候,我们就要获取这个表的MDL元数据锁(meta data lock)写锁(写锁又称为X锁,读锁又称为S锁),只有获取的这个MDL的X锁之后,我们才可以对这个表的结构进行修改,否则不能修改会被阻塞。


DDL Online的方法

目前为止,MySQL的DDL Online的方式主要有以下几种。

  • MySQL官方自带的DDL Online功能
  • percona提供的Percona Toolkit
  • Github开源的gh-ost工具
  • 主从切换的方式
  • Facebook的OSC
  • LHM

下面我们分别针对其中的几种方式来一一归纳总结一下。


官方自带DDL Online

MySQL从5.6之后的版本已经支持了DDL的Online操作。在使用的时候,就是在我们的DDL语句中,显示去指定关键字ALGORITHMLOCK的参数值。示例如下:


/*推荐该参数组合*/
alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=NONE;

alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=SHARED;

alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=DEFAULT;

alter table t add column col varchar(32), ALGORITHM=INPLACE, LOCK=EXCLUSIVE;

其中的ALGORITHM=INPLACE, LOCK=NONE是关键的地方,这里需要分别为ALGORITHMLOCK这两个参数指定值。

  • ALGORITHM该参数的值可以为INPLACE、COPY、DEFAULTINPLACE:它的原理是基于原来的表直接进行DDL的操作,此时原表可以支持DML操作。COPY:它的原理是复制出一张和原表的结构一样的表,然后基于这个新复制出来的表进行DDL操作。然后再用这个复制出来的新表替换掉原表。在执行DDL期间,原表不支持DML的操作,因为数据已经复制了一个新表中,在原表中如果仍然执行DML操作,将不能把这些操作同步到复制的新表中。DEFAULT:默认值,根据DDL语句的类型,自动的选择使用INPLACE或者COPY选项,能使用INPLACE的不使用COPY。注意:这个COPY的操作,要求磁盘的空间要充足,因为它会复制出一张和原表一样的表,会再次占用和原表一样的磁盘空间,同时会增加IO的负载。所以,一般情况下我们都是使用INPLACE作为ALGORITHM参数的值,只有当某些DDL语句,不支持ALGORITHM=INPLACE参数的时候,才选择ALGORITHM=COPY的选项。
  • LOCK参数的取值范围可以有NONE、SHARED、DEFAULT、EXCLUSIVE四种。NONE:表示不加锁,在DDL语句执行的过程中,表仍然可以进行selectDML的操作,这也正是我们DDL Online的真正所希望实现的效果。SHARED:可以执行select操作,但是不能执行DML操作。DEFAULT:根据不同的DDL语句,采用所需要的最小的锁。EXCLUSIVE:在DDL语句执行的过程中,既不能执行select操作,也不能执行DML操作。整个表完全不可以读写,被锁住。

MySQL自带的DDL Online的参数大纲如下:

图片来源参考:https://blog.csdn.net/finalkof1983/article/details/88355314

MySQL官方虽然已经支持了DDL的Online操作,但是,这个操作比较有局限性,并不是所有的DDL语句都可以真正的Online的去执行。有些DDL语句,虽然我们显示的执行要让其使用online的方式去执行,但是当MySQL真正的去执行的时候,如果它发现不能online的时候,会给出错误提示,让我们修改对应的显示参数去改为offline的方式去执行。这里不同的DDL语句范围很广,例如:修改字段类型、增加主键、删除主键、增加索引、删除索引、更改索引名称、增加字段、删除字段、修改字段长度等等。根据不同类型的DDL语句,参数ALGORITHMLOCK的取值范围并不是都可以随意组合使用的,这个要视情况而定,具体场景具体分析。具体参考如下图片:

图片来源参考:https://blog.csdn.net/finalkof1983/article/details/88355314

另外,在针对有主从架构的场景时,使用官方自带的这种DDL Online语句,即便是在master主节点可以online的去执行,但是会在从库上会执行同样的DDL语句期间,从库中对应的这个执行DDL语句的表会出现DML语句被阻塞的情况,从而出现主从延迟的现象。大致过程如下:

  1. master节点上某个表执行DDL语句,此时对表的DML仍然可以支持并行的执行。
  2. 在这个DDL语句没有执行完成之前,这个操作是不会通过binlog同步到slave节点上去的。只有当这个DDL语句在master节点执行完成后,才会同步到slave节点去执行。
  3. slave开始执行从master同步过来的DDL的过程中,从master节点同步过来的,对该表的DML语句不能同时执行,需要等待slave上面的DDL语句执行完成后,才可以执行同步过来的DML语句。
  4. 此时,在slave上就出现了延迟的现象。

所以,官方自带的这个在线的DDL方式比较有局限性。我们基本上都不使用这种方式,而是采用第三方的工具来实现在线修改表结构的需求。


pt-online-schema-change工具

pt-online-schema-change是Percona公司提供的众多工具集中的一个,它是工具包Percona Toolkit里面的其中一个命令。而这个工具箱的安装也比较简单,有各种安装方式。如果不想编译安装,可以下载一个编译好的二进制压缩包,开箱即用,解压后进入bin目录既可以使用。下载地址为:https://www.percona.com/downloads/percona-toolkit/LATEST/

pt-online-schema-change可以实现在线的DDL语句。它的原理是基于触发器来实现在线更改表结构。它的实现过程大概如下:

  1. 先创建一个临时表,这个临时表的表结构比原表的表结构不同之处就在于它已经应用了我们的DDL语句。
  2. 把原表中的数据慢慢的导入到这个临时表中。
  3. 在执行第2步导入操作的时候,如果仍然有对原表的DML语句,这些操作也要记录下来,然后同步到临时表中。
  4. 在确保临时表中的数据和原表中的数据完全同步之后,用临时表替换原表。

其中的第3步,在pt-osc工具中的实现方式是在原表上创建insert、update、delete触发器,通过这些触发器,把在导入数据到临时表的过程中在对原表的DML操作同步到临时表中去。这种做法比较大的问题就是增加了原表的压力,对原表的一些事物的操作会因为触发器操作临时表的加入而导致事物变长。

pt-online-schema-change使用方式如下所示:


pt-online-schema-change --user=root --password=123456 D=test_db,t=test_tab --alter "add column  col1 varchar(16) DEFAULT NULL COMMENT '测试字段1' AFTER id, add column col2 varchar(32) DEFAULT NULL COMMENT '测试字段2' AFTER col1" --recursion-method=processlist --check-interval=5s --max-lag=5s --print --charset=utf8 --execute

pt-online-schema-change命令各个参数解释如下


--user:
-u,连接的用户名
 
--password:
-p,连接的密码
 
--database:
-D,连接的数据库
 
--port
-P,连接数据库的端口
 
--host:
-h,连接的主机地址
 
--socket:
-S,连接的套接字文件
 
--ask-pass
隐式输入连接MySQL的密码
 
--charset
指定修改的字符集
 
--defaults-file
-F,读取配置文件
 
--alter:
结构变更语句,不需要alter table关键字。可以指定多个更改,用逗号分隔。如下场景,需要注意:
    不能用RENAME来重命名表。        
    列不能通过先删除,再添加的方式进行重命名,不会将数据拷贝到新列。
    如果加入的列非空而且没有默认值,则工具会失败。即其不会为你设置一个默认值,必须显示指定。
    删除外键(drop foreign key constrain_name)时,需要指定名称_constraint_name,而不是原始的constraint_name。
    如:CONSTRAINT `fk_foo` FOREIGN KEY (`foo_id`) REFERENCES `bar` (`foo_id`),需要指定:--alter "DROP FOREIGN KEY _fk_foo"
 
--alter-foreign-keys-method
如何把外键引用到新表?需要特殊处理带有外键约束的表,以保证它们可以应用到新表.当重命名表的时候,外键关系会带到重命名后的表上。
该工具有两种方法,可以自动找到子表,并修改约束关系。
    auto: 在rebuild_constraints和drop_swap两种处理方式中选择一个。
    rebuild_constraints:使用 ALTER TABLE语句先删除外键约束,然后再添加.如果子表很大的话,会导致长时间的阻塞。
    drop_swap: 执行FOREIGN_KEY_CHECKS=0,禁止外键约束,删除原表,再重命名新表。这种方式很快,也不会产生阻塞,但是有风险:
    1, 在删除原表和重命名新表的短时间内,表是不存在的,程序会返回错误。
    2, 如果重命名表出现错误,也不能回滚了.因为原表已经被删除。
    none: 类似"drop_swap"的处理方式,但是它不删除原表,并且外键关系会随着重命名转到老表上面。
 
--[no]check-alter
默认yes,语法解析。配合--dry-run 和 --print 一起运行,来检查是否有问题(change column,drop primary key)。
 
--max-lag
默认1s。每个chunk拷贝完成后,会查看所有复制Slave的延迟情况。要是延迟大于该值,则暂停复制数据,直到所有从的滞后小于这个值,使用Seconds_Behind_Master。如果有任何从滞后超过此选项的值,则该工具将睡眠--check-interval指定的时间,再检查。如果从被停止,将会永远等待,直到从开始同步,并且延迟小于该值。如果指定--check-slave-lag,该工具只检查该服务器的延迟,而不是所有服务器。
 
--check-slave-lag
指定一个从库的DSN连接地址,如果从库超过--max-lag参数设置的值,就会暂停操作。
 
--recursion-method
默认是show processlist,发现从的方法,也可以是host,但需要在从上指定report_host,通过show slave hosts来找到,可以指定none来不检查Slave。
METHOD       USES
===========  ==================
processlist  SHOW PROCESSLIST
hosts        SHOW SLAVE HOSTS
dsn=DSN      DSNs from a table
none         Do not find slaves
指定none则表示不在乎从的延迟。
--check-interval 
默认是1。--max-lag检查的睡眠时间。 
 
--[no]check-plan 
默认yes。检查查询执行计划的安全性。
 
--[no]check-replication-filters 
默认yes。如果工具检测到服务器选项中有任何复制相关的筛选,如指定binlog_ignore_db和replicate_do_db此类。发现有这样的筛选,工具会报错且退出。因为如果更新的表Master上存在,而Slave上不存在,会导致复制的失败。使用–no-check-replication-filters选项来禁用该检查。 
 
--[no]swap-tables 
默认yes。交换原始表和新表,除非你禁止--[no]drop-old-table。 
 
--[no]drop-triggers 
默认yes,删除原表上的触发器。 --no-drop-triggers 会强制开启 --no-drop-old-table 即:不删除触发器就会强制不删除原表。 
 
--new-table-name 
复制创建新表的名称,默认%T_new。 
 
--[no]drop-new-table 
默认yes。删除新表,如果复制组织表失败。 
 
--[no]drop-old-table 
默认yes。复制数据完成重命名之后,删除原表。如果有错误则会保留原表。 
 
--max-load 
默认为Threads_running=25。每个chunk拷贝完后,会检查SHOW GLOBAL STATUS的内容,检查指标是否超过了指定的阈值。如果超过,则先暂停。这里可以用逗号分隔,指定多个条件,每个条件格式: status指标=MAX_VALUE或者status指标:MAX_VALUE。如果不指定MAX_VALUE,那么工具会这只其为当前值的120%。 
 
--critical-load 
默认为Threads_running=50。用法基本与--max-load类似,如果不指定MAX_VALUE,那么工具会这只其为当前值的200%。如果超过指定值,则工具直接退出,而不是暂停。 
 
--default-engine 
默认情况下,新的表与原始表是相同的存储引擎,所以如果原来的表使用InnoDB的,那么新表将使用InnoDB的。在涉及复制某些情况下,很可能主从的存储引擎不一样。使用该选项会默认使用默认的存储引擎。 
 
--set-vars 
设置MySQL变量,多个用逗号分割。默认该工具设置的是: wait_timeout=10000 innodb_lock_wait_timeout=1 lock_wait_timeout=60 
 
--chunk-size-limit
当需要复制的块远大于设置的chunk-size大小,就不复制.默认值是4.0,一个没有主键或唯一索引的表,块大小就是不确定的。
 
--chunk-time
在chunk-time执行的时间内,动态调整chunk-size的大小,以适应服务器性能的变化,该参数设置为0,或者指定chunk-size,都可以禁止动态调整。
 
--chunk-size
指定块的大小,默认是1000行,可以添加k,M,G后缀.这个块的大小要尽量与--chunk-time匹配,如果明确指定这个选项,那么每个块就会指定行数的大小. 
 
--[no]check-plan
默认yes。为了安全,检查查询的执行计划.默认情况下,这个工具在执行查询之前会先EXPLAIN,以获取一次少量的数据,如果是不好的EXPLAIN,那么会获取一次大量的数据,这个工具会多次执行EXPALIN,如果EXPLAIN不同的结果,那么就会认为这个查询是不安全的。 
 
--statistics
打印出内部事件的数目,可以看到复制数据插入的数目。
 
--dry-run
创建和修改新表,但不会创建触发器、复制数据、和替换原表。并不真正执行,可以看到生成的执行语句,了解其执行步骤与细节。--dry-run与--execute必须指定一个,二者相互排斥。和--print配合最佳。
 
--execute
确定修改表,则指定该参数。真正执行。--dry-run与--execute必须指定一个,二者相互排斥。
 
--print
打印SQL语句到标准输出。指定此选项可以让你看到该工具所执行的语句,和--dry-run配合最佳。
 
--progress
复制数据的时候打印进度报告,二部分组成:第一部分是百分比,第二部分是时间。
 
--quiet
-q,不把信息标准输出。

pt-online-schema-change工具的不足之处在于它是通过在原表上创建各种trigger的方式来完成原表和新创建的临时表之间增量数据同步的需求。这样在临时表上执行来自于触发器的SQL,和原表上面的SQL是属于同一个事物。当原表的DML比较多的时候,会出现严重的性能问题。主要问题有如下:

  1. 触发器是用存储过程的实现的,就无法避免存储过程本身需要的开销;
  2. 增大了同一个事务的执行步骤,更多的锁争抢;
  3. 整个过程无法暂停,假如发现影响主库性能,停止 Online DDL,那么下次就需要从头来过;
  4. 多个并行的操作是不安全的;
  5. 无法在生产环境做测试;
  6. 触发器和源操作还是在同一个事务空间;

为了解决这些问题,Github开源的工具gh-ost放弃了基于触发器的原理,把更多的操作压力从数据库层级解放出来,放在gh-ost工具中去做,避免让数据库去做更多的任务。


gh-ost工具

gh-ost是Github开源的一款自己内部使用的在线修改数据库表结构的工具。它放弃了大多数第三方工具基于trigger触发器的原理来实现增量同步设计思想,改为使用基于binlog日志的方式来做原表和临时表的数据增量的同步。由于是基于binlog来实现数据同步的,所以MySQL主从都需要开启的binlog功能,与此同时,需要使用指定的row格式的binlog(虽然go-ost工具中支持把binlog的日志自己转换为row格式,但是最好还是自己本身就是使用的是row格式的日志)。

它的下载和安装也比较简单,有rpm安装包,也有提供编译好的二进制安装包,解压后直接使用即可。下载安装包的地址为:https://github.com/github/gh-ost/releases/tag/v1.1.0。

gh-ost在Github上面地址为:https://github.com/github/gh-ost,里面介绍了它的特点。主要是:无触发器、轻量级、可暂停、可动态控制、可审计、可测试等。

它的实现过程大致如下:

  1. gh-ost连接到master节点上,在master节点创建一个临时表ghost table,这表的结构是最后我们希望要的表结构。此时在从库上也会有一个临时表。
  2. 在主库上,将原表original table中的数据库复制到新建的临时表ghost table中。此时从库上面的临时表也会有数据被同步过去。数据来自于主库的临时表。
  3. gh-ost连接到某一个slave节点上,从slave节点上的binlog中,拉取原表的增量的binlog日志,然后把这些日志再应用到master节点上面的临时表ghost table中去。此时的动作也会同步到从库中的临时表中去。
  4. 等待所有的binlog都同步完成后,此时的原表original table和临时表ghost table数据已经完全一致,只是表结构不一样。锁住原表,用临时表替换原表。

gh-ost支持还支持多种操作方式如下:

  • 连接到主接单和从节点,上图中的第一个方式。这种方式适合有主从架构的集群,也是比较推荐的方式。
  • 只连接到主节点,上图中的第二个方式。如果我们的MySQL没有集群,只是一个单节点实例,我们可以采用图中的第二种方式。它完全可以支持只连接到一个节点上来实现online的DDL
  • 只连接到从节点,上图中的第三个方式。这种方式比较适合做测试。只在从节点上面实验。

参数解释如下:


Usage of gh-ost:
  --aliyun-rds:是否在阿里云数据库上执行。true
  
  --allow-master-master:是否允许gh-ost运行在双主复制架构中,一般与-assume-master-host参数一起使用
  
  --allow-nullable-unique-key:允许gh-ost在数据迁移依赖的唯一键可以为NULL,默认为不允许为NULL的唯一键。如果数据迁移(migrate)依赖的唯一键允许NULL值,则可能造成数据不正确,请谨慎使用。
  
  --allow-on-master:允许gh-ost直接运行在主库上。默认gh-ost连接的从库。
  
  --alter string:DDL语句
  
  --approve-renamed-columns ALTER:如果你修改一个列的名字,gh-ost将会识别到并且需要提供重命名列名的原因,默认情况下gh-ost是不继续执行的,除非提供-approve-renamed-columns ALTER。
  
  --ask-pass:MySQL密码,弹出输入密码的对话框,在命令行中手动输入。
  
  --assume-master-host string:为gh-ost指定一个主库,格式为”ip:port”或者”hostname:port”。在这主主架构里比较有用,或则在gh-ost发现不到主的时候有用。
  
  --assume-rbr:确认gh-ost连接的数据库实例的binlog_format=ROW的情况下,可以指定-assume-rbr,这样可以禁止从库上运行stop slave,start slave,执行gh-ost用户也不需要SUPER权限。
  
  --check-flag
  
  --chunk-size int:在每次迭代中处理的行数量(允许范围:100-100000),默认值为1000。
  
  --concurrent-rowcount:该参数如果为True(默认值),则进行row-copy之后,估算统计行数(使用explain select count(*)方式),并调整ETA时间,否则,gh-ost首先预估统计行数,然后开始row-copy。
  
  --conf string:gh-ost的配置文件路径。
  
  --critical-load string:一系列逗号分隔的status-name=values组成,当MySQL中status超过对应的values,gh-ost将会退出。-critical-load Threads_connected=20,Connections=1500,指的是当MySQL中的状态值Threads_connected>20,Connections>1500的时候,gh-ost将会由于该数据库严重负载而停止并退出。
        Comma delimited status-name=threshold, same format as --max-load. When status exceeds threshold, app panics and quits
        
  --critical-load-hibernate-seconds int :负载达到critical-load时,gh-ost在指定的时间内进入休眠状态。 它不会读/写任何来自任何服务器的任何内容。
  
  --critical-load-interval-millis int:当值为0时,当达到-critical-load,gh-ost立即退出。当值不为0时,当达到-critical-load,gh-ost会在-critical-load-interval-millis秒数后,再次进行检查,再次检查依旧达到-critical-load,gh-ost将会退出。
  
  --cut-over string:选择cut-over类型:atomic/two-step,atomic(默认)类型的cut-over是github的算法,two-step采用的是facebook-OSC的算法。
  
  --cut-over-exponential-backoff
  
  --cut-over-lock-timeout-seconds int:gh-ost在cut-over阶段最大的锁等待时间,当锁超时时,gh-ost的cut-over将重试。(默认值:3)
  
  --database string:数据库名称。
  
  --debug:debug模式。
  
  --default-retries int:各种操作在panick前重试次数。(默认为60)
  
  --discard-foreign-keys:该参数针对一个有外键的表,在gh-ost创建ghost表时,并不会为ghost表创建外键。该参数很适合用于删除外键,除此之外,请谨慎使用。
  
  --dml-batch-size int:在单个事务中应用DML事件的批量大小(范围1-100)(默认值为10)
  
  --exact-rowcount:准确统计表行数(使用select count(*)的方式),得到更准确的预估时间。
  
  --execute:实际执行alter&migrate表,默认为noop,不执行,仅仅做测试并退出,如果想要ALTER TABLE语句真正落实到数据库中去,需要明确指定--execute
  
  --exponential-backoff-max-interval int
  
  --force-named-cut-over:如果为true,则'unpostpone | cut-over'交互式命令必须命名迁移的表
  
  --force-table-names string:在临时表上使用的表名前缀
  
  --heartbeat-interval-millis int:gh-ost心跳频率值,默认为500
  
  --help
  
  --hooks-hint string:任意消息通过GH_OST_HOOKS_HINT注入到钩子
  
  --hooks-path string:hook文件存放目录(默认为empty,即禁用hook)。hook会在这个目录下寻找符合约定命名的hook文件来执行。
  
  --host string :MySQL IP/hostname
  
  --initially-drop-ghost-table:gh-ost操作之前,检查并删除已经存在的ghost表。该参数不建议使用,请手动处理原来存在的ghost表。默认不启用该参数,gh-ost直接退出操作。
  
  --initially-drop-old-table:gh-ost操作之前,检查并删除已经存在的旧表。该参数不建议使用,请手动处理原来存在的ghost表。默认不启用该参数,gh-ost直接退出操作。
  
  --initially-drop-socket-file:gh-ost强制删除已经存在的socket文件。该参数不建议使用,可能会删除一个正在运行的gh-ost程序,导致DDL失败。
  
  --master-password string :MySQL 主密码
  
  --master-user string:MysQL主账号
  
  --max-lag-millis int:主从复制最大延迟时间,当主从复制延迟时间超过该值后,gh-ost将采取节流(throttle)措施,默认值:1500s。
  
  --max-load string:逗号分隔状态名称=阈值,如:'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes
  
  --migrate-on-replica:gh-ost的数据迁移(migrate)运行在从库上,而不是主库上。 
  
  --nice-ratio float:每次chunk时间段的休眠时间,范围[0.0…100.0]。0:每个chunk时间段不休眠,即一个chunk接着一个chunk执行;1:每row-copy 1毫秒,则另外休眠1毫秒;0.7:每row-copy 10毫秒,则另外休眠7毫秒。
  
  --ok-to-drop-table:gh-ost操作结束后,删除旧表,默认状态是不删除旧表,会存在_tablename_del表。
  
  --panic-flag-file string:当这个文件被创建,gh-ost将会立即退出。
  
  --password string :MySQL密码
  
  --port int :MySQL端口,最好用从库
 
  --postpone-cut-over-flag-file string:当这个文件存在的时候,gh-ost的cut-over阶段将会被推迟,数据仍然在复制,直到该文件被删除。
  
  --quiet:静默模式。
  
  --replica-server-id uint : gh-ost的server_id
  
  --replication-lag-query string:弃用
  
  --serve-socket-file string:gh-ost的socket文件绝对路径。
  
  --serve-tcp-port int:gh-ost使用端口,默认为关闭端口。
  
  --skip-foreign-key-checks:确定你的表上没有外键时,设置为'true',并且希望跳过gh-ost验证的时间-skip-renamed-columns ALTER
  
  --skip-renamed-columns ALTER:如果你修改一个列的名字(如change column),gh-ost将会识别到并且需要提供重命名列名的原因,默认情况下gh-ost是不继续执行的。该参数告诉gh-ost跳该列的数据迁移,让gh-ost把重命名列作为无关紧要的列。该操作很危险,你会损失该列的所有值。
  
  --stack:添加错误堆栈追踪。
  
  --switch-to-rbr:让gh-ost自动将从库的binlog_format转换为ROW格式。
  
  --table string:表名
  
  --test-on-replica:在从库上测试gh-ost,包括在从库上数据迁移(migration),数据迁移完成后stop slave,原表和ghost表立刻交换而后立刻交换回来。继续保持stop slave,使你可以对比两张表。
  
  --test-on-replica-skip-replica-stop:当-test-on-replica执行时,该参数表示该过程中不用stop slave。
  
  --throttle-additional-flag-file string:当该文件被创建后,gh-ost操作立即停止。该参数可以用在多个gh-ost同时操作的时候,创建一个文件,让所有的gh-ost操作停止,或者删除这个文件,让所有的gh-ost操作恢复。
  
  --throttle-control-replicas string:列出所有需要被检查主从复制延迟的从库。
  
  --throttle-flag-file string:当该文件被创建后,gh-ost操作立即停止。该参数适合控制单个gh-ost操作。-throttle-additional-flag-file string适合控制多个gh-ost操作。
  
  --throttle-http string
  
  --throttle-query string:节流查询。每秒钟执行一次。当返回值=0时不需要节流,当返回值>0时,需要执行节流操作。该查询会在数据迁移(migrated)服务器上操作,所以请确保该查询是轻量级的。
  
  --timestamp-old-table:在旧表名中使用时间戳。 这会使旧表名称具有唯一且无冲突的交叉迁移
  
  --tungsten:告诉gh-ost你正在运行的是一个tungsten-replication拓扑结构。
  
  --user string :MYSQL用户
  
  --verbose
  
  --version
  

在MySQL单实例中使用示例:


gh-ost \
--user="root" \
--password="root" \
--host=192.168.163.131 \
--database="test" \
--table="t1" \
--alter="ADD COLUMN cc2 varchar(10),add column cc3 int not null default 0 comment 'test'" \
--allow-on-master \
--execute

单实例中需要指定--allow-on-master参数,默认gh-ost是连接到从节点上面的。

在MySQL主从集群中的使用示例:


gh-ost \
--user="root" \
--password="root" \
--host=192.168.163.130 \
--database="test" \
--table="t" \
--initially-drop-old-table \
--alter="ADD COLUMN y1 varchar(10),add column y2 int not null default 0 comment 'test' " \
--execute

在执行DDL中,从库会执行一次stop/start slave,要是确定从的binlog是ROW的话可以添加参数:--assume-rbr。如果从库的binlog不是ROW,可以用参数--switch-to-rbr来转换成ROW,此时需要注意的是执行完毕之后,binlog模式不会被转换成原来的值,如果需要,需要自己去手动切换为原来的格式。--assume-rbr和--switch-to-rbr参数不能一起使用。

只在从库中进行测试的使用示例:


gh-ost \
--user="root" \
--password="root" \
--host=192.168.163.130 \
--database="test" \
--table="t" \
--alter="ADD COLUMN x varchar(10),add column y int not null default 0 comment 'test'" \
--test-on-replica \
--switch-to-rbr \
--execute

参数--test-on-replica:在从库上测试gh-ost,包括在从库上数据迁移(migration),数据迁移完成后stop slave,原表和ghost表立刻交换而后立刻交换回来。继续保持stop slave,使你可以对比两张表。如果不想stop slave,则可以再添加参数:--test-on-replica-skip-replica-stop


总结

平时我们使用的比较多的就是Percona公司提供的pt-online-schema-change,还有就是Github的gh-ost工具。

对于其他几种方式,大家如果有兴趣,可以自己研究一下,这里不再赘述了。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言