Write by lyc at 2019-10-30
参考博文:
在线更改MySQL表结构工具pt-online-schema-change
pt-online-schema-change使用说明、限制与比较
pt-online-schema-change的原理解析与应用说明
一、pt-online-schema-change 介绍
1.pt-osc 特点
percona-toolkit
里带的工具,安装percona-toolkit
即可
- 在线执行DDL操作,不会阻塞读写操作
- 选择业务低谷时操作,操作前先备份数据
- 操作前确认该表没有未提交的大事务或者慢查询
2.pt-osc 使用限制
- 如果修改表有外键,除非使用
--alter-foreign-keys-method
指定特定的值,否则工具不予执行
- 被修改表必须要有主键或者唯一索引,否则报错
- 被修改表上不能有针对after delete|insert|update三个触发器,否则修改表结构操作失败
3. pt-osc 工作原理
- 创建一个和要执行
Alter
操作的表一样的新的空表结构(是alter之前的结构),新表名为tablename_new
- 在新表执行
Alter TABLE
语句
- 在原表中创建触发器3个触发器分别对应insert,update,delete操作
- 以一定块大小从原表拷贝数据到临时表,拷贝过程中通过原表上的触发器在原表进行的写操作都会更新到新建的临时表
RENAME
原表成old表,再新的临时表RENAME
为原表名
- 默认最后将旧原表删除,删除触发器
- 另外如果存在外键,根据
alter-foreign-keys-method
参数的值,检测外键相关的表,做相应设置的处理。
二、pt-online-schema-change 参数
1.基础参数
--user
mysql用户名
--password
mysql用户密码
--host
数据库ip
--port
数据库端口号
--socket
数据库socket文件
--alter
DDL语句,省略ALTER TABLE table_name
关键字后面的SQL
D=database,t=table_name
要操作DDL的库名,表名
--check-replication-filters
检查复制中是否设置了过滤条件,如果设置了,程序将退出
--no-check-replication-filters
不检查复制中是否设置了过滤条件
--alter-foreign-keys-method
2.主从延迟参数
--recursion-method=
master寻找slave的方式
none
主从环境,不在乎从的延迟
processlist
使用SHOW PROCESSLIST;
命令查找从库 hosts
hosts
使用SHOW SLAVE HOSTS;
命令查找从库
dsn=DSN
使用表格 tdsn存储从库信息,需要手动在需要DDL的数据库内创建固定表格
--max-lag
默认1s 检查从库延迟的时间,如果超过,则停止copy data,休息--check-interval
秒后,再重新开始copy数据。查看通过延迟时间,是通过从库show slave status;
,查看Seconds_Behind_Master 如果指定--check-slave-lag
,该工具只检查该服务器的延迟,而不是所有服务器。
--check-interval
从库延迟超过指定的--max-lag
,中断copy data休息的时间 默认为1s
--max-load
copy data的过程,监控数据库当前正在运行的thread,如果超过指定的Threads_running
值,则停止拷贝数据,会在输出的内容中答应 Pausing because Threads_runing=15,直到运行的线程数小于给定的值,恢复copy data,如此循环,直到拷贝数据结束。 Threads_runing默认为25 举例:--max-load=Thread_running=15
3.输出与执行参数
--print
详细打印alter过程,不指定的时候,简略打印
--dry-run
创建和修改新表,但不会创建触发器、复制数据、和替换原表。并不真正执行,可以看到生成的执行语句,了解其执行步骤与细节,和–print配合最佳。。
--execute
确定修改表,则指定该参数。真正执行alter。–dry-run与–execute必须指定一个,二者相互排斥
三、执行在线DDL(不考虑外键、不考虑从库延迟)
修改表引擎
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ /usr/local/bin/pt-online-schema-change \ --user=root \ --password=123456 \ --host=xxx.xxx.xxx.xxx \ --port=3306 \ --charset=utf8 \ --alter "ENGINE=InnoDB" \ D=db_name,t=tb_name \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
修改表行格式(开启压缩)
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --host=xxx.xxx.xxx.xxx \ --port=3306 \ --charset=utf8 \ --alter "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8" \ D=db_name,t=tb_name \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
增加字段
1 2 3 4 5 6 7 8 9 10 11 12
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --socket=/data/mysql_data_3306/mysql_3306.sock \ --charset=utf8 \ --alter "ADD COLUMN test_column INT(11) DEFAULT 0 NULL COMMENT '测试加字段' AFTER StatDateInt" \ D=database_name,t=table_name \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
删除字段
1 2 3 4 5 6 7 8 9 10 11 12
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --socket=/data/mysql_data_3306/mysql_3306.sock \ --charset=utf8 \ --alter "DROP COLUMN test_column" \ D=database_name,t=table_name \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
修改字段类型
1 2 3 4 5 6 7 8 9 10 11 12
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --socket=/data/mysql_data_3306/mysql_3306.sock \ --charset=utf8 \ --alter "modify column test_column char(11)" \ D=database_name,t=table_name \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
字段改名
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --socket=/data/mysql_data_3306/mysql_3306.sock \ --charset=utf8 \ --alter "CHANGE COLUMN test_column test_column_new char(11)" \ D=database_name,t=table_name \ --no-check-alter \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execut
|
创建索引
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --socket=/data/mysql_data_3306/mysql_3306.sock \ --charset=utf8 \ --alter "ADD INDEX Index_test_column_new(test_column_new)" \ D=database_name,t=table_name \ --no-check-alter \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
删除索引
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ pt-online-schema-change \ --user=root \ --password=123456 \ --socket=/data/mysql_data_3306/mysql_3306.sock \ --charset=utf8 \ --alter "DROP INDEX Index_test_column_new" \ D=database_name,t=table_name \ --no-check-alter \ --no-check-replication-filters \ --alter-foreign-keys-method=auto \ --recursion-method=none \ --print \ --execute
|
四、执行在线DDL(不考虑外键、考虑从库延迟)
1.创建表格dsns,记录从库信息(2*slave+)
- 2个及以上从库考虑使用 dsns表格来记录从库信息。
- 1个从库可以直接使用参数
--check-slave-lag
指定从库
1 2 3 4 5 6 7 8 9 10 11
| 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 into dsns(dsn) select "h=192.168.100.170,u=slave,p=TVKIYZ93n53RciV0yCHwygew,P=3306"; insert into dsns(dsn) select "h=192.168.100.172,u=slave,p=TVKIYZ93n53RciV0yCHwygew,P=3306";
|