程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> mysqldump意外終止的原因以及解決方法

mysqldump意外終止的原因以及解決方法

編輯:關於MYSQL數據庫

引子     

MySQLdump是非常重要的MySQL備份工具。然而在長年累月的使用過程中,TAOBAO多次出現了因MySQLdump意外終止而導致備份失敗的情況。

以下是我們經常遇到的問題:

1、Lost connection to MySQL Server at ‘reading initial communication packet’:

這個主要是因為DNS不穩定導致的。如果做了網絡隔離,MySQL處於一個相對安全的網絡環境,那麼開啟skip-name-resolve選項將會最大程度避免這個問題。

2、Lost connection to MySQL Server at ‘reading authorization packet’:

從MySQL獲取一個可用的連接是多次握手的結果。在多次握手的過程中,網絡波動會導致握手失敗。增加connect_timeout可以解決這個問題;然而增加connect_timeout並不能防止網絡故障的發生,反而會引起MySQL線程占用。最好的解決辦法是讓MySQLdump重新發起連接請求。

3、Lost connection to MySQL Server during query:

這個問題具備隨機性,而淘寶MySQL的應用場景決定了我們無法多次備份數據以便重現問題。

然而我們注意到這個問題一般會在兩種情況下會發生。一種是mysqldump **** | gzip ****;另外一種是MySQLdump **** > /nfs-file

注意,不管是gzip還是nfs都有一種特點,那就是它們影響了mysqldump的速度。從這個角度思考,是不是mysqldump從MySQL接受數據包的速度不夠快導致Lost connection to MySQL Server during query錯誤呢?

為了定位到問題,我搭建了一個測試環境:

[email protected]:3306

CREATE TABLE `test` (

`id` bigint(20) NOT NULL auto_increment,

`b` varchar(2000) default NULL,

`c` varchar(2000) default NULL,

`d` varchar(2000) default NULL,

`e` varchar(2000) default NULL,

PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

insert into test(b,c,d,e) values (lpad(‘a’,1900,’b'), lpad(‘a’,1900,’b'), lpad(‘a’,1900,’b'), lpad(‘a’,1900,’b'));

多次復制數據使測試環境達到一定數據量。

192.168.0.2:

編寫一個c++程序

#include <stdio.h>

#include <MySQL.h>

using namespace std;

int main()

MySQL conn;

MySQL_RES *result;

MySQL_ROW row;

my_bool reconnect = 0;

MySQL_init(&conn);

mysql_options(&conn, MySQL_OPT_RECONNECT, &reconnect);

if(!MySQL_real_connect(&conn, “192.168.0.1″, “test”, “test”, “test”, 3306, NULL, 0))

fprintf(stderr, “Failed to connect to database: %s\n”, MySQL_error(&conn));

exit(0);

else

fprintf(stdout, “Success to connect\n”);

MySQL_query(&conn, “show variables like ‘%timeout%’”);

result = MySQL_use_result(&conn);

while(row=MySQL_fetch_row(result))

fprintf(stdout, “%-10s: %s\n”, row[0], row[1]);

MySQL_free_result(result);

fprintf(stderr, “\n”);

MySQL_query(&conn, “select SQL_NO_CACHE * from test.test”);

result = MySQL_use_result(&conn);

while((row=MySQL_fetch_row(result))!=NULL)

fprintf(stderr, “Error %d: %s\n”, mysql_errno(&conn), MySQL_error(&conn));

fprintf(stdout, “%s\n”, row[0]);

sleep(100);

fprintf(stderr, “Error %d: %s\n”, mysql_errno(&conn), MySQL_error(&conn));

MySQL_free_result(result);

MySQL_close(&conn);

return 1;

在這段代碼裡,sleep函數用來模擬NFS的網絡延遲和gzip的運算時間。執行一段時間之後,Lost connection to MySQL Server during query出現了,程序意外終止。在數據處理足夠快的情況下,又會是怎樣的結果?

將sleep的時間改為1,重新編譯後發現程序能夠完整跑完。根據上對net_write_timeout的解釋,我們可以發現,mysqldump處理數據過慢(NFS、gzip引起)會導致MySQL主動斷開連接,此時MySQLdump就會報Lost connection to MySQL Server during query錯誤。經過多次測試,確定這個錯誤是由於net_write_timeout設置過短引起。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved