持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
前言
当我们的表数据量特别大,并且是生产环境
同时因为业务的改动,我们需要变更表字段或者新增字段的话,该怎么办?
本文介绍的pt-online-schema-change工具即可应对该场景:
在 mysql 5.6 版本以前,修改表结构如添加索引、修改列,需要锁表,期间不能写入,对于一个有几千万数据的大表来说,这个简直不能接收,对于分秒必争的互联网时代,服务中断很长时间的后果是很严重的。
升级Mysql 到5.6 版本后,情况会好转,支持online-DDL, 但是实际在Alter表的时候,还会有可能锁表。
pt-online-schema-change是Percona-toolkit一员, 支持在不锁表的情况下,在线改表。
1. pt-online-schema-change 工具介绍与使用
1.1 原理
- 建立一个与需要操作的表相同表结构的空表
- 给空表执行表结构修改
- 在原表上增加delete/update/insert的after trigger
- copy数据到新表
- 将原表改名,并将新表改成原表名
- 删除原表
- 删除trigger
1.2 pt-osc限制条件:
- 表要有主键,否则会报错;
- 表不能有trigger;
1.3 下载
1.4 安装
tar -zxvf percona-toolkit.tar.gz
cd percona-toolkit-3.0.4
perl Makefile.PL
(若执行Makefile出错 则需先执行yum install perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker)
make
make test
make install
1.5 使用方法
pt-online-schema-change --help 可查看参数帮助
#!/bin/bash
dbconn=$1
username=$2
passwd=$3
addordrop=$4
add () {
for i in {0..99}
do
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "ADD COLUMN tmp int(11) NULL" P=3306,D=trade,t="ay_trade_main_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "ADD COLUMN tmp int(11) NULL" P=3306,D=trade,t="ay_trade_payment_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "ADD COLUMN tmp int(11) NULL" P=3306,D=trade,t="ay_trade_sub_order_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "ADD COLUMN tmp int(11) NULL" P=3306,D=trade,t="ay_trade_consign_logistics_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "ADD COLUMN tmp int(11) NULL" P=3306,D=trade,t="ay_trade_ext_taobao_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "ADD COLUMN tmp int(11) NULL" P=3306,D=trade,t="ay_trade_invoice_idinfo_$i" --execute >> /data/srv/sql/pt.log
done
}
drop () {
for i in {0..99}
do
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "DROP COLUMN tmp" P=3306,D=trade,t="ay_trade_main_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "DROP COLUMN tmp" P=3306,D=trade,t="ay_trade_payment_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "DROP COLUMN tmp" P=3306,D=trade,t="ay_trade_sub_order_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "DROP COLUMN tmp" P=3306,D=trade,t="ay_trade_consign_logistics_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "DROP COLUMN tmp" P=3306,D=trade,t="ay_trade_ext_taobao_$i" --execute >> /data/srv/sql/pt.log
/usr/local/bin/pt-online-schema-change --charset=utf8 --no-version-check --host=$1 -u$2 -p$3 --alter "DROP COLUMN tmp" P=3306,D=trade,t="ay_trade_invoice_idinfo_$i" --execute >> /data/srv/sql/pt.log
done
}
case ${addordrop} in
"add" )
add ${dbconn} ${username} ${passwd}
;;
"drop" )
drop ${dbconn} ${username} ${passwd}
;;
* )
echo "参数不正确"
exit 0
esac