percona toolkit系列(pt-osc)

背景

Mysql对应大数据量的表结构更改,可选用pt-online-schema-change或是gh-ost 或者5.7版本以上可Online DDL 不管使用那种方式,请阅读使用限制和进行命令测试,并且在备份相应数据表之后再在业务低峰期执行更改。

写在前面
本次使用的是线下测试库,Mysql5.7.26,数据表test110 ,100W行 工具版本为pt-online-schema-change 3.2.1 对应下面命令的使用前请先复制到本地进行本地化更改(里面包含多余的回车键)

添加列

请先使用--dry-run 进行添加列的测试 ;最后使用--execute 执行更改

ADD COLUMN 添加字段KefuStatus,KefuComfirmDate
pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "ADD COLUMN KefuStatus bit(1),add KefuComfirmDate datetime"  
D=test,t=test110 --dry-run

出现下图正常的显示信息后,使用--execute   执行更改
pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "ADD COLUMN KefuStatus bit(1),add KefuComfirmDate datetime"  
D=test,t=test110 --execute
执行之后,检查执行的输出信息是否正常。

测试
在这里插入图片描述
执行更改
在这里插入图片描述
在这里插入图片描述

删除字段

drop column  删除KefuStatus字段

pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "drop column KefuStatus"  D=test,t=test110 --execute

添加索引

add index   为KefuComfirmDate添加索引,名为idx_KfCD

pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "add index idx_KfCD(KefuComfirmDate)"  
D=test,t=test110 --execute

删除索引

drop index   删除idx_KfCD

pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "drop index idx_KfCD"  D=test,t=test110 --execute

修改字段允许NULL

modify column 修改KefuComfirmDate列为date null

pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "modify column KefuComfirmDate date null"  
D=test,t=test110 --execute

修改字段不允许NULL(NOT NULL)

需要通过指定选项--null-to-not-null,否则会报错。(字段类型为int,默认值为0)

modify column 修改KefuComfirmDate列为datetime not null

pt-online-schema-change -hlocalhost -port17261 --socket=/tmp/mysql_sandbox17261.sock 
-umsandbox -p123456 --alter "modify column KefuComfirmDate datetime not null" 
--null-to-not-null
D=test,t=test110 --execute

删除外键

需要为外键指定名称为_forigen_key,因为在创建新表时候默认为新表上的外键创建这样的名称,如果没这样指定则无法删除。

--alter "drop foreign key _dept_emp_ibfk_1"

重建表

--alter "engine=InnoDB"  
本地测试时,使用工具不如直接alter table test110 engine=innodb; 表碎片 Data_free: 2097152
show table status like 'test110'\G;所以可以直接alter table test110 engine=innodb;

参考文档
https://www.cnblogs.com/dbabd/p/10605629.html
link

工作流程总结:
查询当前数据库服务器信息,包括参数设置,负载信息等,判断表是否有存在触发器,是否有外键关联;
创建一张与旧表结构相同的新表,表名为_旧表名;
在新创建的表上做变更操作;
旧表上创建DELETE、UPDATE、INSERT3个触发器;
拷贝旧表数据到新表上,以chunk为单位进行,拷贝期间涉及的行会持有共享读锁;
拷贝期间如果旧表如有DML操作,则通过触发器更新同步到新表上;
当拷贝数据完成之后旧表与新表进行重命名;
如果有涉及到外键,根据工具指定选项进行外键处理;
删除旧表;
删除旧表上触发器。

如果涉及外键关联的表,优先考虑使用Online DDL。

参数

限制:
1.在绝大部分情况下表都需要有主键或者是唯一索引。因为这个工具会在运行的时候创建一个DELETE触发器,
这是为了保证在变更中新表能够与旧表保持更新一致性。值得注意的是,
如果在需要变更的列上创建主键或是唯一索引时,则会以这些列创建触发器;
2.不能使用RENAME子句为表进行重命名;
3.字段不能通过删除再重添加的方式进行重命名,这种方式是不会拷贝原字段的数到新字段上;
4.如果新增NOT NULL的列并且没有指定default值,工具就会执行失败,它并不会指定默认值;
5.涉及到删除外键时,需要指定_constraint_name,工具会在新表上创建一个前面加了下划线的外键名称,
这个外键名称与原致。如需要删除外键fk_foo,则指定'--alter "DROP FOREIGN KEY _fk_foo"'。

--alter-foreign-keys-method
采用何种方式修改外键以便关联到新表上。有外键约束的表需要被特殊处理,
为了确保外键依然能够关联到正确的表上。当工具重命名外键关联的父表时,确保外键也必须关联到重命名后的父表。
主要有以下几种方式:

`(--alter-foreign-keys-method=auto)一般使用这个`

auto:让工具自动选择使用。优先选择rebuild_constraints,如果不成功,则选择drop_swap;
rebuild_constraints:这种方式使用ALTER TABLE先删除然后重建外键关联到新父表。
这是首选的方式,如果一张或多张子表过大会导致ALTER需要很长时间,子表会被阻塞;

drop_swap:禁用外键约束(FOREIGN_KEY_CHECKS=0),在进行重命名新父表之前删除原父表,
这与常规转换旧表与新表的方式不同,这个RENAME操作是原子性的并且对应用客户端无感知。
这种方式更快速并且不会阻塞,但是也有隐患:
1.删除原父表以及重命名新表这段时间很短,如果这段时间更改子表有可能会报错;
2.如果重命名新表发生失败,而原父表已经永久删除了,这时就需要人工进行干预了。
这种方式强制使用选项'--no-swap-tables''--no-drop-old-table'。

none:这种方式类似于drop_swap,不同在于不进行swap原父表。
子表有任何外键关联父表都将变成关联一张不存在的表,这会使得子表的外键约束失效,
可以通过SHOW ENGINE INNODB STATUS查看。

--[no]analyze-before-swap
默认值:yes
在新表与旧表完成转换之前对新表执行ANALYZE TABLE操作,
默认会在MySQL5.6及之后版本并且开启innodb_stats_persistent的情况下执行。

--ask-pass
命令行提示密码输入,保护密码安全,前提需安装模块perl-TermReadKey。

--check-slave-lag
指定暂停旧表与新表的数据拷贝直到主从复制小于选项'--max-lag'指定的值。

`如果主从延迟超过1s就需要调整以下值`
--max-lag
默认值:1s
指定允许主从复制延迟时长的最大值,单位秒。如果在每次拷贝查询之后主从延迟超过指定的值,
则操作将暂停执行,暂停休眠时间为选项'--check-interval'指定的值。
待休眠时间结束之后再次检查主从延迟时长,检查方法是通过从库查询的'Seconds_Behind_Master'值来确定。
如果主从复制延迟一直大于该参数指定值或者从库停止复制,
则操作将一直等待直到从库重新启动并且延迟小于该参数指定值。

--check-interval
默认值:1s
指定因为选项'--max-lag'检查之间休眠时间。

--max-load
数组类型,默认值:Threads_running = 25
在变更拷贝完每个chunk数据之后,运行SHOW GLOBAL STATUS检查所指定变量值高于该参数指定变量的阈值时
将暂停操作。如果有多个变量阈值,可以用','(逗号)进行分隔,
参数指定型式可以为变量名=MAX_VALUE或变量名:MAX_VALUE。

如果只是指定变量名,没有为其指定阈值,则检查当前值并增加20%作为阈值。如:

    --max-load=Threads_running:没有指定具体值,以当前查询值增加20%作为阈值,如当前为100,阈值为120;
    --max-load=Threads_running:10:以当前指定值为阈值。

--null-to-not-null
指定可以将允许NULL的字段转换为NOT NULL字段。其中如有包含NULL行的字段值转换为字段默认值,
如果没有字段值,则根字段类型来分配默认值。如:字符串类型为''(空字符串),数值类型为0。

--print
打印工具执行过程中的语句到STDOUT。可以结合'--dry-run'一起使用。

–[no]check-replication-filters
默认值:yes
如果服务器指定了任何主从复制过滤选项,该工具会查询是否有复制过滤选项,一旦发现,工具都会中止并报错。

如果有主从复制并且有复制过滤,建议添加--no-check-replication-filters

本文说明,主要技术内容来自互联网技术大佬的分享,还有一些自我的加工(仅仅起到注释说明的作用)。如有相关疑问,请留言,将确认之后,执行侵权必删

猜你喜欢

转载自blog.csdn.net/baidu_34007305/article/details/110953599
今日推荐