1. 程式人生 > 其它 >mysqlimport匯入報錯的排查(r10筆記第58天)

mysqlimport匯入報錯的排查(r10筆記第58天)

今天有個同事問我一個mysqlimport匯入的問題,看起來還是蠻奇怪的。同事在客戶端匯入一個檔案。檔案大小是2.8G,然後報錯mysqlimport: Error: 2013, Lost connection to MySQL server during query 對於這個問題我的第一感覺是一臺雲伺服器,是不是沒有配置swap造成的原因,因為在之前的一次遷移中,被這類問題折磨壞了,遭遇了OOM-Killer的問題,最後發現是swap沒有配置導致的。 但是同事經過確認,這是一臺實體機,而且檢視硬體情況,配置還不錯。buffer_pool_size有50多G,swap也配置了。看來這個問題的原因初步排除了。 對於這個問題,網路上也有很多種說法。有的說是max_allowed_packets導致。檢視當前的配置是1G,看起來是比匯入檔案小了。 不過從Oracle中的經驗來看,似乎這個說法也不是完全靠得住的,如果我匯入一個100G的dump,那這個引數還要配置超過100G,好像聽起來也不大合理啊。而且也沒見過有環境配置一個極高的值。 為此我做了幾個簡單的測試。 首先找了一個測試環境,max_allowed_packets為30多M. # mysqladmin var|grep max_all | max_allowed_packet | 33554432 | slave_max_allowed_packet | 1073741824

鎖定了一個小表. ]> select count(*)from t_fund_info; +----------+ | count(*) | +----------+ | 1998067 | 通過檢視檔案大小,大概是400多M. -rw-rw---- 1 mysql mysql 482344960 Oct 13 16:01 t_fund_info.ibd 這樣就可以輕鬆模擬測試max_allowed_packets的場景了。 首先匯出檔案。 > select * from t_fund_info into outfile '/tmp/t_fund_info.txt'; Query OK, 1998067 rows affected (6.82 sec)
匯出的文字檔案有近300M ll t_fund_info.txt -rw-rw-rw- 1 mysql mysql 291963062 Oct 20 22:25 t_fund_info.txt 然後使用最簡單的命令來匯入: mysqlimport test '/tmp/t_fund_info.txt' 短暫的等待之後,成功匯入。 可以看到慢日誌的輸出如下: # Time: 161020 22:31:49 # User@Host: root[root] @ localhost [] # Thread_id: 4321910 Schema: test Last_errno: 0 Killed: 0 # Query_time: 92.866443 Lock_time: 0.000074 Rows_sent: 0 Rows_examined: 0 Rows_affected: 1998067 Rows_read: 0 # Bytes_sent: 68 SET timestamp=1476973909; LOAD DATA INFILE '/tmp/t_fund_info.txt' INTO TABLE `t_fund_info` IGNORE 0 LINES;
原來mysqlimport會轉換為load data 的形式。 然後delete,truncate,drop重建,都可以成功匯入。 是哪裡測試的不到位嗎,我開始審視這個問題,我們可以在測試環境中模擬這個問題,以當時出問題的資料為準。然後檢視同事提供的日誌和截圖,發現當時使用的命令是 mysqlimport test '/tmp/t_charextra.txt' --local --delete --default-character=gbk 這個表的字符集經過確認是latin,所以就在懷疑是不是因為字符集轉換造成的。 ENGINE=InnoDB DEFAULT CHARSET=latin1 但是短暫的等待之後,還是可以成功匯入。 # mysqlimport test '/tmp/t_charextra.txt' --local --delete --default-character=gbk test.t_charextra: Records: 480174 Deleted: 0 Skipped: 0 Warnings: 0 在表t_charextra存在大量資料的前提下,我們繼續嘗試上面的方法匯入。 整個匯入就會分為兩部分, SET timestamp=1476975647; DELETE FROM t_charextra SET timestamp=1476975748; LOAD DATA LOCAL INFILE '/tmp/t_charextra.txt' INTO TABLE `t_charextra` IGNORE 0 LINES; 還是能夠成功匯入 # mysqlimport test '/tmp/t_charextra.txt' --local --delete --default-character=gbk test.t_charextra: Records: 480174 Deleted: 0 Skipped: 0 Warnings: 0 是哪裡測試的不到位嗎,現在唯一能夠想到的就是兩點,一是通過客戶端呼叫,而是客戶端和服務端的網路延遲較大。 配置了客戶端使用者,把匯出的文字拷貝到客戶端來複現問題。 > grant select,insert,delete on test.* to [email protected] identified by 'mysqlnew'; Query OK, 0 rows affected (0.02 sec) 然後使用下面的命令來嘗試客戶端匯入。 # mysqlimport -h 10.127.xxxx -utestdb -pmysqlnew test '/U01/t_charextra.txt' --local --delete --default-character=gbk Warning: Using unique option prefix default-character instead of default-character-set is deprecated and will be removed in a future release. Please use the full name instead. test.t_charextra: Records: 480174 Deleted: 0 Skipped: 0 Warnings: 0 從日誌看除了丟擲一個警告外,一切都很正常,所以現在的重點就落在了網路上,這一點還是需要進一步確認,不過目前來看已經排除了不少原因,想必原因也快揭曉了。問題背後的原因也會在確認之後進行更多的論證和分析,敬請期待。