首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL AUTO_INCREMENT 不連續根因:唯一鍵衝突、事務回滾、批量插入預分配

     編輯:MySQL 綜合教學

MySQL AUTO_INCREMENT 不連續根因:唯一鍵衝突、事務回滾、批量插入預分配

自增 ID 不連續是正常行為,非 Bug。本文通過實測複現三大典型場景:唯一鍵衝突報錯、事務回滾、批量插入預分配,解析 InnoDB 自增鎖與序列分配機制。

實測複現過程

CREATE TABLE person_list (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(15) NOT NULL,
    sex VARCHAR(15) DEFAULT '中',
    ID_C VARCHAR(20) NOT NULL UNIQUE,  -- 唯一鍵
    vocation VARCHAR(8),
    salary FLOAT DEFAULT 0.0
) CHARSET=utf8;

-- 正常插入 1~7
INSERT ...;  -- id 1~7 連續

-- 插入 id=8 因 ID_C 衝突報錯 (Duplicate entry)
-- 再次插入 id=9 成功 → id 跳至 10

-- 故意連續 10 次衝突插入
-- 再插入成功 → id 跳至 25 (10+15)

三大根因深度解析

場景機制ID 影響
唯一鍵/主鍵衝突報錯InnoDB 預分配自增值 → 執行插入 → 唯一檢查失敗 → 回滾 → **自增值不回收**每次衝突 +1
事務回滾事務內獲取自增值 → 回滾 → **自增值不回收**每次回滾 +1
批量插入 (INSERT ... VALUES(),()...)預分配連續區間(預設 8-32 個)→ 實際用完釋放剩餘 → **下次從區間末尾+1 開始**批次大小相關

InnoDB 自增鎖模式 (innodb_autoinc_lock_mode)

生產預設模式 1,**不保證連續、不保證單調遞增(極罕見並發交錯)**,僅保證**唯一、遞增趨勢**。

常見誤區與對策

  • ❌ 以為自增 ID 必須連續 → **業務邏輯不可依賴連續性**。
  • ❌ 用 MAX(id)+1 手動分配 → 並發極易衝突、效能差。
  • ✅ 業務需連續編號(如發票號)→ 獨立序列表 + 行鎖 SELECT ... FOR UPDATE 串行分配。
  • ✅ 定期整理碎片 ID → 僅靜態歸檔表可考慮 ALTER TABLE AUTO_INCREMENT=N,線上表**嚴禁**。
  • ✅ 監控自增上限:SHOW TABLE STATUS LIKE 't'\G 觀察 Auto_increment,防 BIGINT 耗盡。

驗證查詢

-- 查看下一個自增值
SHOW TABLE STATUS LIKE 'person_list'\G
-- Auto_increment: 25

-- 查看表結構
SHOW CREATE TABLE person_list\G
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
模式值特性適用
Traditional0表級自增鎖,語句結束釋放,嚴格連續主從基於 Statement 复制
Consecutive1簡單 INSERT 表鎖,批量 INSERT 輕量鎖,預分配**預設**,效能平衡
Interleaved2無自增鎖,輕量互斥量,最大並發,ID 可能交錯高併發、Row 复制