首页 MySQL 正文
162

pt-online-schema-change 的用法

此工具要解决的问题

Alter table操作会锁表并造成读写阻塞,对于千万级别大表,持续时间可达数小时,在online情况下,势必造成服务不可用以及用户体验退化的问题。
当然,官方也有这方面的考虑,所以提供了像`ALTER ONLINE TABLE`,  `ALTER TABLE ..., ALGORITHM=INSTANT, LOCK=NONE`这样的命令来解决在线更新表结构的问题。
但是,官方提供的方法,在某些场景下不起作用,比如修改字段,修改索引,添加索引等。 这时候就需要用到第三方工具 pt-online-schema-change 了。

原理,风险,局限性

操作前请认真阅读官方文档

如何操作

比如删除demoTable的索引myIndex (**其实删除索引不需要用此工具,使用**`ALTER TABLE tripadvisor_reviews DROP INDEX locationId, ALGORITHM=INPLACE;`**速度非常快**)


- 先用--dry-run验证命令合法性

`pt-online-schema-change --socket=/run/mysqld/mysqld.sock --alter "DROP INDEX myIndex" D=demoDB, t=demoTable --print --dry-run`

- 通过验证后再用--execute代替--dry-run落地执行

`pt-online-schema-change --socket=/run/mysqld/mysqld.sock --alter "DROP INDEX myIndex" D=demoDB, t=demoTable --print --execute`

修改改字段示例:

`pt-online-schema-change --socket=/run/mysqld/mysqld.sock --alter "CHANGE myfield myfield VARCHAR(5) NOT NULL DEFAULT ''" D=demoDB,t=demoTable --print --dry-run`

添加字段与索引示例:

`pt-online-schema-change --socket=/run/mysqld/mysqld.sock --alter "ADD myfieldCHAR(5) NOT NULL DEFAULT '', ADD INDEX(myfield)" D=demoDB,t=demoTable --print --dry-run`

修改引擎: 

`pt-online-schema-change --alter "ENGINE=InnoDB" D=demoDB, t=demoTable --dry-run`

删除字段: 

`pt-online-schema-change --alter "DROP myColumn" D=demoDB, t=demoTable --dry-run`


由于此工具需要在原始表上创建triggers,所以当原始表本身含有triggers时要如下处理:
1. mysql5.7.1及以下版本(MariaDB 10.2.2)只支持一个event对应一个trigger, 那么必须得删除原始表的triggers, 待数据copy结束之后,重新在新表上手动创建这些triggers.
2. mysql5.7.2及以上版本(MariaDb 10.2.3)支持一个event对应多个triggers, 那么在运行此工具时加上参数`--preserve-triggers` 即可


此工具运行耗时长,建议使用screen开启虚拟终端,在虚拟终端中执行它。

#

#附:screen用法


`screen -R myTermi`   #开启一个名为myTermi的终端,如果存在就直接进入

`screen -S myTermi`   #开启一个名为myTermi的虚拟终端,有可能重名

**进入虚拟终端之后,如果要回到主终端,有两种情况:**

- 退出终端,但保持后台运行: `ctrl+a` 再按 `d`

- 退出终端不保持后台运行:`ctrl+a` 再按 `k`.  (在虚拟终端中输入exit一样的效果)

**重新回到虚拟终端的方法:**

- 先使用`screen -ls` 查看已创建的虚拟终端(结果的第一列是由Pid和name组成)

- 使用`screen -r/-R [Pid/name]` 都可以回到虚拟终端,但这对于状态为Detached的虚拟终端才有用。

- 如果虚拟终端的状态是Attached(比如网络中断导致没有使用ctr+a, d命令退出), 那么使用 -R 并不能重新进入,而是会新创建一个同名虚拟终端。 -r 也无法进入。

- 此时需要使用 `screen -d [pid/name]`将对应的Attached状态变为Detached状态就可以了。


**如何检测是否在虚拟终端中**


- 方法一,在screen session中 使用命令`echo $STY`, 它会输出screen session的名字,否则是空值


- 方法二,`ctrl + a` 再 `ctrl + t`, 如果在screen session中它会输出日期,否则没有任何反应。



正在加载评论...