最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL億級(jí)大表安全添加字段的三種方案

 更新時(shí)間:2025年03月31日 08:55:31   作者:碼農(nóng)阿豪@新空間  
面對(duì)?1.35億條數(shù)據(jù)?的?MySQL?表添加字段,傳統(tǒng)?ALTER?TABLE?可能導(dǎo)致長(zhǎng)時(shí)間鎖表,嚴(yán)重影響業(yè)務(wù),本文將提供一套完整的?零停機(jī)方案,涵蓋?Online?DDL?優(yōu)化、專業(yè)工具使用?和?Java?應(yīng)用層配合策略,需要的朋友可以參考下

1. 億級(jí)大表 ALTER 的風(fēng)險(xiǎn)評(píng)估

1.1 直接執(zhí)行 ALTER 的潛在問題

ALTER TABLE `orders` ADD COLUMN `is_priority` TINYINT NULL DEFAULT 0;
  • 鎖表時(shí)間估算(經(jīng)驗(yàn)值):
    • MySQL 5.6:約 2-6小時(shí)(完全阻塞)
    • MySQL 5.7+:10-30分鐘(短暫阻塞寫入)
  • 業(yè)務(wù)影響:
    • 所有讀寫請(qǐng)求超時(shí)
    • 連接池耗盡(Too many connections
    • 可能觸發(fā)高可用切換(如 MHA)

1.2 關(guān)鍵指標(biāo)檢查

-- 查看表大?。℅B)
SELECT 
    table_name, 
    ROUND(data_length/1024/1024/1024,2) AS size_gb
FROM information_schema.tables 
WHERE table_schema = 'your_db' AND table_name = 'orders';

-- 檢查當(dāng)前長(zhǎng)事務(wù)
SELECT * FROM information_schema.innodb_trx 
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60;

2. 三種安全方案對(duì)比

方案工具執(zhí)行時(shí)間阻塞情況適用版本復(fù)雜度
Online DDL原生MySQL30min-2h短暫阻塞寫5.7+★★☆
pt-oscPercona Toolkit2-4h零阻塞所有版本★★★
gh-ostGitHub1-3h零阻塞所有版本★★★★

3. 方案一:MySQL 原生 Online DDL(5.7+)

3.1 最優(yōu)執(zhí)行命令

ALTER TABLE `orders` 
ADD COLUMN `is_priority` TINYINT NULL DEFAULT 0,
ALGORITHM=INPLACE, 
LOCK=NONE;

3.2 監(jiān)控進(jìn)度(另開會(huì)話)

-- 查看 DDL 狀態(tài)
SHOW PROCESSLIST;

-- 查看 InnoDB 操作進(jìn)度
SELECT * FROM information_schema.innodb_alter_table;

3.3 預(yù)估執(zhí)行時(shí)間(經(jīng)驗(yàn)公式)

時(shí)間(min) = 表大小(GB) × 2 + 10
  • 假設(shè)表大小 50GB → 約 110分鐘

4. 方案二:pt-online-schema-change 實(shí)戰(zhàn)

4.1 安裝與執(zhí)行

# 安裝 Percona Toolkit
sudo yum install percona-toolkit

# 執(zhí)行變更(自動(dòng)創(chuàng)建觸發(fā)器)
pt-online-schema-change \
--alter "ADD COLUMN is_priority TINYINT NULL DEFAULT 0" \
D=your_db,t=orders \
--chunk-size=1000 \
--max-load="Threads_running=50" \
--critical-load="Threads_running=100" \
--execute

4.2 關(guān)鍵參數(shù)說明

參數(shù)作用推薦值(億級(jí)表)
--chunk-size每次復(fù)制的行數(shù)500-2000
--max-load自動(dòng)暫停閾值Threads_running=50
--critical-load強(qiáng)制中止閾值Threads_running=100
--sleep批次間隔時(shí)間0.5(秒)

4.3 Java 應(yīng)用兼容性處理

// 在觸發(fā)器生效期間,需處理重復(fù)主鍵異常
try {
    orderDao.insert(newOrder);
} catch (DuplicateKeyException e) {
    // 自動(dòng)重試或走降級(jí)邏輯
    orderDao.update(newOrder);
}

5. 方案三:gh-ost 高級(jí)用法

5.1 執(zhí)行命令(無需觸發(fā)器)

gh-ost \
--database="your_db" \
--table="orders" \
--alter="ADD COLUMN is_priority TINYINT NULL DEFAULT 0" \
--assume-rbr \
--allow-on-master \
--cut-over=default \
--execute

5.2 核心優(yōu)勢(shì)

  • 無觸發(fā)器設(shè)計(jì):避免性能損耗
  • 動(dòng)態(tài)限流:自動(dòng)適應(yīng)服務(wù)器負(fù)載
  • 可交互控制:支持暫停/恢復(fù)
# 運(yùn)行時(shí)控制
echo throttle | nc -U /tmp/gh-ost.sock
echo no-throttle | nc -U /tmp/gh-ost.sock

6. Java 應(yīng)用層適配策略

6.1 雙寫兼容模式(推薦)

// 在變更期間同時(shí)寫入新舊字段
public void createOrder(Order order) {
    order.setIsPriority(0); // 新字段默認(rèn)值
    orderMapper.insert(order);
    
    // 兼容舊代碼
    if (order.getV2() == null) {
        orderMapper.updateIsPriority(order.getId(), 0);
    }
}

6.2 動(dòng)態(tài) SQL 路由

<!-- MyBatis 動(dòng)態(tài)字段映射 -->
<insert id="insertOrder">
    INSERT INTO orders 
    (id, user_id, amount
    <if test="isPriority != null">, is_priority</if>)
    VALUES
    (#{id}, #{userId}, #{amount}
    <if test="isPriority != null">, #{isPriority}</if>)
</insert>

7. 監(jiān)控與回滾方案

7.1 實(shí)時(shí)監(jiān)控指標(biāo)

# 監(jiān)控復(fù)制延遲(主從架構(gòu))
pt-heartbeat --monitor --database=your_db

# 查看 gh-ost 進(jìn)度
tail -f gh-ost.log

7.2 緊急回滾步驟

# pt-osc 回滾(自動(dòng)清理臨時(shí)表)
pt-online-schema-change --drop-new-table --alter="..." --execute

# gh-ost 回滾
gh-ost --panic-on-failure --revert

8. 總結(jié)建議

  1. 首選方案:

    • MySQL 8.0 → 原生 ALGORITHM=INSTANT(秒級(jí)完成)
    • MySQL 5.7 → gh-ost(無觸發(fā)器影響)
  2. 執(zhí)行窗口:

    • 選擇業(yè)務(wù)流量最低時(shí)段(如凌晨 2-4 點(diǎn))
    • 提前通知業(yè)務(wù)方準(zhǔn)備降級(jí)方案
  3. 驗(yàn)證流程:

-- 變更后檢查數(shù)據(jù)一致性
SELECT COUNT(*) FROM orders WHERE is_priority IS NULL;
  • 后續(xù)優(yōu)化:
-- 添加完成后可改為 NOT NULL
ALTER TABLE orders 
MODIFY COLUMN is_priority TINYINT NOT NULL DEFAULT 0;

通過合理選擇工具+應(yīng)用層適配,即使 1.35億條數(shù)據(jù) 的表也能實(shí)現(xiàn) 零感知 的字段添加。

以上就是MySQL億級(jí)大表安全添加字段的三種方案的詳細(xì)內(nèi)容,更多關(guān)于MySQL大表添加字段的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

元氏县| 隆昌县| 寿阳县| 建始县| 毕节市| 福泉市| 北辰区| 上犹县| 肇庆市| 淅川县| 乃东县| 高唐县| 平舆县| 青海省| 商河县| 清原| 长海县| 宁阳县| 肥乡县| 孟津县| 广西| 巴里| 康定县| 巴马| 若尔盖县| 乐平市| 郧西县| 临沭县| 乌鲁木齐市| 呼玛县| 黑河市| 綦江县| 常熟市| 北辰区| 安平县| 定州市| 云龙县| 邛崃市| 东丽区| 泊头市| 尤溪县|