传统方法修改表结构 类似alter table xx modify,在修改表结构时需要锁表,如果表很大,则操作时间会较长。目前,绝大多数业务要求24*7无间断服务,而此过程中,如果造成较长时间数据库无法更新,则会严重影响业务。最近了解到两种可行的方案:1.替换表结构方法,2.采用percona在线修改表结构工具
mysql5.6.25(mysql5.6相对于mysql5.5已经改进很多了,在mysql5.6中参考了percona-toolkit,增加删除索引不会锁表,同一个session里面,增删查改也不受影响,但是不同session是会受影响的。)
1)、如果修改表有外键,除非使用 --alter-foreign-keys-method 指定特定的值,否则工具不予执行
2)、被修改表必须要有主键,否则报错:Cannot chunk the original table `houyi`.`ga`: There is no good index and the table is oversized. at ./pt-online-schema-change line 5353.
3)、被修改表上不能有针对after delete|insert|update三个触发器,否则修改表结构操作失败
PERCONA提供了若干管理维护MySQL的小工具,集成在 PERCONA Toolkit工具中,有慢查询分析、主从差异对比、主从差异修复及在线表结构修改等工具, 本文简单介绍 pt-online-schema-change 工具。
表格必须带有主键或者唯一索引!!
假设现有tbosc需要做ALTER操作,使用pt-online-schema-change的时候,根据tbddl表结构及索引情况,创建一个新的空表_tbosc_new,然后从原始表格 tbosc 中拷贝数据到新的表格 _tbosc_new,copy data结束后,使用_tbosc_new替换tbddl,同时,删除旧表。
简单流程如上描述,那么详细流程是怎么样的呢?
带着这几个问题来了解:
如何查看其详细的执行流程呢?数据库开启general log,然后执行pt-online-schema-change,它对数据库的所有操作,就都呈现在眼前。
详细执行流程如下:
根据其执行流程,可以对一开始的提问一 一来解答。
工具包下载网页:https://www.percona.com/downloads/percona-toolkit/LATEST/ (目前最新版本为3.0.2)
rpm下载地址:https://www.percona.com/downloads/percona-toolkit/3.0.2/binary/redhat/7/x86_64/percona-toolkit-3.0.2-1.el7.x86_64.rpm
官方使用说明文档地址: https://www.percona.com/doc/percona-toolkit/LATEST/index.html
环境安装依赖项目: Perl, DBI, DBD::mysql
安装非常简单,在安装好相关的环境依赖项后,执行rpm安装即可
rpm -ivh percona-toolkit-3.0.2-1.el7.x86_64.rpm
常规情况,如果有被外键引用的表格,注意对--alter-foreign-keys-method的设置,本小节不考虑从库延迟情况及外键情况。
pt-online-schema-change也支持同个表格的多个SQL合并为一个SQL,由于所有DDL都是采用COPY TABLE TO NEW TABLE方式,所以使用的时候,不需要对DDL SQL做分类。
1 CREATE TABLE `tbosc` ( 2 `id` int(11) NOT NULL AUTO_INCREMENT, 3 `name` varchar(100) DEFAULT NULL, 4 `age` int(11) DEFAULT NULL, 5 PRIMARY KEY (`id`) 6 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 7 8 #添加列 9 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "add column stunum int " --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 10 11 #删除列 12 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "drop column stunum " --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 13 14 #修改列数据类型 15 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "modify column age varchar(10)" --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 16 17 #加大列长度 18 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "modify column age varchar(100)" --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 19 20 #创建索引 21 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "ADD INDEX IX_AGE(AGE)" --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 22 23 #删除索引 24 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "DROP INDEX IX_AGE" --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 25 26 #设置默认值 27 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "ALTER column age SET DEFAULT 100" --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute 28 29 #能否多个合成一个 30 pt-online-schema-change --socket=/tmp/mysql3310.sock --user=root --password=ycf.com D=dbosc,t=tbosc --alter "ADD COLUMN onecol int ,add column twocol varchar(100),add index ix_onecol(onecol),alter column name set default ‘xinysu‘ " --recursion-method=none --no-check-replication-filters --alter-foreign-keys-method auto --print --execute
考虑从库延迟情况 ,意味这要注意这几个选项的设置
从库延迟超过max-lag则停止copy data,等待 check-interval 秒后再开始copy data。check-slave-lag指定slave的机器,只会对比这台slave的延迟情况。recursion-method是主库寻找从库的方法,有四个方法:processlist,hosts,dsn,none,具体查看上部分选项详细说明,本节详细描述dsn及check-slave-lag的使用。
假设需要在dbosc库上的表格tbddl添加一列:hobby varchar(100) ,需要考虑从库的延迟情况
#创建表格dsns,记录从库信息
CREATE TABLE `dsns` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
#insert从库信息,有2个从库,分别为242服务器上的 3310跟3320
insert into dsns(dsn) select "h=192.168.9.244,u=repl,p=****,P=3310";
insert into dsns(dsn) select "h=192.168.9.244,u=repl,p=****,P=3320";
如果需要考虑多个从库的延迟情况,则可以考虑使用 dsns表格来记录从库信息,如果只需要考虑某一台从库的延迟情况,则既可以使用dsns表格也可以使用参数--check-slave-lag指定从库。
不考虑外键关系,考虑从库影响程度,检查到从库延迟超过1s,则休息5s,具体指令如下
pt-online-schema-change -P3310 --user=root --password=ycf.com D=dbosc,t=tbddl --max-lag=1s --check-interval=10s --alter "ADD hobby varchar(100) NOT NULL DEFAULT ‘sleep‘ " --recursion-method dsn=D=dbosc,t=dsns --alter-foreign-keys-method auto --execute
如果检测到slave的 Seconds_Behind_Master超过1s,则会休息10s后再监测,这个过程会在输出文件中打印出:
Replica lag is 395 seconds on sutest244. Waiting.
Replica lag is 425 seconds on sutest244. Waiting.
Replica lag is 456 seconds on sutest244. Waiting.
说明现在主从延时了多少秒,现在copy线程停止,正在等待中。
如果是仅指定一个从库查看延迟情况,使用--check-slave-lag的指令如下:
pt-online-schema-change -P3310 --user=root --password=ycf.com D=dbosc,t=tbddl --max-lag=1 --check-interval=10 --check-slave-lag=h=192.168.9.244,u=root,p=ycf.com,P=3310 --alter "ADD hobby varchar(100) NOT NULL DEFAULT ‘sleep‘ " --recursion-method --alter-foreign-keys-method auto --print --execute
经过这一篇介绍pt-online-schema-change的原理说明及测试,以及上篇的online ddl说明,可明白pt-osc无论是什么DDL SQL,都会新建新表来替换,不分DDL类型,但是执行期间允许DDL操作,而ONLINE DDL则分为了好几类DDL,有的DDL仅需修改元数据,有的DDL仅需在本身ibd文件上新建索引页,有的需要rebuild table,这三种类型执行期间支持DML操作,但是COPY TABLE 类型不支持DML操作。
因此,可以有以下几个判断:
参考文档:https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html