成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

千萬級的大表如何新增字段?

數據庫 其他數據庫
線上千萬級的大表在新增字段的時候,一定要小心,我見過太多團隊在千萬級大表上執行DDL時翻車的案例。很容易影響到正常用戶的使用。

前言

線上千萬級的大表在新增字段的時候,一定要小心,我見過太多團隊在千萬級大表上執行DDL時翻車的案例。

很容易影響到正常用戶的使用。

這篇文章跟大家一起聊聊線上千萬級的大表新增字段的6種方案,希望對你會有所幫助。

1.為什么大表加字段如此危險?

核心問題:MySQL的DDL操作會鎖表

當執行ALTER TABLE ADD COLUMN時:

  • MySQL 5.6之前:全程鎖表(阻塞所有讀寫)
  • MySQL 5.6+:僅支持部分操作的Online DDL

通過實驗驗證鎖表現象:

-- 會話1:執行DDL操作
ALTER TABLE user ADD COLUMN age INT;

-- 會話2:嘗試查詢(被阻塞)
SELECT * FROM user WHERE id=1; -- 等待DDL完成

鎖表時間計算公式:

鎖表時間 ≈ 表數據量 / 磁盤IO速度

對于1000萬行、單行1KB的表,機械磁盤(100MB/s)需要100秒的不可用時間!

如果在一個高并發的系統中,這個問題簡直無法忍受。

那么,我們要如何解決問題呢?

圖片圖片

2.原生Online DDL方案

在MySQL 5.6+版本中可以使用原生Online DDL的語法。

例如:

ALTER TABLE user 
ADD COLUMN age INT,
ALGORITHM=INPLACE, 
LOCK=NONE;

實現原理

圖片圖片

致命缺陷

  • 仍可能觸發表鎖(如添加全文索引)
  • 磁盤空間需雙倍(實測500GB表需要1TB空閑空間)
  • 主從延遲風險(從庫單線程回放)

3.停機維護方案

圖片圖片

適用場景

  • 允許停服時間(如凌晨3點)
  • 數據量小于100GB(減少導入時間)
  • 有完整回滾預案

4.使用PT-OSC工具方案

Percona Toolkit的pt-online-schema-change這個是我比較推薦的工具。

工作原理:

圖片圖片

操作步驟:

# 安裝工具
sudo yum install percona-toolkit

# 執行遷移(添加age字段)
pt-online-schema-change \
--alter "ADD COLUMN age INT" \
D=test,t=user \
--execute

5.邏輯遷移 + 雙寫方案

還有一個金融級安全的方案是:邏輯遷移 + 雙寫方案。

適用場景

  • 字段變更伴隨業務邏輯修改(如字段類型變更)
  • 要求零數據丟失的金融場景
  • 超10億行數據的表

實施步驟

  • 創建新表結構
-- 創建包含新字段的副本表
CREATE TABLE user_new (
    id BIGINT PRIMARY KEY,
    name VARCHAR(50),
    -- 新增字段
    age INT DEFAULT 0,
    -- 增加原表索引
    KEY idx_name(name)
) ENGINE=InnoDB;
  • 雙寫邏輯實現(Java示例)
// 數據寫入服務
publicclass UserService {
    @Transactional
    public void addUser(User user) {
        // 寫入原表
        userOldDAO.insert(user);
        // 寫入新表(包含age字段)
        userNewDAO.insert(convertToNew(user));
    }
    
    private UserNew convertToNew(User old) {
        UserNew userNew = new UserNew();
        userNew.setId(old.getId());
        userNew.setName(old.getName());
        // 新字段處理(從其他系統獲取或默認值)
        userNew.setAge(getAgeFromCache(old.getId()));
        return userNew;
    }
}
  • 數據遷移(分批處理)
-- 分批遷移腳本
SET @start_id = 0;
WHILE EXISTS(SELECT1FROMuserWHEREid > @start_id) DO
    INSERTINTO user_new (id, name, age)
    SELECTid, name, 
        COALESCE(age_cache, 0) -- 從緩存獲取默認值
    FROMuser
    WHEREid > @start_id
    ORDERBYid
    LIMIT10000;
    
    SET @start_id = (SELECTMAX(id) FROM user_new);
    COMMIT;
    -- 暫停100ms避免IO過載
    SELECTSLEEP(0.1); 
ENDWHILE;
  • 灰度切換流程

圖片圖片

這套方案適合10億上的表新增字段,不過操作起來比較麻煩,改動有點大。

6.使用gh-ost方案

gh-ost(GitHub's Online Schema Transmogrifier)是GitHub開源的一種無觸發器的MySQL在線表結構變更方案

專為解決大表DDL(如新增字段、索引變更、表引擎轉換)時鎖表阻塞、主庫負載高等問題而設計。

其核心是通過異步解析binlog,替代觸發器同步增量數據,顯著降低對線上業務的影響。

與傳統方案對比

  • 觸發器方案(如pt-osc):在源表上創建INSERT/UPDATE/DELETE觸發器,在同一事務內將變更同步到影子表。痛點

觸發器加重主庫CPU和鎖競爭,高并發時性能下降30%以上

無法暫停,失敗需重頭開始

外鍵約束支持復雜

  • gh-ost方案
  • 偽裝為從庫:直連主庫或從庫,拉取ROW格式的binlog,解析DML事件(INSERT/UPDATE/DELETE)
  • 異步應用:將增量數據通過獨立連接應用到影子表(如REPLACE INTO處理INSERT事件),與主庫事務解耦
  • 優先級控制:binlog應用優先級 > 全量數據拷貝,確保數據強一致

關鍵流程:

圖片圖片

  • 全量拷貝:按主鍵分塊(chunk-size控制)執行INSERT IGNORE INTO _table_gho SELECT ...,避免重復插入
  • 增量同步

INSERT → REPLACE INTO

UPDATE → 全行覆蓋更新

DELETE → DELETE

  • 原子切換(Cut-over)

1)短暫鎖源表(毫秒級)

2)執行原子RENAME:RENAME TABLE source TO _source_del, _source_gho TO source

3)清理舊表(_source_del

典型命令示例:

gh-ost \
--alter="ADD COLUMN age INT NOT NULL DEFAULT 0 COMMENT '用戶年齡'" \
--host=主庫IP --port=3306 --user=gh_user --password=xxx \
--database=test --table=user \
--chunk-size=2000 \       # 增大批次減少事務數
--max-load=Threads_running=80 \ 
--critical-load=Threads_running=200 \
--cut-over-lock-timeout-secnotallow=5 \  # 超時重試
--execute \               # 實際執行
--allow-on-master         # 直連主庫模式

監控與優化建議

  • 進度跟蹤
echo status | nc -U /tmp/gh-ost.sock  # 查看實時進度
  • 延遲控制

設置--max-lag-millis=1500,超閾值自動暫停

從庫延遲過高時切換為直連主庫模式

  • 切換安全:使用--postpone-cut-over-flag-file人工控制切換時機

7.分區表滑動窗口方案

適用場景:

  • 按時間分區的日志型大表
  • 需要頻繁變更結構的監控表

核心原理: 通過分區表特性,僅修改最新分區結構。

操作步驟

修改分區定義:

-- 原分區表定義
CREATETABLElogs (
    idBIGINT,
    log_time DATETIME,
    contentTEXT
) PARTITIONBYRANGE (TO_DAYS(log_time)) (
    PARTITION p202301 VALUESLESSTHAN (TO_DAYS('2023-02-01')),
    PARTITION p202302 VALUESLESSTHAN (TO_DAYS('2023-03-01'))
);

-- 添加新字段(僅影響新分區)
ALTERTABLElogsADDCOLUMN log_level VARCHAR(10) DEFAULT'INFO';

創建新分區(自動應用新結構):

-- 創建包含新字段的分區
ALTER TABLE logs REORGANIZE PARTITION p202302 INTO (
    PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),
    PARTITION p202303 VALUES LESS THAN (TO_DAYS('2023-04-01'))
);

歷史數據處理:

-- 僅對最近分區做數據初始化
UPDATE logs PARTITION (p202302) 
SET log_level = parse_log_level(content);

8.千萬級表操作注意事項

  • 主鍵必須存在(無主鍵將全表掃描)
  • 磁盤空間監控(至少預留1.5倍表空間)
  • 復制延遲控制
SHOW SLAVE STATUS; 
-- 確保Seconds_Behind_Master < 10
  • 灰度驗證步驟

先在從庫執行

檢查數據一致性

低峰期切主庫

  • 字段屬性選擇

避免NOT NULL(導致全表更新)

優先使用ENUM代替VARCHAR

默認值用NULL而非空字符串

9.各方案對比

以下是針對千萬級MySQL表新增字段的6種方案的對比。

方案

鎖表時間

業務影響

數據一致性

適用場景

復雜度

原生Online DDL

秒級~分鐘級

中(并發DML受限)

強一致

<1億的小表變更

停機維護

小時級

高(服務中斷)

強一致

允許停服+數據量<100GB

PT-OSC

毫秒級(僅cut-over)

中(觸發器開銷)

最終一致

無外鍵/觸發器的常規表

邏輯遷移+雙寫

0

低(需改代碼)

強一致

金融級核心表(10億+)

gh-ost

毫秒級(僅cut-over)

低(無觸發器)

最終一致

高并發大表(TB級)

中高

分區滑動窗口

僅影響新分區

分區級一致

按時間分區的日志表

總結

  1. 常規場景(<1億行)

首選 Online DDLALGORITHM=INSTANT,MySQL 8.0秒級加字段)

備選 PT-OSC(兼容低版本MySQL)

  1. 高并發大表(>1億行)
  • 必選 gh-ost(無觸發器設計,對寫入影響<5%)
  1. 金融核心表

雙寫方案 是唯一選擇(需2-4周開發周期)

  1. 日志型表

分區滑動窗口 最優(僅影響新分區)

  1. 緊急故障處理
  • 超百億級表異常時,考慮 停機維護 + 回滾預案

給大家一些建議

  • 加字段前優先使用 JSON字段預擴展ALTER TABLE user ADD COLUMN metadata JSON
  • 萬億級表建議 分庫分表 而非直接DDL
  • 所有方案執行前必須 全量備份mysqldump + binlog
  • 流量監測(Prometheus+Granfa實時監控QPS)

在千萬級系統的戰場上,一次草率的ALTER操作可能就是壓垮駱駝的最后一根稻草。

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2025-03-31 01:55:00

2019-11-19 07:56:30

MySQL壓測數據表

2018-07-26 14:50:00

數據庫MySQL大表優化

2010-09-10 13:37:30

表分區SQL Server

2024-10-08 09:35:23

2020-02-11 08:02:26

千萬級大表優化

2010-07-20 10:24:56

金蝶Apusic

2024-06-19 09:38:05

2021-03-31 10:12:12

MongoDBQPS存儲

2010-11-25 16:40:11

MySQL大表重復字段

2018-12-17 09:02:25

百億大表維度查詢

2024-10-28 10:50:33

2019-08-01 08:36:51

緩存系統并發

2015-06-26 11:30:33

WOT2015足記CTO孫東風

2024-11-12 11:57:08

2019-06-14 09:33:58

淘寶架構服務端

2019-10-25 09:28:12

算法設計操作系統

2022-02-28 10:11:22

查詢數據SQL

2019-12-09 09:52:38

設計軟件數據庫

2020-08-06 08:00:51

數據分頁優化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本少妇中文字幕 | 青青在线 | 日韩视频免费在线观看 | 日本黄色免费视频 | 色99999| 国产成人一区二区 | 日本美女性生活 | 日韩精品一区二区三区免费视频 | 久久精品国产77777蜜臀 | 麻豆av在线免费观看 | 一级特黄妇女高潮 | 嫩草在线视频 | 午夜快播 | 欧美日韩免费一区二区三区 | 久草免费在线视频 | 国产伦理一区二区 | 毛片www| 日韩av手机在线观看 | 香蕉成人网 | 国产精品激情 | 欧美黄色片视频 | 久久精品观看 | 久久99久久99| 精品久久久久久久久久久久久 | 精品小视频 | 欧美性一区二区 | 超碰免费在线观看 | 国产福利小视频 | 看黄色大片 | av久草| 免费视频久久 | 五月激情综合网 | 黄色大片免费在线观看 | 免费一级a毛片 | 一级毛片网 | 亚洲高清视频在线观看 | 亚洲黄色录像 | 五月天黄色网址 | 国产99对白在线播放 | 一级黄色录像带 | 一区二区国产在线 |