核心語法與三大運作模式
# 1. 備份單庫/多庫
mysqldump [options] --databases db1 db2 db3 > backup.sql
# 2. 備份單庫內指定表
mysqldump [options] db_name table1 table2 > backup.sql
# 3. 備份所有使用者庫 (含 mysql 系統庫)
mysqldump [options] --all-databases > full_backup.sql
關鍵參數分類詳解
| 類別 | 參數 | 短參 | 功能 | 生產建議 |
| 輸出格式 | --extended-insert | -e | 多值 INSERT (批次 1000 行),大幅縮小檔案、加速還原 | 必開 (預設開啟) |
| --complete-insert | -c | 完整 INSERT 含欄位名 | 禁用 (檔案膨脹 30-50%,還原較慢) |
| --hex-blob | | BINARY/BLOB 以 0x 十六進位輸出 | 必開 (避免字符集轉換損壞二進位) |
| --quote-names | | 反引號包裹識別符 | 必開 (預設) |
| --tab=dir | -T | 每表產生 .sql (DDL) + .txt (資料) 分離檔案 | 大表並行匯入用 (配合 mysqlimport) |
| --fields-terminated-by=, | | 配合 -T 指定 CSV 分隔符 | 預設 \t |
| --fields-enclosed-by=\" | | 配合 -T 指定引用字符 | 標準 CSV 需雙引號 |
| --lines-terminated-by=\n | | 配合 -T 指定換行符 | Windows 檔案用 \r\n |
| 一致性與鎖 | --single-transaction | | InnoDB 一致性快照 (REPEATABLE READ),不阻塞寫入 | InnoDB 必用 |
| --lock-tables | -l | 鎖定所有表 (MyISAM/混合引擎) | 避免 (阻塞寫入),單庫用 --lock-all-tables |
| --lock-all-tables | -x | 全域讀鎖 (FLUSH TABLES WITH READ LOCK) | 僅非 InnoDB 環境最後手段 |
| --master-data=2 | | 輸出 CHANGE MASTER TO 註解 (位置點) | 建立從庫必備,2=註解不執行 |
| --dump-slave=2 | | 從庫備份時記錄主庫座標 | 從庫備份場景 |
| --apply-slave-statements | | 還原時自動執行 STOP/START SLAVE | 從庫遷移便利 |
| 物件選擇 | --no-create-info | -t | 僅導出資料 (無 CREATE TABLE) | 資料同步、增量合併 |
| --no-data | -d | 僅導出結構 (無 INSERT) | Schema 遷移、版本對比 |
| --routines | -R | 導出預存程序/函數 | 必開 |
| --triggers | | 導出觸發器 | 必開 (預設開啟) |
| --events | -E | 導出 Event 排程器任務 | 必開 |
| --ignore-table=db.tbl | | 排除指定表 (可多次) | 排除大日誌/臨時表 |
| --where='condition' | -w | 導出符合條件的資料 | 分片導出、歷史歸檔 |
| 效能與網路 | --quick | -q | 不緩衝結果集,直接串流輸出 (mysql_use_result) | 大表必開 (預設開啟) |
| --compress | -C | 客戶端-伺服端壓縮協議 | 跨機房/公網備份開啟 |
| --max-allowed-packet | | 最大封包大小 (預設 24M/1G) | 大 BLOB 表設 1G |
| --net-buffer-length | | 網路緩衝區大小 | 配合 max_allowed_packet |
| --order-by-primary | | 按主鍵排序導出 (利於還原插入) | InnoDB 叢集索引表建議開啟 |
| 其他 | --flush-logs | -F | 備份前切換 Binlog (配合增量備份) | 增量備份策略必用 |
| --force | -f | 忽略表錯誤繼續備份 | 損壞表搶救模式 |
| --skip-comments | | 不輸出版本/時間註解 | 自動化比對友善 |
| --set-gtid-purged=OFF|AUTO|ON | | 控制 GTID 集合輸出 | GTID 複寫環境 AUTO |
生產級備份命令模板
場景一:全量備份 (每日 02:00,保留 7 天)
#!/bin/bash
# /usr/local/bin/mysql_full_backup.sh
set -euo pipefail
BACKUP_DIR="/backup/mysql/full"
RETENTION_DAYS=7
MYSQL_OPTS="--defaults-file=/etc/mysql/backup.cnf" # 隔離備份帳號密碼
mkdir -p "$BACKUP_DIR"
FILENAME="${BACKUP_DIR}/full_$(date +%F_%H-%M-%S).sql.zst"
mysqldump $MYSQL_OPTS \
--single-transaction \
--routines --triggers --events \
--hex-blob \
--master-data=2 \
--flush-logs \
--all-databases \
| zstd -T0 -19 -q -o "$FILENAME" # Zstandard 極速高壓縮
# 刪除舊備份
find "$BACKUP_DIR" -name "full_*.sql.zst" -mtime +$RETENTION_DAYS -delete
# 校驗備份完整性
zstd -t "$FILENAME" && echo "$(date) Backup verified: $FILENAME" || exit 1
場景二:大表並行導出導入 (TB 級)
# 導出:每表獨立檔案,支援並行
mysqldump $MYSQL_OPTS \
--tab=/backup/mysql/tab \
--fields-terminated-by=',' \
--fields-enclosed-by='\"' \
--fields-escaped-by='\\' \
--lines-terminated-by='\n' \
--no-create-info \
--quick \
--single-transaction \
large_db huge_table1 huge_table2
# 並行導入 (8 併發)
cd /backup/mysql/tab
ls *.txt | parallel -j 8 "mysqlimport $MYSQL_OPTS --local --fields-terminated-by=',' --fields-enclosed-by='\"' --lines-terminated-by='\n' large_db {}"
# 結構單獨導入
mysqldump $MYSQL_OPTS --no-data --routines --triggers --events large_db > schema.sql
mysql $MYSQL_OPTS large_db < schema.sql
場景三:增量備份 (Binlog + 定期全量)
# 1. 全量備份時 --flush-logs --master-data=2 記錄 Binlog 位置
# 2. 持續複製 Binlog (mysqlbinlog --raw --stop-never)
mysqlbinlog --raw --stop-never --host=db-master --user=repl --password \
--result-file=/backup/mysql/binlog/ mysql-bin.000123
# 3. 恢復:全量 + Binlog 重放
mysql $MYSQL_OPTS < full_backup.sql
mysqlbinlog /backup/mysql/binlog/mysql-bin.000123 \
--start-position=12345 \
| mysql $MYSQL_OPTS
場景四:跨版本/跨引擎遷移 (MySQL 5.7 → 8.0)
# 1. 相容性檢查
mysqlcheck $MYSQL_OPTS --all-databases --check-upgrade
# 2. 導出 (排除 mysql 系統庫,避免權限表衝突)
mysqldump $MYSQL_OPTS \
--single-transaction \
--routines --triggers --events \
--hex-blob \
--column-statistics=0 \ # 8.0 客戶端備份 5.7 需關閉
--databases $(mysql $MYSQL_OPTS -NBe "SHOW DATABASES LIKE 'app_%'") \
> migration.sql
# 3. 目標庫預建帳號/權限 (勿導入 mysql.user)
# 4. 匯入前檢查
grep -i "DEFINER\|sql_mode\|TYPE=" migration.sql | head -20 # 手動修正
# 5. 匯入
mysql $MYSQL_OPTS < migration.sql
常見錯誤與對策
| 錯誤 | 原因 | 解決 |
| Got error: 1044 Access denied for user 'backup'@'%' to database 'mysql' | 備份帳號缺乏系統庫權限 | GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER, PROCESS ON *.* TO 'backup'@'%'; 或排除 mysql 库 |
| mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes | 單行/單欄位超過封包限制 | --max-allowed-packet=1G (客戶端)、伺服端同步調大 |
| Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions | GTID 環境部分備份 | --set-gtid-purged=OFF (不需 GTID) 或 AUTO (自動) |
| mysqldump: Couldn't execute 'SHOW FIELDS FROM tbl': Table 'db.tbl' doesn't exist | 備份過程中表被 DROP | --lock-tables / --single-transaction 確保一致性視圖 |
| Restore fails: Unknown collation 'utf8mb4_0900_ai_ci' | 8.0 備份導入 5.7 | sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' backup.sql |
備份驗證與演練 (不可省略)
- 校驗和:
sha256sum backup.sql.zst 記錄至備份清單
- 解壓測試:
zstd -t backup.sql.zst 每日自動執行
- 還原演練:每季度至少 1 次**在測試環境**完整還原驗證 RTO/RPO
- 資料抽樣比對:
SELECT COUNT(*), CHECKSUM TABLE 關鍵表源端 vs 目標端