美文网首页Java 程序员方案Java
我们是如何优雅修改正式环境的表结构,而不影响线上运行的?

我们是如何优雅修改正式环境的表结构,而不影响线上运行的?

作者: 程序花生 | 来源:发表于2021-08-07 16:36 被阅读0次

    文中案例说明

    需要在大表中添加一个字段group_id,表中有个1千万的数据量,而且有几个索引字段,如果直接在客户端通过sql ALTER TABLE h_app_message ADD group_id bigint(20) 会造成数据库卡顿,耗费时间很长,直接影响线上正常使用。

    一般对于较大数据量的修改方式,如果线上并发不是很高的情况下是可以手动处理的,方式如下:

    • 首先备份,备份,备份,重要的事情说三遍
    • 删除表中的索引
    • 修改表结构
    • 修复数据
    • 恢复索引
    • 表结构修改完成

    我们的处理方式是通过pt-online-schame-change 工具在线修改正式环境的字段,添加group_id。

    此工具的好处:

    • 降低主从延时的风险
    • 可以限速、限资源,避免操作时MySQL负载过高

    建议:

    在业务低峰期做,将影响降到最低

    直接原表修改缺点:

    当表的数据量很大的时候,如果直接在线修改表结构,严重影响线上环境,而且耗时不可预估

    注意:

    • 需要确认表必须包含主键或者唯一索引
    • 工具会创建触发器,所以原表上不能有触发器
    • 有外键的表需要注意使用参数--alter-foreign-keys-method(现在业务上不建议表中外键关联,建议在业务中控制)

    原理:

    • 首先它会新建一张一模一样的表,表名一般是_new后缀
    • 然后在这个新表执行更改字段操作
    • 然后在原表上加三个触发器,DELETE/UPDATE/INSERT,将原表中要执行的语句也在新表中执行
    • 最后将原表的数据拷贝到新表中,然后替换掉原表

    1、数据备份

    无论操作多么有把握,也要把备份做好(万一很可怕的)

    2、安装

    下载安装包:

    wget  https://downloads.percona.com/downloads/percona-toolkit/3.3.1/source/tarball/percona-toolkit-3.3.1.tar.gz
    

    解压:

    tar -xvf percona-toolkit-3.3.1.tar.gz
    

    安装一些依赖包:

    yum install perl-DBIyum install perl-DBD-MySQLyum install perl-Time-HiResyum install perl-IO-Socket-SSLyum -y install perl-Digest-MD5
    

    3、测试可用

    在解压包的bin目录下执行,看是否正常,查看命令

    ./pt-online-schema-change --help
    

    4、参数字段及含义

    5、具体操作

    1. 添加一个字段

    如果执行失败,检查alter语句,如果确认无误 可以避免检查 --no-check-alter

    ./pt-online-schema-change --user=xxxx --password=xxxx --host=xxx.xxx.xxx.xxxx --alter "add column group_id bigint(20) not NULL default '0' comment 'test' " P=30306,D=h_pushcenter,t=h_message --charset=utf8 --no-version-check --print --execute
    

    2. 修改字段

    sql语句:

    ALTER TABLE `h_message` MODIFY COLUMN `group_id` int(20)  NOT NULL DEFAULT '1';ALTER TABLE `h_message` MODIFY COLUMN `group_id` int(20)  NOT NULL DEFAULT '1';
    

    pt命令:

    --alter "MODIFY COLUMN group_id int(20) NOT NULL DEFAULT '1'"
    

    3. 修改字段名

    sql语句:

    ALTER TABLE `h_message` CHANGE column group_id group_id_0 bigint(20);
    

    pt命令:

    --alter "CHANGE group_id group_id_0 bigint(20)"
    

    4. 添加索引

    sql语句:

    ALTER TABLE `h_message` ADD INDEX h_message_n1(group_id);
    

    pt命令:

    --alter "ADD INDEX h_message_n1(group_id)"
    

    6、操作日志

    • 创建new结尾的新表
    Creating new table...
    CREATE TABLE `h_pushcenter`.`_h_message_new` .....
    Created new table h_pushcenter._h_message_new OK.
    
    • 新表执行alter操作
    Altering new table...
    ALTER TABLE `h_pushcenter`.`_h_message_new` add column  group_id bigint(20) not NULL default '0'  comment 'test'
    Altered `h_pushcenter`.`_h_message_new` OK.
    
    • 原表上创建3个触发器
    Creating triggers...
    Event : DELETE
    Event : UPDATE
    Event : INSERT
    Created triggers OK.
    
    • 复制数据到新表
    Copying approximately 8187 rows...
    Copied rows OK.
    
    • 重命名新旧两个表,然后替换,删除旧表
    2021-05-19T10:33:08 Swapping tables...
    RENAME TABLE `h_pushcenter`.`h_message` TO `h_pushcenter`.`_h_message_old`, `h_pushcenter`.`_h_message_new` TO `h_pushcenter`.`h_message`
    2021-05-19T10:33:09 Swapped original and new tables OK.
    2021-05-19T10:33:09 Dropping old table...
    DROP TABLE IF EXISTS `h_pushcenter`.`_h_message_old`
    2021-05-19T10:33:09 Dropped old table `h_pushcenter`.`_h_message_old` OK.
    
    • 删除触发器
    2021-05-19T10:33:09 Dropping triggers...
    DROP TRIGGER IF EXISTS `h_pushcenter`.`pt_osc_h_pushcenter_h_message_del`
    DROP TRIGGER IF EXISTS `h_pushcenter`.`pt_osc_h_pushcenter_h_message_upd`
    DROP TRIGGER IF EXISTS `h_pushcenter`.`pt_osc_h_pushcenter_h_message_ins`
    2021-05-19T10:33:09 Dropped triggers OK.
    
    • 打完收工

    作者:纪先生
    链接:https://juejin.cn/post/6993339537824940046
    来源:掘金

    相关文章

      网友评论

        本文标题:我们是如何优雅修改正式环境的表结构,而不影响线上运行的?

        本文链接:https://www.haomeiwen.com/subject/epkgvltx.html