php - 如果连接未关闭并重新打开,则发送 QUERY 数据包时 MySQl 错误
问题描述
Warning Error while sending QUERY packet in PID=
当我使用仅从 2 列中SELECT
获取5 行数据的语句时,我得到了这样的结果,然后让脚本休眠 10 分钟,然后醒来继续INSERT
进入数据库。
如果我在语句之后关闭连接SELECT
并在 之前重新打开连接INSERT
,那么一切正常并且不会产生错误。
我无法弄清楚为什么会这样。我在公共共享服务器上。
选择
选择的值是:
Seller
长度为 10 个字符,长度Token
为 872。
include('con.php');
if ($result = $con->query("SELECT Seller,Token FROM `Sellers`")) {
$sellers = $result->fetch_all(MYSQLI_ASSOC);
$result->close();
}
$con->close();
睡觉
sleep(600);
插入
插入的所有值的长度都是最小的,其中 21 个字符是该列中最长的jobType
。从 foreach 循环中插入总共 5 行。
include('con.php');
foreach(...) {
$insert = "INSERT INTO `jobStatus` (ack, jobId, RefId, Type, Status, error, percent, Seller, creationTime, completionTime) VALUES ('$ack', '$jid', '$frid', '$jtyp', '$jstat', '$errc', '$pcom', '$sid', '$crtime', '$cotime')";
if($con->query($insert)) {
echo "inserted into db successfully.\n";
} else {
echo "not inserted into db. Query Failed.\n";
}
}
$con->close();
由于关闭和重新打开语句之间的连接,上面的代码可以正常工作。
我希望它在 . 之后保持连接打开SELECT
,然后在INSERT
.
有人可以指出我需要做什么才能实现这一目标吗?
注意:我的脚本中已经将 set_time_limit 设置为 0。
set_time_limit(0);
这是产生错误的代码。
导致错误的代码
选择
include('con.php');
if ($result = $con->query("SELECT Seller,Token FROM `Sellers`")) {
$sellers = $result->fetch_all(MYSQLI_ASSOC);
$result->close();
}
睡觉
sleep(600);
插入
foreach($sellers as $seller) {
$insert = "INSERT INTO `jobStatus` (ack, jobId, RefId, Type, Status, error, percent, Seller, creationTime, completionTime) VALUES ('$ack', '$jid', '$frid', '$jtyp', '$jstat', '$errc', '$pcom', '$sid', '$crtime', '$cotime')";
if($con->query($insert)) {
echo "inserted into db successfully.\n";
} else {
echo "not inserted into db. Query Failed.\n";
}
}
$con->close();
更新:
以下是结果SHOW VARIABLES LIKE '%timeout'
$SESSION_VARIABLES = array(
array(
"Variable_name" => "connect_timeout",
"Value" => "10",
),
array(
"Variable_name" => "delayed_insert_timeout",
"Value" => "300",
),
array(
"Variable_name" => "innodb_flush_log_at_timeout",
"Value" => "1",
),
array(
"Variable_name" => "innodb_lock_wait_timeout",
"Value" => "50",
),
array(
"Variable_name" => "innodb_rollback_on_timeout",
"Value" => "OFF",
),
array(
"Variable_name" => "interactive_timeout",
"Value" => "30",
),
array(
"Variable_name" => "lock_wait_timeout",
"Value" => "86400",
),
array(
"Variable_name" => "net_read_timeout",
"Value" => "30",
),
array(
"Variable_name" => "net_write_timeout",
"Value" => "60",
),
array(
"Variable_name" => "slave_net_timeout",
"Value" => "60",
),
array(
"Variable_name" => "thread_pool_idle_timeout",
"Value" => "60",
),
array(
"Variable_name" => "wait_timeout",
"Value" => "30",
),
);
解决方案
mysql 连接在 30 秒后超时,即在 30 秒不活动后自动关闭,您对此无能为力(除了在睡眠时每 29 秒轮询一次)。如有必要,我建议您在睡眠后使用mysqli::ping重新连接:
if ($con->ping()) {
// foreach... insert
}
推荐阅读
- python - 括号 ()、单方括号[]、双方括号[[]]、大括号{}
- mysql - 如何将某些列及其数据从 csv 文件导入 mysql phpmyadmin
- mysql - 你能在这里解释一下“reference”关键字的含义吗
- angular - 在角度应用程序中读取 Firestore 数据库时间戳并进行比较时出现问题
- postman - 如何使用邮递员从 keycloak 获取访问令牌(授权码流)
- linux - linux 中需要嵌套的 while 循环:- 我有两个变量 A=(a1;b2),B=(A1,B2) 需要像 this1=A1 & b2=B2 这样的输出
- java - 多个嵌套的 Recyclerviews 会降低应用程序的性能
- php - 如何在 cmd 提示符下获取 php-cli 版本 7
- openxml - 演示 OpenXml 包无法找到字体颜色的来源
- json - 如何使用 entityframework ICollection '我的方式'进行序列化