php mysqli MySQL server has gone away 问题分析
结论
mysqli没有处理对端(MySQL server)的断开请求。在send时,收到对端(MySQL server)的RST,会打印MySQL server has gone away。
环境
xxxx@xxxx:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.4 (jessie)
Release: 8.4
Codename: jessie
xxxx@xxxx:~$ php --version
PHP 5.6.30 (cli) (built: Oct 27 2017 11:18:47) (DEBUG)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
MySQL server的官方解释
https://dev.mysql.com/doc/refman/5.7/en/gone-away.html
官方文档非常罗嗦,简单说来就是:
- 无效链接
1.关闭连接后仍然发起查询如超时断开、主动断开
2.fork子进程使用父进程的链接)。 - 查询太大。
- 无访问权限。
- 网络问题(防火墙等)。
都可能造成MySQL server has gone away。
而我遇到的问题属于无效链接。
抓包分析

可以看到。
No.469 是 MySQL server的tcp断开请求,apache的工作进程并没有返回FIN。
netstat的结果也证明了这一点:
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 11439/mysqld
tcp 1 0 127.0.0.1:56236 127.0.0.1:3306 CLOSE_WAIT 21523/apache2
tcp 1 0 127.0.0.1:56196 127.0.0.1:3306 CLOSE_WAIT 21466/apache2
tcp 1 0 127.0.0.1:56191 127.0.0.1:3306 CLOSE_WAIT 21523/apache2
tcp 0 0 127.0.0.1:3306 127.0.0.1:56247 FIN_WAIT2 -
tcp 0 0 127.0.0.1:3306 127.0.0.1:56236 FIN_WAIT2 -
tcp 1 0 127.0.0.1:56247 127.0.0.1:3306 CLOSE_WAIT 21466/apache2
No.2113 是 MySQL client 的 Change User 请求,值得注意的是,仍然用原端口(链接)和MySQL server通信。被MySQL server RST,触发MySQL server has gone away
开始我认为这是一个BUG,于是开始从源码中寻找答案。
源码分析
在脚本层定位到链接、报错发生在:
$this->_mysqli->real_connect
对应的c函数:
mysqli_noapi.c:mysqli_common_connect
因为链接由apache工作进程持有,mysqli拓展作为动态库载入,若apache需要对MySQL server的FIN包做出处理,mysqli 拓展必须在建立链接时,将链接ID传给apache。
但我没找到这样的逻辑。
结论是:
实现就是如此。MySQL断开链接时,mysqli对失效链接无任何处理。
mysqli在send时才能发现链接失效,若链接失败,会重连一次。
调试证实
No.2113 被RST
mysqlnd_auth.c:226,单步执行后,tcpdump抓到
15:21:20.300274 IP localhost.i.nease.net.56230 > localhost.i.nease.net.mysql: Flags [P.], seq 2540548209:2540548279, ack 3116587272, win 86, options [nop,nop,TS val 888121188 ecr 888020891], length 70
15:21:20.300305 IP localhost.i.nease.net.mysql > localhost.i.nease.net.56230: Flags [R], seq 3116587272, win 0, length 0
错误信息来源:
mysqlnd_auth.c:234
(gdb) n
234 COPY_CLIENT_ERROR(*conn->error_info, chg_user_resp->error_info);
(gdb) p conn->error_info.error
$14 = "MySQL server has gone away", '\000' <repeats 486 times>
mysqli使用失效链接时,被MySQL server RST。
重连
mysqli_nonapi.c
244 if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
(gdb) n
tcpdump 结果
15:27:33.105716 IP localhost.i.nease.net.56247 > localhost.i.nease.net.mysql: Flags [S], seq 842214159, win 43690, options [mss 65495,sackOK,TS val 888214389 ecr 0,nop,wscale 9], length 0
15:27:33.105738 IP localhost.i.nease.net.mysql > localhost.i.nease.net.56247: Flags [S.], seq 3337503184, ack 842214160, win 43690, options [mss 65495,sackOK,TS val 888214389 ecr 888214389,nop,wscale 9], length 0
15:27:33.105771 IP localhost.i.nease.net.56247 > localhost.i.nease.net.mysql: Flags [.], ack 1, win 86, options [nop,nop,TS val 888214389 ecr 888214389], length 0
15:27:33.106227 IP localhost.i.nease.net.mysql > localhost.i.nease.net.56247: Flags [P.], seq 1:79, ack 1, win 86, options [nop,nop,TS val 888214389 ecr 888214389], length 78
15:27:33.106241 IP localhost.i.nease.net.56247 > localhost.i.nease.net.mysql: Flags [.], ack 79, win 86, options [nop,nop,TS val 888214389 ecr 888214389], length 0
15:27:33.106362 IP localhost.i.nease.net.56247 > localhost.i.nease.net.mysql: Flags [P.], seq 1:122, ack 79, win 86, options [nop,nop,TS val 888214389 ecr 888214389], length 121
15:27:33.106373 IP localhost.i.nease.net.mysql > localhost.i.nease.net.56247: Flags [.], ack 122, win 86, options [nop,nop,TS val 888214389 ecr 888214389], length 0
15:27:33.106479 IP localhost.i.nease.net.mysql > localhost.i.nease.net.56247: Flags [P.], seq 79:90, ack 122, win 86, options [nop,nop,TS val 888214389 ecr 888214389], length 11
15:27:33.142634 IP localhost.i.nease.net.56247 > localhost.i.nease.net.mysql: Flags [.], ack 90, win 86, options [nop,nop,TS val 888214399 ecr 888214389], length 0
可以看到。因mysqli_common_connect在链接失效时,会重试一次。
项目使用了pconnect,大量长链接因空闲超时被断开,下次请求时,链接失效会导致gone away,因为有重连。该报错可忽略。
php mysqli MySQL server has gone away 问题分析的更多相关文章
- Python pandas ERROR 2006 (HY000): MySQL server has gone away
之前在做python pandas大数据分析的时候,在将分析后的数据存入mysql的时候报ERROR 2006 (HY000): MySQL server has gone away 原因分析:在对百 ...
- gearman中worker常驻后台,导致MySQL server has gone away
产生这个原因主要有如下几点: 1.mysql服务宕机了 2.长时间没有操作,超过了wait_timeout的设置,mysql自动断开 3.mysql请求链接被主动kill 4.发送的请求或返回结果过大 ...
- phpMyAdmin出现找不到mysql扩展和Cannot log in to the MySQL server问题
环境:Centos6.5,Apache2.4, PHP5.5, MySql5.6. phpMyAdmin版本:https://files.phpmyadmin.net/phpMyAdmin/4.4.1 ...
- 2003-Can't connect to mysql server on localhost (10061)
mysql数据库出现2003-Can't connect to mysql server on localhost (10061)问题 解决办法:查看wampserver服务器是否启动,如果没有启动启 ...
- ERROR 2003 (HY000): Can't connect to MySQL server on 'ip address' (111)的处理办法
远程连接mysql数据库时可以使用以下指令 mysql -h 192.168.1.104 -u root -p 如果是初次安装mysql,需要将所有/etc/mysql/内的所有配置文件的bind-a ...
- mySql 远程连接(is not allowed to connect to this MySQL server)
如果你想连接你的mysql的时候发生这个错误: ERROR 1130: Host '192.168.1.3' is not allowed to connect to this MySQL serve ...
- 报错:1130-host ... is not allowed to connect to this MySql server
报错:1130-host ... is not allowed to connect to this MySql server 解决方法: 1. 改表法. 可能是你的帐号不允许从远程登陆,只能在l ...
- 连接Mysql提示Can’t connect to local MySQL server through socket的解决方法
mysql,mysqldump,Mysqladmin,php连接mysql服务常会提示下面错误: ERROR 2002 (HY000): Can't connect to local MySQL se ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
有时候,当我们使用"mysql"."mysqladmin"."mysqldump"等命令管理数据库时,服务器抛出类似如下错误: 一.错误现场 ...
随机推荐
- 201521123015 《Java程序设计》第9周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...
- 猴子吃桃问题(南阳ACM324)
猴子吃桃问题 时间限制:3000 ms | 内存限制:65535 KB 难度:0 描述 有一堆桃子不知数目,猴子第一天吃掉一半,又多吃了一个,第二天照此方法,吃掉剩下桃子的一半又多一个,天天如此, ...
- windows 2008 R2操作系统上使用iis服务运行php和mysql数据库的网站遇到的验证码不显示问题?
1,本地运行正常,路径没问题. 2,GD2.dll开启 3,IIS服务正常开启,并启用父路径为True 4,检查是否IIS服务中FSO权限问题 开始 -> 程序 -> 管理工具 -> ...
- Hibernate第二篇【API讲解、执行流程图】
前言 从上一篇中已经大致介绍了Hibernate并且有了一个快速入门案例的基础了,-.本博文主要讲解Hibernate API 我们看看快速入门案例的代码用到了什么对象吧,然后一个一个讲解 publi ...
- 凸包GiftWrapping GrahamScan 算法实现
开始 游戏内有需求做多边形碰撞功能,但是接入box2d相对游戏的需求来说太重度了.所以准备自己实现碰撞. 确定多边形,必然要用到凸包的算法.在github上也找到了一些lua实现,但是这里的算法没有考 ...
- STM32获取DHT11温度传感器数据
准备物件 STM32F103C8T6核心板 ST-LINK V2 DHT11 杜邦线若干 连接线 STM32F103C8T6芯片管脚图 管脚说明 连接仿真器 STM32 ST-LINKV2 VCC V ...
- webpack2系列step1
第一篇:HTML 本文将一步一步的介绍webpack2的配置,从最基础的一直到与node结合. 操作都一样: midir step1 && cd step1 npm init -y n ...
- MySql join on 和 where
原文:http://www.cnblogs.com/Jessy/p/3525419.html left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录. right join : ...
- Linux入门之常用命令(13) crontab
为当前用户创建cron服务 1. 键入 crontab -e 编辑crontab服务文件 例如 文件内容如下: */2 * * * * /bin/sh /home/admin/jiaoben/bu ...
- Bmob云IM实现头像更换并存入Bmob云数据库中(1.拍照替换,2.相册选择)
看图效果如下: 1.个人资料界面 2.点击头像弹出对话框 3.点击拍照 4.切割图片,选择合适的部分 5.点击保存,头像替换完毕,下面看从相册中选择图片. 6.点击相册 7.任选一张图片 8.切割图片 ...