推送通知服务商遇MySQL 2006错误(仅CRON&Ajax场景)求解决方案
针对"MySQL server gone away 2006"错误的可行解决方案(CRON/Ajax场景)
根据你的环境和已做的排查,这个错误集中出现在后台异步任务(CRON)和Ajax请求中,核心原因通常是MySQL主动断开了闲置连接,或是连接生命周期管理存在疏漏。以下是针对性的落地解决方案:
1. 调整MySQL的连接超时参数
CRON任务属于非交互式连接,MySQL的wait_timeout参数会自动断开长时间闲置的连接(默认通常是8小时,但如果你的任务中间有等待GCM响应的长时间停顿,就会触发断开)。
- 先查看当前设置:
SHOW VARIABLES LIKE '%timeout%'; - 修改
/etc/my.cnf(或/etc/mysql/my.cnf,依MySQL安装路径而定),添加/调整:wait_timeout = 3600 # 设为1小时,可根据任务实际运行时长灵活调整 interactive_timeout = 3600 # 和wait_timeout保持一致,避免参数冲突 - 重启MySQL生效:
service mysqld restart
2. 在CodeIgniter中添加连接重连机制
虽然你设置了pconnect=false,但长时间运行的CRON任务仍可能在执行过程中被MySQL主动断开连接。可以在数据库操作前主动检查连接有效性,无效则自动重连:
- 在你的模型或控制器中,每次执行数据库操作前添加:
$db =& $this->db; // 检查连接是否存活,ping失败则重新初始化连接 if (!$db->conn_id || !$db->ping()) { $db->initialize(); } - 更优雅的方式是扩展CodeIgniter的数据库驱动,在底层自动处理重连(注意备份原框架文件,避免破坏核心逻辑)。
3. 优化CRON任务的数据库操作逻辑
如果你的CRON任务是批量处理推送数据,中间会有大量网络IO(调用GCM API),这会导致数据库连接长时间处于闲置状态:
- 批量拉取数据后,先主动关闭数据库连接:
$this->db->close();,再处理GCM推送,完成后重新连接更新状态 - 将大任务拆分为多个小任务(比如每次处理100条数据),每个小任务完成后重新建立连接,避免长时间持有连接
4. 确认max_allowed_packet设置真正生效
有时候修改配置后没有正确重启MySQL,或是PHP端的对应参数与MySQL不一致:
- 检查MySQL端设置:
建议设置为64M以上:SHOW VARIABLES LIKE 'max_allowed_packet';max_allowed_packet = 64M(在my.cnf中修改后重启MySQL) - 检查PHP端的
mysqli.max_packet_size(CodeIgniter通常用mysqli扩展),在php.ini中确保与MySQL端一致,修改后重启PHP-FPM或Apache
5. 排查服务器层面的连接中断问题
CentOS 6的防火墙或SELINUX可能会断开长时间闲置的TCP连接:
- 检查iptables的超时规则:
如果有针对3306端口的短超时规则,调整延长时间iptables -L -v -n | grep timeout - 检查SELINUX日志是否有阻止MySQL连接的记录:
必要时可以临时关闭SELINUX测试:tail -f /var/log/audit/audit.logsetenforce 0,如果问题解决,再调整SELINUX策略
6. 升级CodeIgniter到兼容PHP5.6的最新稳定版
如果你使用的CodeIgniter版本较旧,可能存在数据库驱动的连接管理bug。PHP5.6对应的最新稳定版是CodeIgniter 3.1.13,升级后可以修复一些旧版本的连接问题(注意备份项目文件,确保业务兼容性)
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

