zoukankan      html  css  js  c++  java
  • php分享二十八:mysql运行中的问题排查

    一:杀掉mysql连接的方法:

    kill thread_id:  杀掉当前进程,断开连接

    kill query thread_id: 只杀掉某连接当前的SQL,而不断开连接。

    批量杀死MySQL连接的几种方法:

    1> 通过information_schema.processlist表中的连接信息生成需要处理掉的MySQL连接的语句临时文件,然后执行临时文件中生成的指令。

     mysql> select concat('KILL ',id,';') from information_schema.processlist where user='root';
    +------------------------+
    | concat('KILL ',id,';') |
    +------------------------+
    | KILL 3101;             |
    | KILL 2946;             |
    +------------------------+
    2 rows in set (0.00 sec)
    
    mysql>select concat('KILL ',id,';') from information_schema.processlist where user='root' into outfile '/tmp/a.txt';
    Query OK, 2 rows affected (0.00 sec)
     
    mysql>source /tmp/a.txt;
    Query OK, 0 rows affected (0.00 sec) 
    

    2>杀掉当前所有的MySQL连接

    mysqladmin -uroot -p processlist|awk -F "|" '{print $2}'|xargs -n 1 mysqladmin -uroot -p ki

    mysqladmin -uroot -p processlist|awk -F "|" '{if($3 == "Mike")print $2}'|xargs -n 1 mysqladmin -uroot -p kill

    3>通过SHEL脚本实现

    杀掉锁定的MySQL连接

    for id in `mysqladmin processlist|grep -i locked|awk '{print $1}'`
    do
       mysqladmin kill ${id}
    done
    

     

    二:MySQL server has gone away 问题的解决方法

    原因一. MySQL 服务宕了

    判断是否属于这个原因的方法很简单,进入mysql控制台,查看mysql的运行时长

    mysql> show global status like 'uptime';
    +---------------+---------+
    | Variable_name | Value   |
    +---------------+---------+
    | Uptime        | 3414707 |
    +---------------+---------+
    

     或者查看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秒后被自动关闭
    

    解决办法:

    1> 修改my.cnf

    wait_timeout=2880000
    interactive_timeout = 2880000
    

     如果不能修改my.cnf,则可以在连接数据库的时候设置CLIENT_INTERACTIVE,MySQL默认是8个小 时。

    2>检查 MySQL的链接状态,使其重新链接

    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这样的问题,而且不会对系统造成额外的开销。

    sql = "set interactive_timeout=24*3600";
    mysql_real_query(...)
    

    原因三. mysql请求链接进程被主动kill

    这种情况和原因二相似,只是一个是人为一个是MYSQL自己的动作

    mysql> show global status like 'com_kill';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Com_kill      | 21    |
    +---------------+-------+
    

     原因四. 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)
    

    解决办法:

    1> 修改参数

    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)
    

     2> 修改my.cnf,加大max_allowed_packet的值即可

    在[mysqld]配置下:

    max_allowed_packet = 10M(也可以设置自己需要的大小)
    max_allowed_packet 参数的作用是,用来控制其通信缓冲区的最大长度。

    参考:

    mysql 常用语句:http://www.jb51.net/article/18667.htm

  • 相关阅读:
    Delphi数据类型转换
    js截取指定长度字符
    Internet Explorer无法打开站点,已终止操作
    关于最近做项目的一点点总结
    屏蔽右键菜单
    屏蔽回车自动提交
    自己写的一个客户端验证js
    如何播放声音文件
    如何:使用 CodeDOM 创建类
    js操作dom(4)关于xml节点属性的操作
  • 原文地址:https://www.cnblogs.com/Alight/p/5234598.html
Copyright © 2011-2022 走看看