萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL LOAD DATA INFILE 百億級數據導入實戰:分片、關閉 Binlog、FIFO 流式加載

痛點:億級數據導入為何會「卡死」?

  • 單次 LOAD DATA 耗時數十分鐘,事務過大導致 Undo Log 膨脹、鎖表久。
  • 主庫寫 Binlog → 傳給從庫 → 從庫單線程重放,主從延遲達數十分鐘,業務讀從庫數據不一致。
  • 發現數據源錯誤需回滾,回滾時間 ≈ 導入時間,極其被動。

核心優化策略

1. 文件分片:大文件拆小,並行導入

# 使用 mk-fifo-split (Percona Toolkit) 建立命名管道分片
wget https://www.percona.com/get/mk-fifo-split
perl mk-fifo-split ./huge_data.txt --fifo /tmp/load.fifo --lines 1000000

# 循環讀取管道導入(主庫關閉 Binlog,加速並避免從庫延遲)
while [ -e /tmp/load.fifo ]; do
  mysql -e "SET sql_log_bin=0; SET foreign_key_checks=0; SET unique_checks=0; 
            LOAD DATA LOCAL INFILE '/tmp/load.fifo' INTO TABLE target_table"
  sleep 1
done

2. 關鍵會話級關閉開關(僅當前連接生效)

SET sql_log_bin = 0;        -- 不寫 Binlog,極大加速且不傳遞給從庫
SET foreign_key_checks = 0; -- 關閉外鍵檢查
SET unique_checks = 0;      -- 關閉唯一性檢查
SET autocommit = 0;         -- 手動提交事務(大事務慎用,建議分批提交)

⚠️ 風險提示:關閉檢查可能導致髒數據寫入,務必確保源數據已清洗驗證;導入完成後必須重新開啟並執行一致性校驗。

3. 引擎層面對比測試(實測數據)

方案引擎耗時備註
直接 LOADInnoDB6m 4s基線
關閉 Binlog+檢查InnoDB5m 4s提速 ~15%
FIFO 分片 100萬行/批InnoDB5m 26s可控制並發、便於監控
關閉 Binlog+檢查MyISAM3m 25sMyISAM 批量導入極快,但無事務

生產級導入 SOP

  1. 預檢:wc -l 確認行數,head -5 核對字段分隔符、編碼。
  2. 建表優化:導入前刪除二級索引,僅保主鍵;導入後 ALTER TABLE ADD INDEX ... 重建,速度提升 10 倍+。
  3. 分片並行:按主鍵範圍或 hash 拆分文件,多線程並發導入(注意控制併發數,避免壓垮 IO)。
  4. 驗證:行數對比、關鍵字段抽樣、Checksum 校驗。
  5. 從庫追趕:主庫導入完成後,開啟 sql_log_bin,從庫自動追趕;或使用 pt-table-sync 修復不一致。

工具箱推薦

  • mk-fifo-split / pt-fifo-split:命名管道分片,無需落地分片文件。
  • mysqlpump / mydumper:並行導出導入,支援壓縮、多線程。
  • Load Data Local Infile:客戶端讀取文件發送給服務端,適合應用服務器與 DB 分離場景。
copyright © 萬盛學電腦網 all rights reserved