MySQL server has gone away 成績的處理辦法。本站提示廣大學習愛好者:(MySQL server has gone away 成績的處理辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL server has gone away 成績的處理辦法正文
mysql湧現ERROR : (2006, 'MySQL server has gone away') 的成績意思就是指client和MySQL server之間的鏈接斷開了。
形成如許的緣由普通是sql操作的時光太長,或許是傳送的數據太年夜(例如應用insert ... values的語句太長, 這類情形可以經由過程修正max_allowed_packed的設置裝備擺設參數來防止,也能夠在法式中將數據分批拔出)。
發生這個成績的緣由有許多,總結下網上的剖析:
緣由一. MySQL 辦事宕了
斷定能否屬於這個緣由的辦法很簡略,進入mysql掌握台,檢查mysql的運轉時長
mysql> show global status like 'uptime';
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Uptime | 3414707 |
+---------------+---------+
1 row in set或許檢查MySQL的報錯日記,看看有無重啟的信息
假如uptime數值很年夜,注解mysql辦事運轉了良久了。解釋比來辦事沒有重啟過。
假如日記沒有相干信息,也表名mysql辦事比來沒有重啟過,可以持續檢討上面幾項內容。
緣由二. mysql銜接超時
即某個mysql長銜接良久沒有新的要求提議,到達了server真個timeout,被server強行封閉。
爾後再經由過程這個connection提議查詢的時刻,就會報錯server has gone away
(年夜部門PHP劇本就是屬於此類)
mysql> show global variables like '%timeout';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+----------------------------+----------+
10 rows in set
wait_timeout 是28800秒,即mysql鏈接在無操作28800秒後被主動封閉
緣由三. mysql要求鏈接過程被自動kill
這類情形和緣由二類似,只是一個是工資一個是MYSQL本身的舉措
mysql> show global status like 'com_kill';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_kill | 21 |
+---------------+-------+
1 row in set緣由四. Your SQL statement was too large.
當查詢的成果集跨越 max_allowed_packet 也會湧現如許的報錯。定位辦法是打出相干報錯的語句。
用select * into outfile 的方法導出到文件,檢查文件年夜小能否跨越 max_allowed_packet ,假如跨越則須要調劑參數,或許優化語句。
mysql> show global variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name | Value |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+
1 row in set (0.00 sec)
修正參數:
mysql> set global max_allowed_packet=1024*1024*16;
mysql> show global variables like 'max_allowed_packet';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
1 row in set (0.00 sec)
以下是彌補:
運用法式(好比PHP)長時光的履行批量的MYSQL語句。履行一個SQL,但SQL語句過年夜或許語句中含有BLOB或許longblob字段。好比,圖片數據的處置。都輕易惹起MySQL server has gone away。
明天碰到相似的情形,MySQL只是冷冷的說:MySQL server has gone away。
年夜概閱讀了一下,重要能夠是由於以下幾種緣由:
一種能夠是發送的SQL語句太長,乃至跨越了max_allowed_packet的年夜小,假如是這類緣由,你只需修正my.cnf,加年夜max_allowed_packet的值便可。
還有一種能夠是由於某些緣由招致超時,好比說法式中獲得數據庫銜接時采取了Singleton的做法,固然屢次銜接數據庫,但其實應用的都是統一個銜接,並且法式中某兩次操作數據庫的距離時光跨越了wait_timeout(SHOW STATUS能看到此設置),那末便可能湧現成績。最簡略的處置方法就是把wait_timeout改年夜,固然你也能夠在法式裡時不時隨手mysql_ping()一下,如許MySQL就曉得它不是一小我在戰役。
處理MySQL server has gone away
1、運用法式(好比PHP)長時光的履行批量的MYSQL語句。最多見的就是收集或許新舊數據轉化。
處理計劃:
在my.cnf文件中添加或許修正以下兩個變量:
wait_timeout=2880000
interactive_timeout = 2880000
關於兩個變量的詳細解釋可以谷歌或許看官方手冊。假如不克不及修正my.cnf,則可以在銜接數據庫的時刻設置CLIENT_INTERACTIVE,好比:
sql = "set interactive_timeout=24*3600";
mysql_real_query(...)
2、履行一個SQL,但SQL語句過年夜或許語句中含有BLOB或許longblob字段。好比,圖片數據的處置
處理計劃:
在my.cnf文件中添加或許修正以下變量:
max_allowed_packet = 10M(也能夠設置本身須要的年夜小)
max_allowed_packet 參數的感化是,用來掌握其通訊緩沖區的最年夜長度。
比來做網站有一個站要用到WEB網頁收集器功效,當一個PHP劇本在要求URL的時刻,能夠這個被要求的網頁異常漸漸,跨越了mysql的 wait-timeout時光,然後當網頁內容被抓回來後,預備拔出到MySQL的時刻,發明MySQL的銜接超時封閉了,因而就湧現了“MySQL server has gone away”如許的毛病提醒,處理這個成績,我的經歷有以下兩點,也許對年夜家有效處:
第 一種辦法:
固然是增長你的 wait-timeout值,這個參數是在my.cnf(在Windows上台上面是my.ini)中設置,我的數據庫負荷略微年夜一點,所以,我設置的值 為10,(這個值的單元是秒,意思是當一個數據庫銜接在10秒鐘內沒有任何操作的話,就會強行封閉,我應用的不是永遠鏈接 (mysql_pconnect),用的是mysql_connect,關於這個wait-timeout的後果你可以在MySQL的過程列表中看到 (show processlist) ),你可以把這個wait-timeout設置成更年夜,好比300秒,呵呵,普通來說300秒足夠用了,其實你也能夠不消設置,MySQL默許是8個小 時。情形由你的辦事器和站點來定。
第二種辦法:
這也是我小我以為最好的辦法,即檢討 MySQL的鏈接狀況,使其從新鏈接。
能夠年夜家都曉得有mysql_ping這麼一個函數,在許多材料中都說這個mysql_ping的 API會檢討數據庫能否鏈接,假如是斷開的話會測驗考試從新銜接,但在我的測試進程中發明現實其實不是如許子的,是有前提的,必需要經由過程 mysql_options這個C API傳遞相干參數,讓MYSQL有斷開主動鏈接的選項(MySQL默許為不主動銜接),但我測試中發明PHP的MySQL的API中其實不帶這個函數,你從新編纂MySQL吧,呵呵。但mysql_ping這個函數照樣終究能用得上的,只是要在個中有一個小小的操作技能:
這是我的的數據庫操 作類中央的一個函數
function ping(){
if(!mysql_ping($this->link)){
mysql_close($this->link); //留意:必定要先履行數據庫封閉,這是症結
$this->connect();
}
}
我須要挪用這個函數的代碼能夠是如許子的
$str = file_get_contents('http://www.jb51.net');
$db->ping();//經由後面的網頁抓取後,或許會招致數據庫銜接封閉,檢討偏重新銜接
$db->query('select * from table');
ping()這個函數先檢測數據銜接能否正常,假如被封閉,全部把以後劇本的MYSQL實例封閉,再從新銜接。
經 過如許處置後,可以異常有用的處理MySQL server has gone away如許的成績,並且不會對體系形成額定的開支。
__________________________________________________________________________________________________
明天碰到相似的情形,MySQL只是冷冷的說:MySQL server has gone away。
年夜概閱讀了一下,重要能夠是由於以下幾種緣由:
一種能夠是發送的SQL語句太長,乃至跨越了max_allowed_packet的年夜小,假如是這類緣由,你只需修正my.cnf,加年夜max_allowed_packet的值便可。
還有一種能夠是由於某些緣由招致超時,好比說法式中獲得數據庫銜接時采取了Singleton的做法,固然屢次銜接數據庫,但其實應用的都是統一個銜接,並且法式中某兩次操作數據庫的距離時光跨越了wait_timeout(SHOW STATUS能看到此設置),那末便可能湧現成績。最簡略的處置方法就是把wait_timeout改年夜,固然你也能夠在法式裡時不時隨手mysql_ping()一下,如許MySQL就曉得它不是一小我在戰役。
處理MySQL server has gone away
1、運用法式(好比PHP)長時光的履行批量的MYSQL語句。最多見的就是收集或許新舊數據轉化。
處理計劃:
在my.cnf文件中添加或許修正以下兩個變量:
wait_timeout=2880000
interactive_timeout = 2880000 關於兩個變量的詳細解釋可以谷歌或許看官方手冊。假如不克不及修正my.cnf,則可以在銜接數據庫的時刻設置CLIENT_INTERACTIVE,好比:
sql = "set interactive_timeout=24*3600";
mysql_real_query(...)
2、履行一個SQL,但SQL語句過年夜或許語句中含有BLOB或許longblob字段。好比,圖片數據的處置
處理計劃:
在my.cnf文件中添加或許修正以下變量:
max_allowed_packet = 10M(也能夠設置本身須要的年夜小)
max_allowed_packet參數的感化是,用來掌握其通訊緩沖區的最年夜長度。
1、運用法式(好比PHP)長時光的履行批量的MYSQL語句。
最多見的就是收集或許新舊數據轉化。
處理計劃:
在my.ini文件中添加或許修正以下兩個變量:
wait_timeout=2880000
interactive_timeout = 2880000
關於兩個變量的詳細解釋可以谷歌或許看官方手冊。
假如不克不及修正my.cnf,則可以在銜接數據庫的時刻設置CLIENT_INTERACTIVE,好比:
sql = "set interactive_timeout=24*3600";
mysql_real_query(...)
2、履行一個SQL,但SQL語句過年夜或許語句中含有BLOB或許longblob字段。
好比,圖片數據的處置
處理計劃
在my.cnf文件中添加或許修正以下變量:
max_allowed_packet = 10M (也能夠設置本身須要的年夜小)
max_allowed_packet 參數的感化是,用來掌握其通訊緩沖區的最年夜長度。
修正辦法
1) 辦法1
可以編纂my.cnf來修正(windows下my.ini),在[mysqld]段或許mysql的server設置裝備擺設段停止修正。
max_allowed_packet = 20M
假如找不到my.cnf可以經由過程
mysql --help | grep my.cnf
去尋覓my.cnf文件。
2) 辦法2
(很讓步,很糾結的方法)
進入mysql server
在mysql 敕令行中運轉
set global max_allowed_packet = 2*1024*1024*10
然後封閉失落這此mysql server鏈接,再進入。
show VARIABLES like '%max_allowed_packet%';
檢查下max_allowed_packet能否編纂勝利
------------ 以下是收集搜刮的材料 -------------------
或許其別人碰到這個成績,紛歧定是這兒的緣由,那末,就把我在網上找到比擬周全的剖析放到上面:
有兩篇,第一篇比擬直不雅,第二篇比擬深邃。
處理MySQL server has gone away 2009-01-09 16:23:22
明天碰到相似的情形,MySQL只是冷冷的說:MySQL server has gone away。
年夜概閱讀了一下,重要能夠是由於以下幾種緣由:
一種能夠是發送的SQL語句太長,乃至跨越了max_allowed_packet的年夜小,假如是這類緣由,你只需修正my.cnf,加年夜max_allowed_packet的值便可。
還有一種能夠是由於某些緣由招致超時,好比說法式中獲得數據庫銜接時采取了Singleton的做法,固然屢次銜接數據庫,但其實應用的都是統一個銜接,並且法式中某兩次操作數據庫的距離時光跨越了wait_timeout(SHOW STATUS能看到此設置),那末便可能湧現成績。最簡略的處置方法就是把wait_timeout改年夜,固然你也能夠在法式裡時不時隨手mysql_ping()一下,如許MySQL就曉得它不是一小我在戰役。
處理MySQL server has gone away
1、運用法式(好比PHP)長時光的履行批量的MYSQL語句。最多見的就是收集或許新舊數據轉化。
處理計劃:
在my.cnf文件中添加或許修正以下兩個變量:
wait_timeout=2880000
interactive_timeout = 2880000
關於兩個變量的詳細解釋可以谷歌或許看官方手冊。假如不克不及修正my.cnf,則可以在銜接數據庫的時刻設置CLIENT_INTERACTIVE,好比:
sql = "set interactive_timeout=24*3600";
mysql_real_query(...)
2、履行一個SQL,但SQL語句過年夜或許語句中含有BLOB或許longblob字段。好比,圖片數據的處置
處理計劃:
在my.cnf文件中添加或許修正以下變量:
max_allowed_packet = 10M
(也能夠設置本身須要的年夜小)
max_allowed_packet
參數的感化是,用來掌握其通訊緩沖區的最年夜長度
MySQL: 詭異的MySQL server has gone away及其處理
在Mysql履行show status,平日更存眷緩存後果、過程數等,常常疏忽了兩個值:
Variable_name Value
Aborted_clients 3792
Aborted_connects 376
平日只占query的0.0x%,所以其實不為人所看重。並且在傳統Web運用上,query毛病對用戶而言影響其實不年夜,只是從新刷新一下頁面就OK了。比來的基本改革中,把許多運用作為service運轉,沒法提醒用戶從新刷新,這類情形下,能夠就會影響到辦事的品德。
經由過程法式劇本的日記跟蹤,重要報錯信息為“MySQL server has gone away”。官方的說明是:
The most common reason for the MySQL server has gone away error is that the server timed out and closed the connection.
Some other common reasons for the MySQL server has gone away error are:
You (or the db administrator) has killed the running thread with a KILL statement or a mysqladmin kill command.
You tried to run a query after closing the connection to the server. This indicates a logic error in the application that should be corrected.
A client application running on a different host does not have the necessary privileges to connect to the MySQL server from that host.
You got a timeout from the TCP/IP connection on the client side. This may happen if you have been using the commands: mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...) or mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...). In this case increasing the timeout may help solve the problem.
You have encountered a timeout on the server side and the automatic reconnection in the client is disabled (the reconnect flag in the MYSQL structure is equal to 0).
You are using a Windows client and the server had dropped the connection (probably because wait_timeout expired) before the command was issued.
The problem on Windows is that in some cases MySQL doesn't get an error from the OS when writing to the TCP/IP connection to the server, but instead gets the error when trying to read the answer from the connection.
In this case, even if the reconnect flag in the MYSQL structure is equal to 1, MySQL does not automatically reconnect and re-issue the query as it doesn't know if the server did get the original query or not.
The solution to this is to either do a mysql_ping on the connection if there has been a long time since the last query (this is what MyODBC does) or set wait_timeout on the mysqld server so high that it in practice never times out.
You can also get these errors if you send a query to the server that is incorrect or too large. If mysqld receives a packet that is too large or out of order, it assumes that something has gone wrong with the client and closes the connection. If you need big queries (for example, if you are working with big BLOB columns), you can increase the query limit by setting the server's max_allowed_packet variable, which has a default value of 1MB. You may also need to increase the maximum packet size on the client end. More information on setting the packet size is given in Section A.1.2.9, “Packet too large”.
An INSERT or REPLACE statement that inserts a great many rows can also cause these sorts of errors. Either one of these statements sends a single request to the server irrespective of the number of rows to be inserted; thus, you can often avoid the error by reducing the number of rows sent per INSERT or REPLACE.
You also get a lost connection if you are sending a packet 16MB or larger if your client is older than 4.0.8 and your server is 4.0.8 and above, or the other way around.
It is also possible to see this error if hostname lookups fail (for example, if the DNS server on which your server or network relies goes down). This is because MySQL is dependent on the host system for name resolution, but has no way of knowing whether it is working — from MySQL's point of view the problem is indistinguishable from any other network timeout.
You may also see the MySQL server has gone away error if MySQL is started with the --skip-networking option.
Another networking issue that can cause this error occurs if the MySQL port (default 3306) is blocked by your firewall, thus preventing any connections at all to the MySQL server.
You can also encounter this error with applications that fork child processes, all of which try to use the same connection to the MySQL server. This can be avoided by using a separate connection for each child process.
You have encountered a bug where the server died while executing the query.
據此剖析,能夠緣由有3:
1,Mysql辦事端與客戶端版本不婚配。
2,Mysql辦事端設置裝備擺設出缺陷或許優化缺乏
3,須要改良法式劇本
經由過程改換多個辦事端與客戶端版本,發明只能部門削減報錯,其實不能完整處理。消除1。
對辦事端停止了完全的優化,也未能到達幻想後果。在timeout的取值設置上,從經歷值的10,到PHP默許的60,停止了屢次測驗考試。而Mysql官方默許值(8小時)顯著是弗成能的。從而對2也停止了消除。(更多優化的經歷分享,將在今後整頓供給)
針對3對法式代碼停止剖析,發明法式中年夜量運用了相似以下的代碼(為便於懂得,用原始api描寫):
$conn=mysql_connect( ... ... );
... ... ... ...
if(!$conn){ //reconnect
$conn=mysql_connect( ... ... );
}
mysql_query($sql, $conn);
這段代碼的寄義,與Mysql官方建議的辦法思緒符合[ If you have a script, you just have to issue the query again for the client to do an automatic reconnection. ]。在現實剖析中發明,if(!$conn)其實不是靠得住的,法式經由過程了if(!$conn)的磨練後,依然會前往上述毛病。
對法式停止了改寫:
if(!conn){ // connect ...}
elseif(!mysql_ping($conn)){ // reconnect ... }
mysql_query($sql, $conn);
經現實不雅測,MySQL server has gone away的報錯根本處理。
BTW: 附帶一個關於 reconnect 的疑問,
在php4x+client3x+mysql4x的舊情況下,reconnet的代碼:
$conn=mysql_connect(...) 可以正常任務。
然則,在php5x+client4x+mysql4x的新情況下,$conn=mysql_connect(...)前往的$conn有部門情形下弗成用。須要書寫為:
mysql_close($conn);
$conn=mysql_connect(...);
前往的$conn才可以正常應用。緣由未明。未做深刻研討,也未見相干評論辯論。也許mysql官方的BUG報告請示中會有吧。
~~呵呵~~
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/brightsnow/archive/2009/03/17/3997705.aspx
description:
remember that your MySQL "max_allowed_packet" configuration setting (default 1MB)
mysql 默許最年夜可以或許處置的是1MB
假如你在sql應用了年夜的text或許BLOB數據,就會湧現這個成績。 php手冊上的正文
When trying to INSERT or UPDATE and trying to put a large amount of text or data (blob) into a mysql table you might run into problems.
In mysql.err you might see:
Packet too large (73904)
To fix you just have to start up mysql with the option -O max_allowed_packet=maxsize
You would just replace maxsize with the max size you want to insert, the default is 65536
mysql手冊上說
Both the client and the server have their own max_allowed_packet variable, so if you want to handle big packets, you must increase this variable both in the client and in the server.
If you are using the mysql client program, its default max_allowed_packet variable is 16MB. To set a larger value, start mysql like this:
shell> mysql --max_allowed_packet=32M That sets the packet size to 32MB.
The server's default max_allowed_packet value is 1MB. You can increase this if the server needs to handle big queries (for example, if you are working with big BLOB columns). For example, to set the variable to 16MB, start the server like this:
shell> mysqld --max_allowed_packet=16M You can also use an option file to set max_allowed_packet. For example, to set the size for the server to 16MB, add the following lines in an option file:
[mysqld]max_allowed_packet=16M
應用mysql做數據庫復原的時刻,因為有些數據很年夜,會湧現如許的毛病:The MySQL Server returned this Error:MySQL Error Nr.2006-MySQL server has gone away。我的一個150mb的備份復原的時刻就湧現了這毛病。處理的辦法就是找到mysql裝置目次,找到my.ini文件,在文件的最初添加:max_allowed_packet = 10M(也能夠設置本身須要的年夜小)。 max_allowed_packet 參數的感化是,用來掌握其通訊緩沖區的最年夜長度。