欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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)檢查

-- 查看表大小(GB)
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)文章

  • 解決Windows環(huán)境下安裝 mysql-8.0.11-winx64 遇到的問題

    解決Windows環(huán)境下安裝 mysql-8.0.11-winx64 遇到的問題

    這篇文章主要介紹了Windows環(huán)境下安裝 mysql-8.0.11-winx64 遇到的問題及解決辦法 ,需要的朋友可以參考下
    2018-10-10
  • 簡(jiǎn)述MySQL主鍵和外鍵使用及說明

    簡(jiǎn)述MySQL主鍵和外鍵使用及說明

    MySQL通過外鍵約束來保證表與表之間的數(shù)據(jù)的完整性和準(zhǔn)確性,本文主要介紹了簡(jiǎn)述MySQL主鍵和外鍵使用及說明,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Mysql查詢不需要Group?by的字段方法實(shí)例

    Mysql查詢不需要Group?by的字段方法實(shí)例

    在平時(shí)的開發(fā)任務(wù)中我們經(jīng)常會(huì)用到MYSQL的GROUP BY分組,用來獲取數(shù)據(jù)表中以分組字段為依據(jù)的統(tǒng)計(jì)數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Mysql查詢不需要Group?by字段方法的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • MySQL source命令的使用簡(jiǎn)介

    MySQL source命令的使用簡(jiǎn)介

    這篇文章主要介紹了MySQL source命令的使用簡(jiǎn)介,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03
  • Mysql教程分組排名實(shí)現(xiàn)示例詳解

    Mysql教程分組排名實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了Mysql數(shù)據(jù)庫分組排名實(shí)現(xiàn)的示例詳解教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10
  • linux下mysql自動(dòng)備份腳本代碼

    linux下mysql自動(dòng)備份腳本代碼

    mysql是以mysql用戶身份運(yùn)行的,對(duì)/home /mybackup不可寫也會(huì)失敗
    2010-07-07
  • MySQL server has gone away的問題解決

    MySQL server has gone away的問題解決

    本文主要介紹了MySQL server has gone away的問題解決,意思就是指client和MySQL server之間的鏈接斷開了,下面就來介紹一下幾種原因及其解決方法,感興趣的可以了解一下
    2024-07-07
  • mysql事務(wù)和隔離級(jí)別底層原理淺析

    mysql事務(wù)和隔離級(jí)別底層原理淺析

    大家好,本篇文章主要講的是mysql事務(wù)和隔離級(jí)別底層原理淺析,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2021-12-12
  • mysql語法時(shí)采用了雙引號(hào)““的錯(cuò)誤問題

    mysql語法時(shí)采用了雙引號(hào)““的錯(cuò)誤問題

    錯(cuò)誤原因:使用雙引號(hào)定義表名和列名導(dǎo)致MySQL報(bào)錯(cuò),應(yīng)使用反引號(hào),修改方案:將雙引號(hào)改為反引號(hào),避免語法沖突,總結(jié):在MySQL中,正確使用反引號(hào)引用標(biāo)識(shí)符,確保SQL語句符合MySQL語法規(guī)則
    2024-10-10
  • mysql中關(guān)于between和in的區(qū)別

    mysql中關(guān)于between和in的區(qū)別

    這篇文章主要介紹了mysql中關(guān)于between和in的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評(píng)論