首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 表結構變更完全指南:ALTER TABLE 核心操作、鎖控制與線上 DDL 實戰

     編輯:MySQL 資料庫相關知識

前言:DDL 是運維的「心臟手術」

ALTER TABLE 是 MySQL 結構變更的核心命令,涉及列增刪改、索引管理、主鍵調整、字符集遷移、表重命名等高危操作。本文系統梳理全操作命令、MySQL 版本演進下的鎖機制差異、ALGORITHM/LOCK 參數精準控制、大表變更實戰策略與回滾預案,助您在「零停機/極小停機」窗口期安全完成結構演進。

一、基礎表結構變更命令全集

1. 列操作


-- 刪除列
ALTER TABLE person DROP COLUMN birthday;

-- 新增列(指定位置)
ALTER TABLE person ADD COLUMN birthday DATETIME FIRST;           -- 首列
ALTER TABLE person ADD COLUMN birthday DATETIME AFTER name;      -- 指定列後
ALTER TABLE person ADD COLUMN birthday DATETIME;                 -- 尾部(默認)

-- 修改列類型/屬性(保留列名)
ALTER TABLE person MODIFY number BIGINT NOT NULL;

-- 修改列名+類型/屬性
ALTER TABLE person CHANGE number id BIGINT;
  • MODIFY:僅改類型/屬性,列名不變。
  • CHANGE:可改列名,必須重新聲明完整類型定義。

2. 主鍵操作


-- 新增主鍵
ALTER TABLE person ADD PRIMARY KEY (id);

-- 刪除主鍵
ALTER TABLE person DROP PRIMARY KEY;
  • InnoDB 表**必須有主鍵**,刪除 PK 會自動提升第一個非空唯一索引為 PK,否則隱式生成 6 字節 Row ID(性能差)。

3. 索引操作


-- 新增唯一索引
ALTER TABLE person ADD UNIQUE name_unique_index (name);

-- 新增普通索引
ALTER TABLE person ADD INDEX birthday_index (birthday);

-- 刪除索引
ALTER TABLE person DROP INDEX birthday_index;
ALTER TABLE person DROP INDEX name_unique_index;

4. 非唯一索引啟用/禁用(MyISAM 專用)


ALTER TABLE person DISABLE KEYS;   -- 停止更新非唯一索引,加速批量導入
ALTER TABLE person ENABLE KEYS;    -- 重建所有非唯一索引
  • InnoDB **不支援**,二級索引隨數據實時維護。
  • 適用場景:MyISAM 大批量 LOAD DATA/INSERT 前後。

5. 字符集遷移:三種語義截然不同


-- 1. 轉換表默認字符集 + 所有字符列字符集(數據實際轉碼)
ALTER TABLE person CONVERT TO CHARACTER SET utf8mb4;

-- 2. 僅修改單列字符集(數據實際轉碼)
ALTER TABLE person CHANGE name name VARCHAR(255) CHARACTER SET utf8mb4;

-- 3. 僅修改表默認字符集(僅影響後續新增列,現有列不變)
ALTER TABLE person DEFAULT CHARACTER SET utf8mb4;

避坑:CONVERT TO 會鎖表重建全表,大表極慢。建議:pt-online-schema-change / gh-ost 線上遷移。

6. 表重命名與跨庫移動


-- 同庫重命名
RENAME TABLE person TO person_other;

-- 跨庫移動(原子操作,元數據級,極快)
RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
  • RENAME TABLE 獲得元數據鎖,阻塞進行中的 DML/DDL,但耗時極短(毫秒級)。
  • 跨庫移動**不複製數據**,僅修改數據字典指向,極適合分庫遷移。

二、MySQL 版本演進與 DDL 鎖機制:從「全鎖」到「線上」

版本/引擎算法鎖模式說明
≤ 5.5 / MyISAMCOPY表級排他鎖全表拷貝,全程阻塞讀寫
5.6+ InnoDBINPLACE輕量元數據鎖大多數操作線上執行,僅準備/提交階段短暫阻塞
8.0+ InnoDBINSTANT無鎖/極輕量新增列(尾部)、修改默認值、刪除虛擬列等**秒級完成,零拷貝**

核心參數精準控制


ALTER TABLE tbl_name
    ADD COLUMN col INT,
    ALGORITHM=INPLACE,   -- DEFAULT/INPLACE/INSTANT/COPY
    LOCK=NONE;           -- DEFAULT/NONE/SHARED/EXCLUSIVE
ALGORITHM含義失敗行為
DEFAULT優先 INPLACE,不支援則 COPY報錯
INPLACE強制線上算法不支援報錯
COPY強制拷貝算法(老方式)報錯
INSTANT強制元數據級秒級算法不支援報錯
LOCK含義適用場景
DEFAULT自動選擇最低鎖級別常規
NONE**禁止任何鎖**,不支援則報錯核心業務零停機
SHARED允許共享讀鎖,阻塞寫可接受短暫寫阻塞
EXCLUSIVE排他鎖,阻塞讀寫維護窗口/非核心表

三、常見操作的算法/鎖支援矩陣

操作InnoDB 算法最低鎖備註
新增列 (尾部)INSTANT (8.0+)NONE元數據修改,極快
新增列 (首部/中間)INPLACESHARED需重建表
刪除列INPLACESHARED需重建表
修改列類型INPLACESHARED兼容性轉換(如 INT→BIGINT) 支援 INSTANT
修改列名INPLACENONE8.0+ 純元數據
新增/刪除二級索引INPLACENONE構建索引過程不阻塞 DML
新增/刪除主鍵INPLACESHARED涉及聚簇索引重建
字符集轉換COPYEXCLUSIVE全表重建,**極慢**,大表禁用
修改默認值INSTANT (8.0+)NONE純元數據
RENAME TABLE元數據短暫 EXCLUSIVE毫秒級,跨庫同效

四、大表線上變更實戰策略

1. 原生 Online DDL (5.6+)

  • 適用:新增/刪除二級索引、修改列名/默認值、兼容性類型變更、新增尾部列 (8.0)。
  • 強制參數:ALGORITHM=INPLACE, LOCK=NONE(不支援則報錯,不靜默降級 COPY)。

2. 工具級方案:不支援 INPLACE 的操作(字符集遷移、修改主鍵、刪除列等)

工具原理優點缺點
pt-online-schema-change (Percona)觸發器+影子表同步成熟穩定、支援複雜變更、可暫停/恢復觸發器開銷、從庫延遲風險
gh-ost (GitHub)Binlog 異步回放+影子表無觸發器、主庫無寫入壓力、可控流量限流需開啟 Row 格式 Binlog、主鍵必須存在

# gh-ost 典型用法
gh-ost --host=127.0.0.1 --user=root --password=xxx \
  --database=db --table=person \
  --alter="MODIFY COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT" \
  --max-load=Threads_running=200 --critical-load=Threads_running=500 \
  --chunk-size=1000 --execute

3. 變更前檢查清單

  1. 備份驗證:還原演練確保可回滾。
  2. 兼容性測試:應用代碼對新結構兼容(雙寫/版本兼容)。
  3. 從庫先行:從庫先變更,驗證無誤後主庫變更(利用複製延遲窗口)。
  4. 監控指標:Threads_running、Innodb_row_lock_waits、複製延遲、磁碟空間(影子表佔用 1x)。
  5. 回滾預案:pt-osc 支援 --drop-old-table/--no-drop-old-table 保留舊表便於回滾。

五、實戰案例:大表字符集 utf8 → utf8mb4 遷移


-- 方案:gh-ost 線上遷移(避免 COPY 算法鎖表數小時)
gh-ost --host=... --database=prod --table=big_table \
  --alter="CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" \
  --max-load=Threads_running=100 --critical-load=Threads_running=300 \
  --chunk-size=2000 --execute --panic-flag-file=/tmp/gh-ost.panic
  • 分批遷移,每批 2000 行,根據主庫負載自動限流。
  • 恐慌文件機制:觸發即暫停,人工介入後恢復。
  • 完成後驗證:SHOW CREATE TABLE、抽樣數據校對、應用煙霧測試。

結語

表結構變更是數據庫演進的必經之路。從理解 ALGORITHM/LOCK 的精準語義,到選擇原生 Online DDL 或 gh-ost/pt-osc 工具級方案;從「從庫先行」的架構級策略,到「恐慌文件」的戰術級熔斷——每一個決策都在為**業務連續性**與**數據安全**投票。願本文指南助您在大表變更的「手術台」上,穩健落刀、精準縫合、零事故交付。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved