命令行導入是資料庫遷移、備份恢復、環境初始化的核心技能。本文詳述 source 命令全流程操作、字符集設置避坑、大檔案導入優化參數、常見錯誤排查與自動化腳本模版,助你實現「零失誤、可追溯、高效能」的資料導入。
cd /path/to/mysql/binmysql -h localhost -u root -pmysql -u root -p)USE target_db;SET NAMES utf8mb4;SOURCE /absolute/path/to/backup.sql;導入前在會話中調整(或配置文件永久生效):
SET GLOBAL max_allowed_packet = 1073741824; -- 1GB SET GLOBAL net_buffer_length = 1048576; -- 1MB SET GLOBAL sql_log_bin = OFF; -- 關閉 Binlog 記錄,大幅提速、節省磁碟 SET GLOBAL foreign_key_checks = 0; -- 關閉外鍵檢查 SET GLOBAL unique_checks = 0; -- 關閉唯一性檢查 SET GLOBAL autocommit = 0; -- 關閉自動提交,手動事務控制 -- 導入結束後恢復 SET GLOBAL foreign_key_checks = 1; SET GLOBAL unique_checks = 1; SET GLOBAL autocommit = 1; SET GLOBAL sql_log_bin = ON;
若備份檔未包含事務控制,可手動包裹:
START TRANSACTION; SOURCE /path/to/backup.sql; COMMIT;
注意:超大事務會導致 Undo Log 膨脹、鎖持有時間過長,建議備份檔本身按表/批次包含 COMMIT,或使用 mysqldump --single-transaction 導出時自動包裹。
| 錯誤現象 | 根因 | 解決方案 |
|---|---|---|
| ERROR 1064 (42000): syntax error | SQL 檔編碼不匹配、含 BOM 頭、特殊字符未轉義 | 確認檔案 UTF-8 無 BOM、SET NAMES utf8mb4、檢查首行異常字符 |
| ERROR 2006 (HY000): MySQL server has gone away | 導入耗時超過 wait_timeout/max_allowed_packet | 調大上述參數、分割 SQL 檔、使用 mysql -e "source ..." 非交互模式 |
| ERROR 1153 (08S01): Got a packet bigger than max_allowed_packet | 單條 INSERT 過大(如大 BLOB/TEXT) | 調大 max_allowed_packet、拆分大行、改用 LOAD DATA |
| ERROR 1213 (40001): Deadlock found | 並發導入衝突、外鍵順序依賴 | 串行導入、關閉外鍵檢查、按拓撲序導入 |
| 中文亂碼/截斷 | 連線字符集未設、表字符集非 utf8mb4 | 全鏈路 utf8mb4、SET NAMES utf8mb4、表轉換 CONVERT TO CHARSET utf8mb4 |
#!/bin/bash
# import_db.sh - 安全導入腳本
set -euo pipefail
DB_HOST="localhost"
DB_USER="root"
DB_PASS="your_password"
DB_NAME="target_db"
SQL_FILE="/data/backup/full_$(date +%F).sql"
# 參數校驗
[[ -f "$SQL_FILE" ]] || { echo "SQL file not found: $SQL_FILE"; exit 1; }
# 執行導入(管道模式避免交互超時)
mysql -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" \
--max_allowed_packet=1G --net_buffer_length=1M \
--default-character-set=utf8mb4 \
-e "SET foreign_key_checks=0; SET unique_checks=0; SET autocommit=0; SET sql_log_bin=0; USE \`$DB_NAME\`; SOURCE $SQL_FILE; COMMIT; SET foreign_key_checks=1; SET unique_checks=1; SET autocommit=1; SET sql_log_bin=1;"
echo "Import completed at $(date)"
exit 0
SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='db';SELECT COUNT(*) FROM core_table;CHECKSUM TABLE core_table; 對比源庫命令行導入看似簡單,細節決定成敗。建立「參數預熱 → 編碼對齊 → 事務控制 → 驗證收口」標準化動作,並封裝為可審計的自動化腳本,讓資料遷移從「祈禱不出錯」進化到「可控、可追溯、可複用」。