场景:
某个表上已是联合主键,后来需要修改成 自增长的id 主键。
思路:
1.先删除原表的联合主键
2.再添加id 列,并设置为主键
3.把原表的主键作为新表的unique key
sql如下:
alter_sql="DROP PRIMARY KEY,add column id bigint(20) NOT NULL AUTO_INCREMENT primary key,add unique key uk_dic_cid(device_id,comic_id)"
**为什有第三步呢?? **
delete触发器新表是根据老表的主键删除。
如果新表没有加unique key,pt-osc 执行过程中会引发性能问题。
首先看一段pt-osc 的输出:
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
Starting a dry run. xxx
.comment_xxx_test
will not be altered. Specify --execute instead of --dry-run to alter the table.
--alter contains 'DROP PRIMARY KEY'. Dropping and altering the primary key can be dangerous, especially if the original table does not have other unique indexes.
Creating new table...
CREATE TABLE xxxx
._comment_xxx_test_new
(
device_id
int(11) NOT NULL,
comment_id
int(11) NOT NULL,
comic_id
bigint(20) unsigned NOT NULL DEFAULT '0',
created_at
datetime NOT NULL,
status
smallint(6) NOT NULL DEFAULT '0',
target_type
tinyint(4) NOT NULL DEFAULT '0' COMMENT '评论的对象类型',
PRIMARY KEY (device_id
,comment_id
),
KEY ix_comment
(comment_id
,status
),
KEY ix_device_comic
(device_id
,comic_id
,status
),
KEY idx_created_at
(created_at
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Created new table xxx._comment_xxx_test_new OK.
Altering new table...
ALTER TABLE xxx
._comment_xxx_test_new
DROP PRIMARY KEY,add column id bigint(20) NOT NULL AUTO_INCREMENT primary key,add unique key uk_dic_cid(device_id,comic_id)
Altered xxx
._comment_xxx_test_new
OK.
Using original table index PRIMARY for the DELETE trigger instead of new table index PRIMARY because the new table index uses column id which does not exist in the original table.
Not creating triggers because this is a dry run.
CREATE TRIGGER pt_osc_xxx_comment_xxx_test_del
AFTER DELETE ON xxx
.comment_xxx_test
FOR EACH ROW DELETE IGNORE FROM xxx
._comment_xxx_test_new
WHERE xxx
._comment_xxx_test_new
.device_id
<=> OLD.device_id
AND xxx
._comment_xxx_test_new
.comment_id
<=> OLD.comment_id
CREATE TRIGGER pt_osc_xxx_comment_xxx_test_upd
AFTER UPDATE ON xxx
.comment_xxx_test
FOR EACH ROW REPLACE INTO xxx
._comment_xxx_test_new
(device_id
, comment_id
, comic_id
, created_at
, status
, target_type
) VALUES (NEW.device_id
, NEW.comment_id
, NEW.comic_id
, NEW.created_at
, NEW.status
, NEW.target_type
)
CREATE TRIGGER pt_osc_xxx_comment_xxx_test_ins
AFTER INSERT ON xxx
.comment_xxx_test
FOR EACH ROW REPLACE INTO xxx
._comment_xxx_test_new
(device_id
, comment_id
, comic_id
, created_at
, status
, target_type
) VALUES (NEW.device_id
, NEW.comment_id
, NEW.comic_id
, NEW.created_at
, NEW.status
, NEW.target_type
)
Not copying rows because this is a dry run.
INSERT LOW_PRIORITY IGNORE INTO xxx
._comment_xxx_test_new
(device_id
, comment_id
, comic_id
, created_at
, status
, target_type
) SELECT device_id
, comment_id
, comic_id
, created_at
, status
, target_type
FROM xxx
.comment_xxx_test
LOCK IN SHARE MODE /pt-online-schema-change 15453 copy table/
Not swapping tables because this is a dry run.
Not dropping old table because this is a dry run.
Not dropping triggers because this is a dry run.
DROP TRIGGER IF EXISTS xxx
.pt_osc_xxx_comment_xxx_test_del
;
DROP TRIGGER IF EXISTS xxx
.pt_osc_xxx_comment_xxx_test_upd
;
DROP TRIGGER IF EXISTS xxx
.pt_osc_xxx_comment_xxx_test_ins
;
2016-06-15T16:58:08 Dropping new table...
DROP TABLE IF EXISTS xxx
._comment_xxx_test_new
;
2016-06-15T16:58:08 Dropped new table OK.
Event Count
====== =====
INSERT 0
Dry run complete. xxx
.comment_xxx_test
was not altered.