php中如何设置mysql查询读取数据的超时时间

现象:
php能通过代理正常连接到mysql。但是,执行query后,一直等待,没有任何数据返回。
结果导致php-fpm进程全部阻塞在读取数据的地方。不能处理其他正常请求。

解决方法:
可以通过设置mysql查杀的超时时间来解决这个问题。
第一种设置mysql查询超时时间的方法是使用mysqlnd。
关于msyqlnd的介绍,大家可以看下这篇文章 http://www.bo56.com/php-mysqlnd-简介/
php启用mysqlnd扩展后,只要在php.ini文件中设置 mysqlnd.net_read_timeout 即可。
参数值的单位为秒。如:
mysqlnd.net_read_timeout = 3 表示每次mysql查询超时时间为3秒。如果超时,则会报错。
如下面的代码:

<?php
$dsn = 'mysql:dbname=demo;host=127.0.0.1;port=3306';
$user = 'demo';
$password = 'demo';
$dbh = new PDO($dsn, $user, $password);
$dbh->query("set names utf8");
$sql = "select sleep(5)";
$sth = $dbh->query($sql);
$row = $sth->fetch();
echo "over";
?>

则会报错误:
PHP Warning: PDO::query(): MySQL server has gone away
PHP Warning: PDO::query(): Error reading result set's header
PHP Fatal error: Call to a member function fetch() on a non-object
由于出现了PHP Fatal error错误,导致fetch()之后的代码将无法执行。
​因此代码需要对query的返回值做下判断,修改后的代码如下:

<?php
$dsn = 'mysql:dbname=demo;host=127.0.0.1;port=3306';
$user = 'demo';
$password = 'demo';
$dbh = new PDO($dsn, $user, $password);
$dbh->query("set names utf8");
$sql = "select sleep(5)";
$sth = $dbh->query($sql);
if(is_object($sth)){
    $row = $sth->fetch();
}
echo "over";
?>

注意:设置项 mysqlnd.net_read_timeout 的级别是PHP_INI_SYSTEM。所以在php代码中不能修改mysql查询的超时时间。

另一种方式是使用mysqli。
如果php没有启用mysqlnd,那么可以使用mysqli进行限制read的超时时间。
示例代码如下:

<?php
//自己定义读写超时常量
if (!defined('MYSQL_OPT_READ_TIMEOUT')) {
        define('MYSQL_OPT_READ_TIMEOUT',  11);
}
if (!defined('MYSQL_OPT_WRITE_TIMEOUT')) {
        define('MYSQL_OPT_WRITE_TIMEOUT', 12);
}
//设置超时
$mysqli = mysqli_init();
$mysqli->options(MYSQL_OPT_READ_TIMEOUT, 3);
$mysqli->options(MYSQL_OPT_WRITE_TIMEOUT, 1);
//连接数据库
$mysqli->real_connect("localhost", "root", "root", "test");
if (mysqli_connect_errno()) {
   printf("Connect failed: %s/n", mysqli_connect_error());
   exit();
}
//执行查询 sleep 1秒不超时
printf("Host information: %s/n", $mysqli->host_info);
if (!($res=$mysqli->query('select sleep(1)'))) {
    echo "query1 error: ". $mysqli->error ."/n";
} else {
    echo "Query1: query success/n";
}
//执行查询 sleep 9秒会超时
if (!($res=$mysqli->query('select sleep(9)'))) {
    echo "query2 error: ". $mysqli->error ."/n";
} else {
    echo "Query2: query success/n";
}
$mysqli->close();
echo "close mysql connection/n";
?>

注意:

1. 超时设置单位为秒,最少配置1秒
2. 但mysql底层的read会重试两次,所以实际会是 3 秒
重试两次 + 自身一次 = 3倍超时时间。
那么就是说最少超时时间是3秒,不会低于这个值,对于大部分应用来说可以接受,但是对于小部分应用需要优化。

时间: 2024-08-03 00:39:08

php中如何设置mysql查询读取数据的超时时间的相关文章

php设置mysql查询读取数据的超时时间

现象:php能通过代理正常连接到mysql.但是,执行query后,一直等待,没有任何数据返回. 结果导致php-fpm进程全部阻塞在读取数据的地方.不能处理其他正常请求.解决方法: 可以通过设置mysql查杀的超时时间来解决这个问题. 第一种设置mysql查询超时时间的方法是使用mysqlnd. php启用mysqlnd扩展后,只要在php.ini文件中设置 mysqlnd.net_read_timeout 即可. 参数值的单位为秒.如: mysqlnd.net_read_timeout =

ECharts使用jQuery和PHP、MySQL异步读取数据例子

ECharts地图主要用于地理区域数据的可视化,展示不同区域的数据分布信息.ECharts官网提供了中国地图.世界地图等地图数据下载,通过js引入或异步加载json文件的形式调用地图. ECharts地图应用:使用jQuery和PHP.MySQL异步读取数据 本文将结合实例讲解如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据,我们以中国地图为例,展示去年(2015年)我国各省份GDP数据.通过异步请求php,读取mysql中的数据,然后展示在地图上,因此本文除了你掌握前

如何解决mysql查询百万数据时出现大量sleep的进程

问题描述 如何解决mysql查询百万数据时出现大量sleep的进程 如何解决mysql查询百万数据时出现大量sleep的进程: 当使用jdbc 查询数据量为100多万的数据时,mysql会出现大量sleep的进程,然后程序便会卡死在那儿 解决方案 描述的有点泛泛,如果能把使用场景.涉及库表定义发一下会更容易分析. 大量sleep进程可能并不是问题,因为如果使用到连接池的话,一开始就是初始化一些连接,这些连接没有使用的话,在mysql看可能就是sleep的. 从你描述,感觉"查询数据量为100多万

三星note7如何设置曲面侧屏订阅源超时时间

注:侧屏反馈启动时,无法使用"息屏提醒"功能.  1.在标准模式下,点击[设置].    2.点击[显示].    3.点击[曲面侧屏].    4.阅读"在后台传输数据"的提示后,点击[确认].    5.点击[曲面侧屏订阅源].      6.点击[更多]图标.    7.点击[曲面侧屏订阅源超时].    8.根据需要选择曲面侧屏订阅源超时时间即可,这里以选择[2分钟]为例.         好了上文就是小编为各位整理的一篇关于note7手机设置曲面侧屏订阅源

在S2SH中如何让jsp自动读取数据表里的内容?

问题描述 我想访问主页index.jsp的时候就能自动读取并显示新闻数据表(id,title,createdate)中的前五条数据,看了一些Struts2+spring+hibernate例子,都是必须先提交数据,产生action,后读出返回数据,使用Struts2标签显示出来,但我直接访问主页index.jsp时(好像没有直接提交什么数据),不知道如何自动显示出数据表中的数据,恳请各位帮助! 解决方案 解决方案二:建一个Action,映射为index.action建一个普通文件,名字为inde

C# 是使用Winform操作MYSQL 新增,读取数据乱码

1.C# Winform 连接MYSQL 对MySQL进行新增,读取数据操作,使用Mysql.MySql.Data组件进行数据连接及操作 2.mysql教程的版本本较低4.01 不能对Mysql的环境进行配置 来源:http://www.dezai.cn/blog/article.asp教程?id=418 现象: 1.新增数据正常操作,但是插入MYSQL数据库教程中的对应表中的数据成问号形式 2.Mysql表中中文数据显示正常,但通过datagridview读取显示?号 解决过程 1.在mysq

MySQL查询随机数据的4种方法和性能对比

 从MySQL随机选取数据也是我们最常用的一种发发,其最简单的办法就是使用"ORDER BY RAND()",本文介绍了包括ORDER BY RAND()的4种获取随机数据的方法,并分析了各自的优缺点. 下面从以下四种方案分析各自的优缺点. 方案一:  代码如下:SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1; 这种方法的问题就是非常慢.原因是因为MySQL会创建一张零时表来保存所有的结果集,然后给每个结果一个随机索引,然后再排序并返回.

ASP链接MYSQL并读取数据的程序

mysql|程序|链接|数据 <%'ASP链接MYSQL的程序'需要装MYSQLODBC驱动 下载地址:http://www.mysql.com/downloads/api-myodbc-2.50.html'E-MAIL:Kaxue@Hotmail.com QQ:484110 HOMEPAGE:www.Flyday.net'整理时间:Thursday, May 23, 2002 5:54 PM WIN2000SERVER+IIS5 测式通过strConnection = "dsn=user

中华通网络电话如何查询帐号的过期时间与有效期的提示?

  话费直充到账的帐号余额有效期为一年,如想查询帐号的过期时间,可以在软件上的"充值中心"或在网页上登陆到"个人帐户管理中心"都可以查看到过期时间.具体操作如下: 1.点击软件的"充值"按扭,即可弹出充值框,在充值框的最上方显示.如图: 2.在网站上登陆到"个人帐户管理中心"查看过期时间,如图: 进入到个人管理中心后在"状态查询"即可显示,如图: