mysql时间读不了了

阅读: 评论:0

mysql时间读不了了

mysql时间读不了了

现象:

php能通过代理正常连接到mysql。但是,执行query后,一直等待,没有任何数据返回。

结果导致php-fpm进程全部阻塞在读取数据的地方。不能处理其他正常请求。

解决方法:

可以通过设置mysql查杀的超时时间来解决这个问题。

第一种设置mysql查询超时时间的方法是使用mysqlnd。

关于msyqlnd的介绍,大家可以看下这篇文章 /

php启用mysqlnd扩展后,只要在php.ini文件中设置 mysqlnd_read_timeout 即可。

参数值的单位为秒。如:

mysqlnd_read_timeout = 3 表示每次mysql查询超时时间为3秒。如果超时,则会报错。

如下面的代码:

$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的返回值做下判断,修改后的代码如下:

$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_read_timeout 的级别是PHP_INI_SYSTEM。所以在php代码中不能修改mysql查询的超时时间。

另一种方式是使用mysqli。

如果php没有启用mysqlnd,那么可以使用mysqli进行限制read的超时时间。

示例代码如下:

//自己定义读写超时常量

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-02-01 21:27:04,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170679402439520.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:时间   mysql
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23