暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

pt-online-schema-change使用方法

原创 谭磊Terry 恩墨学院 2022-06-19
2286

工作原理

  • 如果存在外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,做相应设置的处理。没有使用 --alter-foreign-keys-method=rebuild_constraints 指定特定的值,该工具不予执行
  • 创建一个和源表表结构相同的表(table_new),执行alter修改临时表结构
  • 在原表上创建三个触发器,insert,delete,udpate对应的触发器,(用于copy数据的过程中,在原表的更新操作更新到新表)
  • 从原表拷贝数据到新表,拷贝过程中在原表的写操作都会更新到新建的临时表
  • 修改外键相关的子表,根据修改后的数据,修改外键关联的子表
  • rename源数据表为old,把新表rename为源表明,并将old表删除
  • 删除触发器

执行条件

  • 操作的表必须有主键或者唯一索引,否则报错
  • 该表不能定义触发器,否则报错

用法介绍

pt-online-schema-change --host=ip --port=3307 --user=username --password='xxxx' D=db_name,t=table_name --alter="modify order_id bigint(20) COMMENT '订单id';" --critical-load="Threads_running=50" --nocheck-replication-filters --nodrop-old-table --charset=utf8mb4 --execute

pt-online-schema-change --alter="ADD AuthId VARCHAR(32) NOT NULL DEFAULT '' COMMENT '鉴权ID' AFTER Id;" \
--host=127.0.0.1 --user=root --port=3306 --ask-pass --charset=utf8 --check-interval 5 \
--max-lag 2 --drop-old-table --nocheck-replication-filters --chunk-time 1 \
--max-load="Threads_connected=500,Threads_running=50" \
--critical-load="Threads_connected=800,Threads_running=100" \
--set-vars="lock_wait_timeout=20" --tries create_triggers:1:1,drop_triggers:3:1,swap_tables:3:1 \
--progress=time,5 --no-check-alter --execute --print D=risk,t=event

重要参数

  • --dry-run 创建并修改新表,但不创建触发器,也不复制表,或者替换原表,与--execute互斥
  • --execute 这个参数的作用和前面工作原理的介绍的一样,会建立触发器,来保证最新变更的数据会影响至新表。注意:如果不加这个参数,这个工具会在执行一些检查后退出
  • --critical-load 每次chunk操作前后,会根据show global status统计指定的状态量的变化,默认是统计Thread_running。目的是为了安全,防止原始表上的触发器引起负载过高。这也是为了防止在线DDL对线上的影响。超过设置的阀值,就会终止操作,在线DDL就会中断。提示的异常如上报错信息
  • --max-load 选项定义一个阀值,在每次chunk操作后,查看show global status状态值是否高于指定的阀值。该参数接受一个mysql status状态变量以及一个阀值,如果没有给定阀值,则定义一个阀值为为高于当前值的20%。注意这个参数不会像--critical-load终止操作,而只是暂停操作。当status值低于阀值时,则继续往下操作。是暂停还是终止操作这是--max-load和--critical-load的差别。
  • --charset=utf8 连接到MySQL后运行SET NAMES UTF8
  • --check-slave-lag 检查主从延迟
  • --check-replication-filters 检查复制中是否设置了过滤条件,如果设置了,程序将退出
  • --nocheck-replication-filters不检查复制中是否设置了过滤条件
  • --set-vars 设置mysql的变量值
  • --sleep 每个chunk导入后与下一次chunk导入开始前sleep一会,sleep时间越长,对于磁盘IO的冲击就越小
  • --[no]drop-old-table rename新表后drop旧表,可以no-xxx来保留旧表
  • --[no]drop-new-table 如果复制原表失败则删除新表; 也可以no-xxx来保留新表
  • --chunk-size chunk的行数,默认1000
  • --chunk-index-columns 有复合索引的时候,指定索引列
  • --critical-load 默认Threads_running=50; 每次chunk执行后会自动用SHOW GLOBAL STATUS检查负载情况,如果超过阈值则放弃;
  • --execute 执行操作 与 --dry-run互斥
  • --force 强制运行,可能打破外键约束
  • --skip-check-slave-lag 检查SLAVE的时候,指定该SLAVE跳过;
  • --print 将会显示工具执行的命令
  • --null-to-not-null 修改允许null值为not null
  • --preserve-triggers 保留原表的触发器,不删除
  • --max-lag 默认1s, 如果主从延时的时间超过这个值,则复制会暂停"--check-interval"秒时间;然后再检查,直到主从延时小于该值;如果指定了"--check-slave-lag",则只会检查指定slave延时,而不是检查所有slave;如果有任何SLAVE stop了,那么工具会一直等待下去;每次停止的时候都会打印报告
  • --ask-pass 连接的时候会要求提供密码
  • --recursion-method
    master寻找slave的方法,默认值为processlist,hosts
(1)processlist是默认的,因为show slave status不太靠谱。

(2)如果服务器使用非3306端口时,hosts方法也很好

(3)dsn=DSN方法使用时,需要先去库里创建一个表,比如在percona库中建一个dnsn表

建表语句是: 

CREATE TABLE `dsns` (`id` int(11) NOT NULL AUTO_INCREMENT,`parent_id` int(11) DEFAULT NULL,`dsn` varchar(255) NOT NULL,PRIMARY KEY (`id`));
    建好后插入主从复制信息数据,如:insert into table dsns(dsn) values(h=slave_host,u=repl_user,p=repl_password,P=port );

    然后就可以使用DSN方法了:命令为:--recursion-method dsn=D=percona,t=dsns.

(4)如果想只监控hosts10.10.1.16 and 10.10.1.17的复制延迟情况,可以将h=10.10.1.16 and h=10.10.1.17的相关内容存入‘dsns’的表中来精确指定
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论