【发布时间】:2021-06-24 22:15:44
【问题描述】:
我正在为一个爱好 PHP 网站 (PHP 7.3.27-1~deb10u1 (fpm-fcgi)) 运行 MariaDB 服务器 (10.3.27-MariaDB-0+deb10u1 Raspbian 10)。
昨天我决定是时候开始每天备份数据库并为此目的在 cron 作业中添加脚本。在今晚运行 cron 作业后,网站给了我这个错误:
Fatal error: Uncaught mysqli_sql_exception: Prepared statement needs to be re-prepared in [a].php:180
Stack trace:
#0 [a].php(180): mysqli_stmt->execute()
#1 [b].php(64): getTargetID(Object(mysqli), 'ha', 2020)
#2 [c].php(3): require('....')
#3 {main} thrown in funcs.php on line 180
函数 getTargetID() 基本上是在执行一个从视图返回 ID 的查询。在 TablePlus 中运行完全相同的查询(针对相同的数据库)工作正常。
如果我重新启动 MariaDB 服务器,PHP 代码将再次按预期执行,直到再次运行备份脚本。
备份脚本基本上是这样的:
mysqldump -u ${USER} -h${HOST} -p${PASSWORD} --all-databases |gzip > ${SQLFILE}$
编辑:mysqldump 命令被放置在一个 shell 脚本 (db_backup.sh) 中,并在午夜通过一个 cron 作业执行。
脚本在备份机器上执行,该机器有一个具有以下权限的数据库用户:
- 选择
- 触发器
- 显示视图
- 锁定表
编辑2:
导致错误的函数包含以下代码:
function getTargetID(&$mysqli, $league, $year) {
$sql_query = <<<SQL
SELECT team_id
FROM standings
WHERE league = ? and season = ?
ORDER BY points DESC, goals_for DESC, team_name
LIMIT 1;
SQL;
$stmt = $mysqli->prepare($sql_query);
$stmt->bind_param("si", $league, $year);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$rows = $result->fetch_all(MYSQLI_ASSOC);
$team_id = $rows[0]["team_id"];
$result->free();
return $team_id;
}
else { echo "<!-- Error 107 -->"; }
$stmt->close();
}
Standings 是一种“输出”足球联赛排名表的视图。
我有点不知如何解决这个问题,而且到目前为止我无法通过 Google 找到任何解决方案。是否应该在转储命令中添加一些内容?
【问题讨论】:
-
Mysqldump 是可执行文件,不是 sql 语句。你不能用 mysqli 执行它。
-
您能更详细地描述一下您是如何运行
mysqldump命令的吗?正如 Shadow 所说,这不是您可以通过 MySQL 连接执行的操作。这是一个 shell 命令,因为它是一个二进制可执行文件,根本不是 MySQL 命令。 -
mysqldump 命令放置在 shell 脚本 (db_backup.sh) 中,并在午夜通过 cron 作业执行。 (添加了一个编辑)
-
我已在编辑中添加了相关函数的代码。我有点不确定要添加哪些信息以增加足够的清晰度。
标签: php mysql mysqli mariadb prepared-statement