从【MySQL server has gone away】说起[通俗易懂]

从【MySQL server has gone away】说起

大家好,又见面了,我是全栈君。

本文目的

这几天开发了一个PHP CLI程序,用于后台定时调度执行一些任务。此脚本采用了PHP的多进程(pcntl_fork),共享内存和信号量进行IPC和同步。目的是将串行的任务并行执行,缩短执行时间。可是在工作子进程中,访问myql时一直报错,通过mysql_error返回的信息却是冷冷的一句话“MySQL server has gone away”。简单说一句自己挂掉了就完事,太不负责任了。经过仔细搜索,终于发现问题的原因,在此做个分享,也作为备忘。

什么导致“MySQL server has gone away”

官方文档描述,主要有以下一些原因导致此异常出现(我粗略的翻译一下,以原文为准):

1. mysqld线程被杀死.

2. 使用了关闭的链接资源

3. 无权限

4. TCP/IP超时

5. mysql服务器端超时

6. windows兼容问题

7. sql过长

8. 请求包过长

9. DNS解析问题

10. 多进程并发使用同一个链接

11. mysql的未知bug

吐槽:以上情况虽然列举得很详细,但是为什么不能在第一时间通过mysql_error返回呢?

问题的原因

由于我的使用场景是在多进程环境下,所以很快将问题锁定在了mysql链接资源上,果然很快找到答案:mysql_connect函数的第四个参数$new_link没有设置为true.

首先看看mysql_connect函数签名:

resource mysql_connect ([ string $server = ini_get(“mysql.default_host”) [, string $username = ini_get(“mysql.default_user”) [, string$password = ini_get(“mysql.default_password”) [, bool $new_link = false [, int $client_flags = 0 ]]]]] )

默认情况,$new_link设置为false,也就是会重用现有的链接资源(如果有)。设想一下,如果多个进程同时调用mysql_connect,并且没有设置$new_link为true,那么这些进程就会同时使用同一个链接资源,也就是上面第10个原因,导致mysql报告“mysql server has gone away”的异常。

所以,将$new_link设置为true后,此问题就解决了。

问题的本质

mysql链接资源,底层其实是封装了socket和相关的数据,如果多个进程用一个链接,也就是同一个socket和服务器交互,结果可想而知,服务器被混淆了,所以只能吐出一句冷冷的“MySQL server has gone away”了事。

但是,我还有一个疑问,php在apache环境下访问mysql时,并没有显示设置$new_link为True,但是从没有出现上述这个现象,难道是apache处理并发时,采用的单进程而不是多进程?

总结

初次涉及多进程相关开发,往往遇到许多莫名奇妙的问题,有些现象时有时无。这时候,一定冷静分析问题的现象,不要随意将责任推究给其他系统(比如linux,mysql等),而是要在自己的程序上找原因。

在刚遇到此问题时,由于一时没有找到问题的原因,我还怀疑过是mysql的性能太低,不能承受我的程序的并发。其实这是一种出于本能的自我安慰。mysql的并发性能在业绩是有口皆碑的,怎么会在我的几个进程面前倒下。经过一番网上搜素和思考,终于找到问题原因,现在可以松一口气了。

值得高兴的是,程序改成并发后,性能有了质的飞跃,执行时间缩小到原来的十分之一,系统使用率高达90%多,改进前不到10%。

声明:如有转载本博文章,请注明出处。您的支持是我的动力!文章部分内容来自互联网,本人不负任何法律责任。
本文转自bourneli博客园博客,原文链接:http://www.cnblogs.com/bourneli/archive/2012/08/02/2620406.html
,如需转载请自行联系原作者

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108101.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机vb语言程序设计_vb语言程序设计基础

    计算机vb语言程序设计_vb语言程序设计基础VisualBasic程序设计教程:计算机类语音编辑锁定讨论上传视频《VisualBasic程序设计教程:计算机类》是中国科学技术出版社出版的图书,作者是王东、刘福来。中文名VisualBasic程序设计教程:计算机类出版社中国科学技术出版社定价39.20作者王东刘福来ISBN9787504646798VisualBasic程序设计教程:计算机类内容简介编辑语音《全国高等…

    2022年10月7日
    2
  • navicat premium 15 激活码【2021最新】[通俗易懂]

    (navicat premium 15 激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月28日
    558
  • python2装饰器_python函数装饰器

    python2装饰器_python函数装饰器前言我们都知道装饰器的作用是在不改变原有的代码基础上,添加新的功能,但是这样会有一个弊端,被装饰的函数某些属性会变改变,接下来我们来看下案例importtimedefrun_time(fu

    2022年7月30日
    5
  • spring中已经内置的几种事件

    spring中已经内置的几种事件

    2021年9月6日
    50
  • JVM架构和GC垃圾回收机制(JVM面试不用愁)[通俗易懂]

    JVM架构和GC垃圾回收机制(JVM面试不用愁)[通俗易懂]JVM架构和GC垃圾回收机制详解JVM架构图分析下图:参考网络+书籍,如有侵权请见谅(想了解Hadoop内存溢出请看:Hadoop内存溢出(OOM)分类、参数调优化)JVM被分为三个主要的子系统(1)类加载器子系统(2)运行时数据区(3)执行引擎1.类加载器子系统Java的动态类加载功能是由类加载器子系统处理。当它在运行时(不是编译时)首次引用一个类时,它加载、链…

    2022年4月28日
    57
  • 用户态和内核态区别是什么_进程运行在内核态还是用户态

    用户态和内核态区别是什么_进程运行在内核态还是用户态1、linux进程有4GB地址空间,如图所示:3G-4G大部分是共享的,是内核态的地址空间。这里存放整个内核的代码和所有的内核模块以及内核所维护的数据。2、特权级的概念:对于任何操作系统来说,创建一个进程是核心功能。创建进程要做很多工作,会消耗很多物理资源。比如分配物理内存,父子进程拷贝信息,拷贝设置页目录页表等等,这些工作得由特定的进程去做,所以就有了特权级别的概念。最关键的工作必须交给特权级最高的进程去执行,这样可以做到集中管理,减少有限资源的访问和使用冲突。interx86架构的cpu一共有

    2022年9月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号