當資料量大到 PHPMyAdmin、MySQL Workbench 等 GUI 工具力不從心時,命令列工具 mysqldump 是唯一可靠選擇。本文系統整理核心參數、常用組合與大數據庫遷移實戰技巧。
mysqldump [OPTIONS] database [tables]
mysqldump [OPTIONS] --databases db1 [db2 ...]
mysqldump [OPTIONS] --all-databases
不指定表則導出整庫。執行 mysqldump --help 查看版本支援的完整選項。
| 參數 | 短參數 | 功能說明 | 建議場景 |
|---|---|---|---|
--add-locks | - | 每表導出前加 LOCK TABLES,後 UNLOCK TABLES。加速導入 | 導入時預設開啟(含於 --opt) |
--add-drop-table | - | 每 CREATE TABLE 前加 DROP TABLE IF EXISTS | 重建環境、測試庫同步 |
--complete-insert | -c | 使用完整 INSERT 語法(含欄位名)。避免欄位順序變更導致錯誤 | 異構遷移、版本升級 |
--extended-insert | -e | 多行合併 INSERT(INSERT INTO t VALUES (...),(...),...)。大幅縮小檔案、加速導入 | 大數據庫必開(--opt 含之) |
--quick | -q | 不將整個結果集載入記憶體,逐行讀取寫出。大表必須,否則 OOM | 大數據庫必開(--opt 含之) |
--opt | - | 組合開啟:--add-drop-table --add-locks --create-options --quick --extended-insert --lock-tables --set-charset --disable-keys | 預設開啟,一般無需額外指定 |
--single-transaction | - | InnoDB 熱備份核心。啟動一致性快照,不鎖表,保證時間點一致性 | InnoDB 生產備份必加 |
--lock-tables | -l | 鎖定所有表(READ LOCAL)。MyISAM 必須;InnoDB 用 --single-transaction 替代 | MyISAM 表備份 |
--no-data | -d | 僅導出結構(DDL),不導資料 | 結構遷移、審核 Schema |
--no-create-info | -t | 僅導出資料(INSERT),不含 CREATE TABLE | 資料同步、增量導入 |
--routines | -R | 導出預存程序與函數 | 完整遷移 |
--triggers | --triggers | 導出觸發器(預設開啟) | 完整遷移 |
--events | -E | 導出 Event 排程任務 | 完整遷移 |
--hex-blob | - | 二進位欄位(BLOB/BINARY)以十六進位導出,避免編碼問題 | 含二進位資料的表 |
--default-character-set | - | 指定連線字元集,防止亂碼 | 非 utf8mb4 預設環境 |
--master-data=2 | - | 輸出 CHANGE MASTER TO 註解(2=註解形式),記錄 Binlog 位點,支援主從搭建 | 主從同步初始化 |
--flush-logs | -F | 備份前刷新 Binlog,配合 --master-data 獲得精確位點 | 主從搭建、時間點恢復 |
--compress | -C | 客戶端/伺服器通訊壓縮,低頻寬環境加速 | 跨網段備份 |
--force | -f | 遇錯誤繼續執行,不中斷 | 損壞表搶救 |
mysqldump -u root -p \
--single-transaction \
--quick \
--extended-insert \
--hex-blob \
--routines --triggers --events \
--master-data=2 \
--flush-logs \
--default-character-set=utf8mb4 \
my_database > backup_$(date +%F).sql
mysqldump -u root -p \
--lock-tables \
--quick \
--extended-insert \
--hex-blob \
--routines --triggers --events \
my_database > backup_$(date +%F).sql
mysqldump -u root -p --no-data --routines --triggers --events my_database > schema.sql
# 先導出結構
mysqldump -u root -p --no-data my_database > schema.sql
# 大表分批導出(配合 WHERE 條件)
mysqldump -u root -p --quick --where="id BETWEEN 1 AND 1000000" my_database big_table > big_table_part1.sql
mysqldump -u root -p --quick --where="id BETWEEN 1000001 AND 2000000" my_database big_table > big_table_part2.sql
# ... 並行執行多個分批
mysql -u root -p my_database < backup.sql
# 或在 SQL 檔案開頭加入:
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
# 檔案結尾加入:
SET foreign_key_checks=1;
SET unique_checks=1;
SET autocommit=1;
COMMIT;
split -l 100000 backup.sql part_ 然後逐個導入LOAD DATA INFILE 替代 INSERT:導出時加 --tab=/tmp --fields-terminated-by=',' 產生文字檔,導入快 20 倍max_allowed_packet:客戶端與伺服器同步設大(如 1G)防止大封包中斷| 現象 | 原因 | 解決 |
|---|---|---|
| Out of memory / Killed | 未用 --quick,結果集全載入記憶體 | 加上 --quick(--opt 含之) |
| MySQL server has gone away | 封包過大或導入耗時超過 wait_timeout | 調大 max_allowed_packet、wait_timeout |
| 導入極慢 | 自動提交、索引逐行維護、無批次 | 關閉 autocommit/unique_checks,用 --extended-insert |
| 編碼亂碼 | 字元集不一致 | 指定 --default-character-set=utf8mb4,確保資料庫/表/連線三者一致 |
| 備份檔案過大 | 未壓縮、含不需要資料 | 管線壓縮:mysqldump ... | gzip > backup.sql.gz |