70.MySQL PT工具包之-pt-online-schema-change

1.工具介绍
正常情况下在线 ALTER 一个表增加一个字段、一个索引的话MySQL 会锁表 
使用pt-online-schema-change 在线更新表,不停止业务使用的在线更新表结构:在线 DDL 操作改变表结构并且不阻塞.

2.给表添加表结构。
(1)添加字段前。
mysql> desc  t2; 
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  | MUL | NULL    |       |
| name  | varchar(100) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

(2)添加字段
[root@mysql1 test]# pt-online-schema-change --user=root --host=192.168.1.51 --port=3306 --password=rootroot --execute --alter "ADD COLUMN member VARCHAR(20)" D=test,t=t2 --no-check-replication-filters
Found 1 slaves:
mysql2 -> 192.168.1.58:3306
Will check slave lag on:
mysql2 -> 192.168.1.58:3306
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
Altering `test`.`t2`...
Creating new table...
Created new table test._t2_new OK.
Altering new table...
Altered `test`.`_t2_new` OK.
2023-02-28T10:08:52 Creating triggers...
2023-02-28T10:08:52 Created triggers OK.
2023-02-28T10:08:52 Copying approximately 3 rows...
2023-02-28T10:08:52 Copied rows OK.
2023-02-28T10:08:52 Analyzing new table...
2023-02-28T10:08:52 Swapping tables...
2023-02-28T10:08:52 Swapped original and new tables OK.
2023-02-28T10:08:52 Dropping old table...
2023-02-28T10:08:52 Dropped old table `test`.`_t2_old` OK.
2023-02-28T10:08:52 Dropping triggers...
2023-02-28T10:08:52 Dropped triggers OK.
Successfully altered `test`.`t2`.
mysql> DESC t2;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id     | int(11)      | YES  | UNI | NULL    |       |
| name   | varchar(100) | YES  |     | NULL    |       |
| member | varchar(20)  | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
发现已经添加成功。


(3)更改列 
pt-online-schema-change --user=root --host=192.168.1.51 --port=3306 --password=rootroot --execute --alter "MODIFY COLUMN member VARCHAR(30)" D=test,t=t2 --no-check-replication-filters
[root@mysql1 test]# pt-online-schema-change --user=root --host=192.168.1.51 --port=3306 --password=rootroot --execute --alter "MODIFY COLUMN member VARCHAR(30)" D=test,t=t2 --no-check-replication-filters
Found 1 slaves:
mysql2 -> 192.168.1.58:3306
Will check slave lag on:
mysql2 -> 192.168.1.58:3306
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
Altering `test`.`t2`...
Creating new table...
Created new table test._t2_new OK.
Altering new table...
Altered `test`.`_t2_new` OK.
2023-02-28T10:13:41 Creating triggers...
2023-02-28T10:13:41 Created triggers OK.
2023-02-28T10:13:41 Copying approximately 3 rows...
2023-02-28T10:13:41 Copied rows OK.
2023-02-28T10:13:41 Analyzing new table...
2023-02-28T10:13:41 Swapping tables...
2023-02-28T10:13:41 Swapped original and new tables OK.
2023-02-28T10:13:41 Dropping old table...
2023-02-28T10:13:41 Dropped old table `test`.`_t2_old` OK.
2023-02-28T10:13:41 Dropping triggers...
2023-02-28T10:13:41 Dropped triggers OK.
Successfully altered `test`.`t2`.

mysql> DESC t2;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id     | int(11)      | YES  | UNI | NULL    |       |
| name   | varchar(100) | YES  |     | NULL    |       |
| member | varchar(30)  | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

发现已经修改成功。
(3)删除列 
[root@mysql1 test]# pt-online-schema-change --user=root --host=192.168.1.51 --port=3306 --password=rootroot --execute --alter "DROP COLUMN member " D=test,t=t2 --no-check-replication-filters
Found 1 slaves:
mysql2 -> 192.168.1.58:3306
Will check slave lag on:
mysql2 -> 192.168.1.58:3306
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
Altering `test`.`t2`...
Creating new table...
Created new table test._t2_new OK.
Altering new table...
Altered `test`.`_t2_new` OK.
2023-02-28T10:15:58 Creating triggers...
2023-02-28T10:15:58 Created triggers OK.
2023-02-28T10:15:58 Copying approximately 3 rows...
2023-02-28T10:15:58 Copied rows OK.
2023-02-28T10:15:58 Analyzing new table...
2023-02-28T10:15:58 Swapping tables...
2023-02-28T10:15:58 Swapped original and new tables OK.
2023-02-28T10:15:58 Dropping old table...
2023-02-28T10:15:58 Dropped old table `test`.`_t2_old` OK.
2023-02-28T10:15:58 Dropping triggers...
2023-02-28T10:15:58 Dropped triggers OK.
Successfully altered `test`.`t2`.
mysql> DESC t2;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  | UNI | NULL    |       |
| name  | varchar(100) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
删除完成。

3.pt-online-schema-change 其他用法。
(1)增加字段 content 
CREATE TABLE `test_pt` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

pt-online-schema-change --user=root --password=rootroot --host=192.168.1.51 \
--alter "ADD COLUMN content text" D=test,t=test_pt --no-check-replication-filters \
--alter-foreign-keys-method=auto --recursion-method=none --print --execute

No slaves found.  See --recursion-method if host mysql1 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
No foreign keys reference `test`.`test_pt`; ignoring --alter-foreign-keys-method.
Altering `test`.`test_pt`...
Creating new table...
CREATE TABLE `test`.`_test_pt_new` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Created new table test._test_pt_new OK.
Altering new table...
ALTER TABLE `test`.`_test_pt_new` ADD COLUMN content text
Altered `test`.`_test_pt_new` OK.
2023-02-28T10:26:54 Creating triggers...
2023-02-28T10:26:54 Created triggers OK.
2023-02-28T10:26:54 Copying approximately 1 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_test_pt_new` (`id`, `name`, `age`) SELECT `id`, `name`, `age` FROM `test`.`test_pt` LOCK IN SHARE MODE /*pt-online-schema-change 81063 copy table*/
2023-02-28T10:26:54 Copied rows OK.
2023-02-28T10:26:54 Analyzing new table...
2023-02-28T10:26:54 Swapping tables...
RENAME TABLE `test`.`test_pt` TO `test`.`_test_pt_old`, `test`.`_test_pt_new` TO `test`.`test_pt`
2023-02-28T10:26:54 Swapped original and new tables OK.
2023-02-28T10:26:54 Dropping old table...
DROP TABLE IF EXISTS `test`.`_test_pt_old`
2023-02-28T10:26:54 Dropped old table `test`.`_test_pt_old` OK.
2023-02-28T10:26:54 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_ins`
2023-02-28T10:26:54 Dropped triggers OK.
Successfully altered `test`.`test_pt`.
mysql> desc test_pt;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| name    | varchar(10) | YES  |     | NULL    |                |
| age     | int(11)     | YES  |     | NULL    |                |

| content | text        | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

(2)删除字段 
pt-online-schema-change --user=root --password=rootroot --host=192.168.1.51 \
--alter "DROP COLUMN content " D=test,t=test_pt --no-check-replication-filters \
--alter-foreign-keys-method=auto --recursion-method=none --quiet --execute

No foreign keys reference `test`.`test_pt`; ignoring --alter-foreign-keys-method
mysql> desc test_pt;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |
| age   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
删除成功。

(3)修改字段 
pt-online-schema-change --user=root --password=rootroot --host=192.168.1.51 \
--alter "MODIFY COLUMN age TINYINT NOT NULL DEFAULT 0" D=test,t=test_pt \
--no-check-replication-filters --alter-foreign-keys-method=auto \
--recursion-method=none --quiet --execute

No foreign keys reference `test`.`test_pt`; ignoring --alter-foreign-keys-method

修改前 
mysql> desc test_pt;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |

| age   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

修改后:
mysql>  desc test_pt;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |

| age   | tinyint(4)  | NO   |     | 0       |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

(4)字段改名称:将age改成address;
pt-online-schema-change --user=root --password=rootroot --host=192.168.1.51 \
--alter "CHANGE COLUMN age address varchar(30)" D=test,t=test_pt --no-check-alter \
--no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none \
--quiet --execute 

No foreign keys reference `test`.`test_pt`; ignoring --alter-foreign-keys-method

修改前:

mysql>  desc test_pt;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |

| age   | tinyint(4)  | NO   |     | 0       |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

修改后: 
mysql> desc test_pt;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| name    | varchar(10) | YES  |     | NULL    |                |

| address | varchar(30) | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

(5)增加索引,在address列上添加索引
pt-online-schema-change --user=root --password=rootroot --host=192.168.1.51 \
--alter "ADD INDEX idx_address(address)" D=test,t=test_pt --no-check-alter \
--no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none \
--print --execute

No slaves found.  See --recursion-method if host mysql1 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
No foreign keys reference `test`.`test_pt`; ignoring --alter-foreign-keys-method.
Altering `test`.`test_pt`...
Creating new table...
CREATE TABLE `test`.`_test_pt_new` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `address` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Created new table test._test_pt_new OK.
Altering new table...
ALTER TABLE `test`.`_test_pt_new` ADD INDEX idx_address(address)
Altered `test`.`_test_pt_new` OK.
2023-02-28T10:39:41 Creating triggers...
2023-02-28T10:39:41 Created triggers OK.
2023-02-28T10:39:41 Copying approximately 1 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_test_pt_new` (`id`, `name`, `address`) SELECT `id`, `name`, `address` FROM `test`.`test_pt` LOCK IN SHARE MODE /*pt-online-schema-change 81730 copy table*/
2023-02-28T10:39:41 Copied rows OK.
2023-02-28T10:39:41 Analyzing new table...
2023-02-28T10:39:41 Swapping tables...
RENAME TABLE `test`.`test_pt` TO `test`.`_test_pt_old`, `test`.`_test_pt_new` TO `test`.`test_pt`
2023-02-28T10:39:41 Swapped original and new tables OK.
2023-02-28T10:39:41 Dropping old table...
DROP TABLE IF EXISTS `test`.`_test_pt_old`
2023-02-28T10:39:41 Dropped old table `test`.`_test_pt_old` OK.
2023-02-28T10:39:41 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_ins`
2023-02-28T10:39:41 Dropped triggers OK.
Successfully altered `test`.`test_pt`.

修改前:
mysql> show indexes from  test_pt;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table   | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_pt |          0 | PRIMARY     |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

3 rows in set (0.00 sec)
修改后: 
mysql> show indexes from  test_pt;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table   | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_pt |          0 | PRIMARY     |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |

| test_pt |          1 | idx_address |            1 | address     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

(6)删除索引:
pt-online-schema-change --user=root --password=rootroot --host=192.168.1.51 \
--alter "DROP INDEX idx_address" D=test,t=test_pt --no-check-alter \
--no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none \
--print --execute

No slaves found.  See --recursion-method if host mysql1 has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
No foreign keys reference `test`.`test_pt`; ignoring --alter-foreign-keys-method.
Altering `test`.`test_pt`...
Creating new table...
CREATE TABLE `test`.`_test_pt_new` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `address` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_address` (`address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Created new table test._test_pt_new OK.
Altering new table...
ALTER TABLE `test`.`_test_pt_new` DROP INDEX idx_address
Altered `test`.`_test_pt_new` OK.
2023-02-28T10:42:43 Creating triggers...
2023-02-28T10:42:43 Created triggers OK.
2023-02-28T10:42:43 Copying approximately 1 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_test_pt_new` (`id`, `name`, `address`) SELECT `id`, `name`, `address` FROM `test`.`test_pt` LOCK IN SHARE MODE /*pt-online-schema-change 81884 copy table*/
2023-02-28T10:42:43 Copied rows OK.
2023-02-28T10:42:43 Analyzing new table...
2023-02-28T10:42:43 Swapping tables...
RENAME TABLE `test`.`test_pt` TO `test`.`_test_pt_old`, `test`.`_test_pt_new` TO `test`.`test_pt`
2023-02-28T10:42:43 Swapped original and new tables OK.
2023-02-28T10:42:43 Dropping old table...
DROP TABLE IF EXISTS `test`.`_test_pt_old`
2023-02-28T10:42:43 Dropped old table `test`.`_test_pt_old` OK.
2023-02-28T10:42:43 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_pt_ins`
2023-02-28T10:42:43 Dropped triggers OK.
Successfully altered `test`.`test_pt`.

删除前:
mysql> show indexes from  test_pt;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table   | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_pt |          0 | PRIMARY     |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| test_pt |          1 | idx_address |            1 | address     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
删除后:
mysql> show indexes from  test_pt;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table   | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_pt |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)


4.总结 
pt-online-schema-change 可以很方便的实现在线对表增加列,但是有个限制条件就是表必须有主键或者唯一索引,
否则添加失败。有主从的环境需要指定: --no-check-replication-filters.
pt-online-schema-change:
1.添加列
2.删除字段
3.修改字段
4.改字段的名称
5.创建索引
6.删除索引

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值