Mysql online DDL(GH-OST)初尝试

MySQL的大表DDL操作一直是比较头疼的问题,因为DDL操作会锁表影响业务操作,为保障业务连续性不受影响,所以在线DDL操作就很有必要。最近有幸在工作中接触到这类需求。记录一下。

gh-ost介绍

gh-ost(Pronunce: ghost),即 gitHub’s online schema transformer,是github使用go语言开发的,专门用于数据库在线表定义操作(在线DDL操作),其github地址

原理

简而言之,①创建满足要求的ghost table(临时表);②从源表复制行数据;③重演binlog日志到ghost table;④用临时表替换源表。

特性

  • 无触发器

不像Percona的pt-online-schema-change、 Facebook的 OSC 和 LHM  都是基于触发器。gh-ost是基于binlog来监听表中的数据变更。所以它是异步的,只有源表的数据被提交后才会将变更同步到ghost table(临时表)

  • 轻量级(无侵入)

同样得益于没有无触发器的好处,无需创建触发器,基于binlog重演,同步数据。

  • 可暂停
  • 可动态控制
  • 执行操作的过程中发现负载上升了,gh-ost可以通过Unix socket文件或者tcp端口(可配置)的方式来监听请求。

操作者可以在命令运行后更改相应的参数,参考下面的例子:

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

#修改限速参数
echo chunk-size=100 | socat - /tmp/gh-ost.t1.sock
echo max-lag-millis=200 | socat - /tmp/gh-ost.t1.sock
echo max-load=Thread_running=3 | socat - /tmp/gh-ost.t1.sock

 

  • 可审计
  • 可测试
  • 值得信赖

操作模式(三种)

1)连接到从库,在主库上做迁移(DDL)(默认的方式

  • 源表历史数据复制到ghost table在主库进行读写;
  • 变更从库的二进制日志(binlog),将数据的新变更应用到主库ghost table;
  • 在从库收集表格式、字段、行数等信息
  • 在从库内部读取变更事件(如心跳时间)
  • 在主库切换表(ghost table rename成源表名)

2)连接到主库,在主库做迁移

数据复制、binlog重演、切表都是在主库上执行。此时需要持续关注复制延迟的问题

前提:①主库的二进制日志必须是RBR格式;②必须制定--allow-on-master参数;

3)在从库迁移/测试

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

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

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

各个工具对比

常用在线DDL的工具,还有pecorna pt-osc。两者对比主要如下:

 优点缺点
pt-osc并发DML支持较好基于触发器,对库的性能有一定影响
gh-ost对主机性能几乎没有影响,而且可控制,而且是基于binlog,不急于trigger对源表有一定要求,比如不支持外键;要求binlog为row格式;

 

 

 

 

实践

1.登录堡垒机(操作生产环境)

2.构建批量生成的gh-ost脚本的 shell脚本文件

[appdeploy@********:/app/lry/onlineddl]$cat online_mcs_ords_task.sh
#!/bin/bash
echo ===partions====
>online_task.txt
ct=1000000000
cat dbmcsords | while read line
do
let ct++ 
i=`echo $line|awk '{print $1}'`
j=`echo $line|awk '{print $2}'`
echo $i $j $ct
echo "nohup /app/mysql-onlineddl-gh/gh-ost --host=$i --port=3306 --user='ghost' --password='******** --allow-on-master --database='"$j"' --table='tt_bar_record_escale_task' --alter='ADD COLUMN EXTEND_ATTACH_EXT mediumtext NULL COMMENT \"新统一扩展字段\" AFTER EXTEND_ATTACH_34;' --max-load=Threads_running=30 --critical-load=Threads_running=1000 --chunk-size=1000 --initially-drop-ghost-table --initially-drop-old-table --timestamp-old-table --cut-over=default --exact-rowcount --concurrent-rowcount --replica-server-id=$ct --execute >$j.log 2>&1 &" >> online_task.txt
echo "" >> online_task.txt
done

选项注释:

--allow-on-master

针对mater节点做操作。更好的时间是针对slave或者replica操作

-alter string

alter语句(必填)

-max-load string

Comma delimited status-name=threshold. e.g: 'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes

-critical-load string

Comma delimited status-name=threshold, same format as --max-load. When status exceeds threshold, app panics and quits

-chunk-size int

amount of rows to handle in each iteration (allowed range: 100-100,000) (default 1000)

-initially-drop-ghost-table

Drop a possibly existing Ghost table (remains from a previous run?) before beginning operation. Default is to panic and abort if such table exists

--initially-drop-old-table

Drop a possibly existing OLD table (remains from a previous run?) before beginning operation. Default is to panic and abort if such table exists

--timestamp-old-table

Use a timestamp in old table name. This makes old table names unique and non conflicting cross migrations

-cut-over string

choose cut-over type (default|atomic, two-step) (default "atomic")

-exact-rowcount

精确计算行数。actually count table rows as opposed to estimate them (results in more accurate progress estimation)

-concurrent-rowcount

(with --exact-rowcount), when true (default): count rows after row-copy begins, concurrently, and adjust row estimate later on; when false: first count rows, then start row copy (default true)

-replica-server-id uint

server id used by gh-ost process. Default: 99999 (default 99999)

-execute

actually execute the alter & migrate the table. Default is noop: do some tests and exit

3.分批执行online_task.txt的脚本(每次尽量少点,比如40G的表,同时执行10个左右)。

4.jobs命令查看online  DDL执行情况

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值