在运维线上MySQL数据库时,我们总会对数据表进行 DDL 变更,修改添加字段或者索引。在对表进行 DDL 时,会锁表,当表比较小比如小于1w上时,对前端影响较小,当时遇到千万级别的表就会影响前端应用对表的写操作。

pt-online-schema-change 是 percona 公司开发的一个工具,在percona-toolkit包里面可以找到这个功能,它是一个在线DDL工具,可以实现在线数据表 DDL 操作。

使用方法
比如需要运行 SQL 的 DDL 语句

ADD COLUMN mode tinyint(4) DEFAULT NULL AFTER status

可以通过如下命令进行

nohup pt-online-schema-change \
    --charset=utf8 \
    --no-version-check \
    --user="数据库用户" \
    --password="数据库密码" \
    --host="数据库地址" \
    P=3306,D="数据库",t="数据表" \
    --alter "ADD COLUMN mode tinyint(4) DEFAULT NULL AFTER status" \
    --execute &

参数说明

--user=        连接mysql的用户名
--password=    连接mysql的密码
--host=        连接mysql的地址
P=3306         连接mysql的端口号
D=             连接mysql的库名
t=             连接mysql的表名
--alter        修改表结构的语句
--execute      执行修改表结构
--charset=utf8 使用utf8编码,避免中文乱码
--no-version-check  不检查版本,在阿里云服务器中一般加入此参数,否则会报错

工作过程
创建一个和要执行 alter 操作的表一样的新的空表结构(是 alter 之前的结构)

在新表执行 alter table 语句(速度应该很快)

在原表中创建触发器 3 个触发器分别对应 insert, update, delete 操作

以一定块大小从原表拷贝数据到临时表,拷贝过程中通过原表上的触发器在原表进行的写操作都会更新到新建的临时表

Rename 原表到 old 表中,在把临时表 Rename 为原表

如果有参考该表的外键,根据 alter-foreign-keys-method 参数的值,检测外键相关的表,做相应设置的处理

默认最后将旧原表删除

安装方法
仅供参考(CentOS 7 验证)


sudo yum install -y perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5 perl-TermReadKey.x86_64
sudo rpm -ivh percona-toolkit-3.1.0-2.el7.x86_64.rpm

参考资料
https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html

03-05 16:26