gh-ost在每次遷移時會要求原表和新表共享相同的
unique
且 NOT NULL
的key。介紹
以下為原表:
新增一個
ts timestamp
欄位後的新表:在此案例中
gh-ost
除了會使用 PRIMARY KEY
從 tb1
複製資料到 gh-ost TABLE- _tbl_gho
以外,同時會將 binlog
應用在 tbl
的事件也應用在 _tbl_gho
中。為了應用
binlog
而必須要有 shard key
。例如: UPDATE tb1
會被轉換成 REPLACE INTO _tbl_gho
,由此來確保 update
。因此在此事例中, gh-ost
透過 PRIMARY KEY(ID)
來讓 tb1
和 _tbl_gho
是一對一的關係。 規則
原表和新表必須共相同的
unique
且 NOT NULL
的KEY:- 不必是
PRIMARY KEY
- KEY在原表和舊表只要有相同的欄位,允許有不同的名稱
在遷移開始時,
gh-ost
會檢查原表和新表是否至少有一個共同的 unique
且 NOT NULL
的KEY,如果找不到 gh-ost
會退出。如果有 unique
但沒有 NOT NULL
屬性的key,當確保沒有實際 NULL
的值時可以使用 --allow-nullable-unique-key
讓 gh-ost
運行。注意有實際 NULL
的值將破壞數據。範例
在此事例中有2個
unique
且 NOT NULL
的KEY:PRIMARY KEY
和 name_uidx
允許的ALTER操作:
add column i int
add key owner_idx(owner_id)
add unique key owner_idx(owner_id, name)
- 注意:在此遷移期間不要寫入有衝突的行
drop key name_uidx
-PRIMARY KEY
成為這兩張表的Shared Key
drop primary key, add primary key(owner_id, loc_id)
-name_uidx
成為這兩張表的Shared Key
change id bigint unsigned not null auto_increment
-PRIMARY KEY
修改資料型態,並未修改VALUE 是可以的操作
drop primary key, drop key name_uidx, add primary key(name), add unique key id_uidx(id)
- 交換兩個KEY。但無論是id
還是name
都可以使用
不允許的ALTER操作:
drop primary key, drop key name_uidx
- 新表沒有unique
且NOT NULL
的KEY
drop primary key, drop key name_uidx, create primary key(name, owner_id)
- 原表和新表沒有Shared Key
,即使新的primary key
包含了name
,但因為是複合主鍵,因此沒有辦法確保新表的唯一性
解決方案
如果需要將
PRIMARY KEY
和 name_uidx
改為使用其他欄位作為key,則需要進行2次遷移:ADD UNIQUE KEY temp_pk (temp_pk_column,...)
DROP PRIMARY KEY, DROP KEY temp_pk, ADD PRIMARY KEY (temp_pk_column,...)