現有表主鍵為 INT AUTO_INCREMENT,因業務整合需遷移至 CHAR(18)(如統一採用雪花算法 ID)。約束條件:表含海量歷史數據,不可刪表重建,必須在線 DDL 變更。
-- 步驟 1:移除 AUTO_INCREMENT 屬性(保留 INT 類型)
ALTER TABLE `table_name` CHANGE `indexid` `indexid` INT;
-- 步驟 2:刪除主鍵約束(此操作會短暫鎖表,建議低峰期執行)
ALTER TABLE `table_name` DROP PRIMARY KEY;
-- 步驟 3:修改欄位類型為 CHAR(18)(含數據轉換,耗時與表大小成正比)
ALTER TABLE `table_name` CHANGE `indexid` `indexid` CHAR(18);
-- 步驟 4:重新添加主鍵約束
ALTER TABLE `table_name` ADD PRIMARY KEY (`indexid`);
| 風險點 | 影響 | 應對方案 |
|---|---|---|
| 步驟 2 刪除 PK 期間寫入失敗 | 業務報錯 | 維護窗口執行;或使用 pt-online-schema-change / gh-ost 在線變更工具 |
| INT→CHAR 數據轉換邏輯 | 數值 123 → '123' 左對齊,長度不足不補零 | 預先驗證轉換邏輯;若需固定長度,應用層生成 ID 時左補零 |
| 外鍵關聯表級聯失效 | 關聯表外鍵報錯 | 先刪除所有關聯外鍵,變更完成後重建 |
| 索引重建耗時與空間 | 臨時佔用 1-2 倍表空間 | 確保磁盤剩餘空間 > 3 倍表大小;監控 SHOW PROCESSLIST |
# 使用 gh-ost (GitHub 出品,無觸發器、無鎖表)
gh-ost \
--host=127.0.0.1 --port=3306 --user=root --password=xxx \
--database=db_name --table=table_name \
--alter="CHANGE COLUMN indexid indexid CHAR(18), DROP PRIMARY KEY, ADD PRIMARY KEY(indexid)" \
--execute --max-load=Threads_running=50 --critical-load=Threads_running=100
# 或 pt-online-schema-change (Percona Toolkit)
pt-online-schema-change \
--alter="CHANGE COLUMN indexid indexid CHAR(18), DROP PRIMARY KEY, ADD PRIMARY KEY(indexid)" \
D=db_name,t=table_name --execute --max-load=Threads_running=50
SHOW CREATE TABLE table_name 確認結構正確SELECT indexid FROM table_name LIMIT 10 抽樣檢查數據格式INSERT INTO table_name (indexid, ...) VALUES ('test_id_001', ...) 驗證寫入EXPLAIN SELECT * FROM table_name WHERE indexid = 'xxx' 確認索引生效核心原則: 任何主鍵類型變更都是高風險操作,必須經過測試環境全流程驗證、制定回滾預案、在低峰期配合在線變更工具執行。MySQL 8.0+ 支援 INSTANT DDL 部分場景秒級完成,升級版本亦為長遠之計。