Mysql server出現“Mysql server has gone away”的錯誤的解決方式
一、最常見的原因分析及解決方法 wait_timeout 和 interactive_timeout
出現該問題的主要原因是:Mysql server伺服器超時,並且關閉了與客戶端的連線導致的。在這種情況下,你一般會得到下面的兩種錯誤中的一種(具體取決於你的作業系統):
|————–錯誤碼———— | ———————————–錯誤描述——————————-|
CR_SERVER_GONE_ERROR:The client couldn’t send a question to the server.
CR_SERVER_LOST:The client didn’t get an error when writing to the server, but it didn’t get a full answer (or any answer) to the question.
預設情況下,如果在8小時沒有對mysql進行查詢請求的話,伺服器就會自動斷開連線。可以通過修改全域性變數 wait_timeout和interactive_timeout兩個變數的值來進行修改。
$ mysql -u root -p
$ mysql>show variables like '%timeout';
$ mysql>set global wait_timeout = 2880000;
$ mysql>set global interactive_timeout = 2880000;
interactive_timeout:互動式客戶端連線的超時時間。
wait_timeout:是非互動式的超時時間。
client_interactive:執行mysql server 在互動式超時時間interactive_timeout(而不是wait_timeout)時間之後斷開連線。
簡單的說 interactive就是互動式的終端,例如在shell裡面直接執行mysql,出現形如mysql>的提示符後就是互動式的連線。而mysql -e ‘select 1’ 這樣的直接返回結果的方式就是非互動式的連線。
繼承關係
1.通過socket連線 timeout會從哪個global timeout繼承 A:由下例可見,通過socket登入,timeout 繼承於global.interactive_timeout;
mysql> set global interactive_timeout = 11111;
Query OK, 0 rows affected (0.00 sec)
mysql> set global wait_timeout = 22222;
Query OK, 0 rows affected (0.00 sec)
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 | 11111 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 22222 |
+----------------------------+----------+
10 rows in set (0.00 sec)
mysql -uroot -ppassword -S /usr/local/mysql3310/mysql.sock
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.16-log MySQL Community Server (GPL)
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show session 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 | 11111 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 11111 |
+----------------------------+----------+
10 rows in set (0.00 sec)
通過TCP/IP client 連線, timeout會從哪個global timeout繼承 A:由下例可見,通過TCP/IP client 連線後的wait_timeout 仍然繼承於 global.interactive_timeout
mysql -uroot -ppassword -h 127.0.0.1 --port 3310
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.5.16-log MySQL Community Server (GPL)
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show session 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 | 11111 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 11111 |
+----------------------------+----------+
10 rows in set (0.00 sec)
起效關係
timeout值,對於處於執行狀態SQL語句是否起效(即是否等價於執行超時)? A:由下例可見SQL正在執行狀態的等待時間不計入timeout時間。即SQL執行再久也不會因為timeout的配置而中斷
mysql> set session wait_timeout=10;
Query OK, 0 rows affected (0.00 sec)
mysql> set session interactive_timeout=10;
Query OK, 0 rows affected (0.00 sec)
mysql> select 1,sleep(20) from dual;
+---+-----------+
| 1 | sleep(20) |
+---+-----------+
| 1 | 0 |
+---+-----------+
1 row in set (20.00 sec)
mysql>
mysql> show session 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 | 10 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 10 |
+----------------------------+----------+
同一個session中,wait_timeout 和 interacitve_timeout是否都會生效。 A:只有wait_timeout 會真正起到超時限制的作用
mysql> set session interactive_timeout=10;
Query OK, 0 rows affected (0.00 sec)
mysql> set session wait_timeout=20;
Query OK, 0 rows affected (0.00 sec)
mysql> show full processlist;
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| 1 | system user | | NULL | Connect | 103749 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL | 0 | 0 | 1 |
| 2 | system user | | NULL | Connect | 103750 | Connecting to master | NULL | 0 | 0 | 1 |
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist | 0 | 0 | 11 |
| 10 | root | localhost:58946 | NULL | Sleep | 20 | | NULL | 0 | 0 | 11 |
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
4 rows in set (0.00 sec)
mysql> show full processlist;
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| 1 | system user | | NULL | Connect | 103749 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL | 0 | 0 | 1 |
| 2 | system user | | NULL | Connect | 103750 | Connecting to master | NULL | 0 | 0 | 1 |
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist | 0 | 0 | 11 |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
3 rows in set (0.00 sec)
global timeout和session timeout是否都會作為超時判斷依據? A:只有session級別 timeout 會起作用。即一個session開始後,無論如何修改global級別的timeout都不會影響該session
mysql> set session interactive_timeout = 10;
Query OK, 0 rows affected (0.00 sec)
mysql> set session wait_timeout = 10;
Query OK, 0 rows affected (0.00 sec)
mysql> show session variables like '%timeout%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| interactive_timeout | 10 |
| wait_timeout | 10 |
+----------------------------+----------+
10 rows in set (0.00 sec)
mysql> show global variables like '%timeout%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| interactive_timeout | 20 |
| wait_timeout | 20 |
+----------------------------+----------+
10 rows in set (0.00 sec)
mysql> show full processlist;
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist | 0 | 0 | 11 |
| 17 | root | localhost:60585 | NULL | Sleep | 10 | | NULL | 10 | 10 | 11 |
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
2 rows in set (0.00 sec)
mysql> show full processlist;
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist | 0 | 0 | 11 |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
1 rows in set (0.00 sec)
測試2
mysql> show session variables like '%timeout%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| interactive_timeout | 20 |
| wait_timeout | 20 |
+----------------------------+----------+
10 rows in set (0.00 sec)
mysql> show global variables like '%timeout%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| interactive_timeout | 10 |
| wait_timeout | 10 |
+----------------------------+----------+
10 rows in set (0.00 sec)
mysql> show full processlist;
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist | 0 | 0 | 11 |
| 19 | root | localhost:50276 | NULL | Sleep | 19 | | NULL | 10 | 10 | 11 |
+----+-------------+-----------------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
2 rows in set (0.00 sec)
mysql> show full processlist;
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist | 0 | 0 | 11 |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------------------------------------+-----------------------+-----------+---------------+-----------+
1 rows in set (0.00 sec)
二、還有一種就是 你傳送給伺服器的查詢是錯誤的 或者太大了
這種情況下,需要修改 變數max_allowed_packet的大小
$ mysql> set global max_allowed_packet = 64M;
三、其他問題見官方文件
Reference:解決方式參考
修改過程中遇到的其他問題
沒有通過mysql command line來修改變數的時候 是通過在/etc/mysql/my.cnf中新增變數來修改的,
max_allowed_packet = 64M
wait_timeout = 2880000
interactive_timeout = 2880000
這種方式。但是修改完之後重啟mysql service的時候 就出問題了,報錯:“Job for mysql.service failed because the control process exited with error code , see systemctl status mysql.service and journalctl -xe for details”(這裡是因為語法出錯了,要在變數設定前 加上[mysqld]標誌)
於是註釋掉了 上面的變數修改,但是還是不起作用
後來通過Stackoverflow查到了,能夠解決問題的答案:
1.Check the permission of mysql data dir using below command
# ls -ld /var/lib/mysql/
2.Check the permission of databases inside mysql data dir using below command
# ls -lh /var/lib/mysql/
3.Check the listening network tcp ports using below command
# netstat -ntlp
4.Check the mysql log files for any error using below command.
# cat /var/log/mysql/mysqld.log
5.Try to start mysql using below command
# mysqld_safe --defaults-file=/etc/my.cf
我的問題在執行完最後一條之後 就解決了,但是安裝的PHPMyadmin不能連線上了 ,所以又通過下面的命令:
$ sudo service mysql restart
重啟了下 就好了。
附加內容:在使用Mysql server的時候出現 “Mysql server has gone away”的時候 ,大概有兩個方面的原因:
一是 查詢太大 太長
二是 連線超時自動斷開(這個是最常見的錯誤)
這兩個修改方式都是 設定[mysqld]中的變數:
[mysqld]
max_allowed_packet = 64M
wait_timeout = 2880000
interactive_timeout = 2880000
當時在 /etc/mysql/my.cnf中修改的時候 沒有加上 [mysqld]這個標誌 導致語法錯誤 而不能啟動mysql
還有網上別人遇到的錯誤是 修改了變數之後沒有生效。
這個方面的原因大概就是:
my.cnf中 還有引用了兩個地方的設定:
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
這兩個檔案裡面的mysql.conf配置也會被引進來 ,導致my.cnf中的配置被這兩個檔案中的配置覆蓋。
所以儘量到這兩個檔案中,去修改需要修改的變數。