mysqlimport匯入報錯的排查

jeanron100發表於2016-10-20
今天有個同事問我一個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 testdb@10.127.133.86 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
從日誌看除了丟擲一個警告外,一切都很正常,所以現在的重點就落在了網路上,這一點還是需要進一步確認,不過目前來看已經排除了不少原因,想必原因也快揭曉了。問題背後的原因也會在確認之後進行更多的論證和分析,敬請期待。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2126844/,如需轉載,請註明出處,否則將追究法律責任。

相關文章