在使用 mysql < dump.sql 或 source 匯入大型 SQL 檔案時,常遇到以下錯誤:
ERROR 2013 (HY000): Lost connection to MySQL server during query ERROR 2006 (HY000): MySQL server has gone away ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
這通常不是網路問題,而是**單次 INSERT 陳述式過大**導致封包超過 max_allowed_packet 或執行時間過長觸發 wait_timeout/net_read_timeout。
使用 mysqldump 匯出資料時,加上 --skip-extended-insert 參數,將多列合併的 INSERT INTO ... VALUES (...),(...),... 拆分為逐列獨立的 INSERT:
mysqldump -u root -p --skip-extended-insert db_name > dump.sql
雖然檔案體積會變大、匯入速度略慢,但能避免單一封包過大導致連線中斷。
若資料量極大或不想改變匯出方式,可調整 my.cnf(或 my.ini)中的以下參數並重啟 MySQL:
| 參數 | 建議值 | 說明 |
|---|---|---|
| max_allowed_packet | 256M ~ 1G | 單次封包最大容量,預設常為 4M/16M,大量資料必須調大 |
| wait_timeout | 600 | 非互動連線等待秒數,預設 28800,匯入大檔案時可適度調大 |
| net_read_timeout | 600 | 讀取封包超時秒數,預設 30 秒,大交易需調大 |
| net_write_timeout | 600 | 寫入封包超時秒數 |
/var/log/mysqld.log 或 journalctl -u mysqld 確認是否 OOM Killer 殺掉進程(記憶體不足),需增加 Swap 或升級記憶體。my.cnf,統一指定 socket=/var/lib/mysql/mysql.sock。innodb_log_file_size 過小導致大交易無法寫入,建議設為 256M 以上。本文測試環境:mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64)。新版 MySQL (5.7/8.0) 預設 max_allowed_packet 已提升至 64M,但大量資料仍建議使用 --skip-extended-insert。