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执行情况
标签:主库,--,Mysql,OST,ost,DDL,table,echo,gh 来源: https://blog.csdn.net/zpsimon/article/details/111665975