오류 준비 전표를 다시 준비해야 합니다.
취미 PHP 사이트(PHP 7.3.27-1~deb10u1(fpm-fcgi))를 위해 MariaDB 서버(10.3.27-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
getTarget 함수ID()는 기본적으로 보기에서 ID를 반환하는 쿼리를 실행합니다.TablePlus에서 동일한 데이터베이스에 대해 동일한 쿼리를 실행하면 문제없이 작동합니다.
MariaDB 서버를 다시 시작하면 백업 스크립트가 다시 실행될 때까지 PHP 코드가 예상대로 다시 실행됩니다.
백업 스크립트는 기본적으로 다음과 같습니다.
mysqldump -u ${USER} -h${HOST} -p${PASSWORD} --all-databases |gzip > ${SQLFILE}$
편집: mysqldump 명령은 셸 스크립트(db_backup)에 배치됩니다.sh) cron 작업으로 자정에 실행됩니다.
이 스크립트는 다음 권한을 가진 데이터베이스 사용자가 있는 백업 시스템에서 실행됩니다.
- 선택한다.
- 트리거
- 보기 표시
- 테이블 잠금
EDIT2:
오류를 발생시키는 함수에는 다음 코드가 포함되어 있습니다.
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();
}
순위는 축구 리그에서 순위표를 "출력"하는 관점입니다.
저는 이 문제를 어떻게 해결해야 할지 조금 막막하고, 지금까지 구글을 통해 어떤 해결책도 찾을 수 없었습니다.dump 명령에 무언가를 추가해야 합니까?
이것 좀 봐요...
$stmt = $mysqli->prepare($sql_query);
$stmt->bind_param("si", $league, $year);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
/* do some stulff
$rows = $result->fetch_all(MYSQLI_ASSOC);
$team_id = $rows[0]["team_id"];
$result->free();
return $team_id; /* return here */
}
else { echo "<!-- Error 107 -->"; }
$stmt->close(); /* close here */
쿼리가 성공하면 먼저 준비된 쿼리 개체를 닫지 않고 함수에서 돌아갑니다.어떤 종류의 준비 쿼리 누출을 유발할 수 있습니까?
php 코드를 다음과 같은 것으로 변경해 보십시오.
$stmt = $mysqli->prepare($sql_query);
$stmt->bind_param("si", $league, $year);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
/* do some stulff
$rows = $result->fetch_all(MYSQLI_ASSOC);
$team_id = $rows[0]["team_id"];
$result->free();
$stmt->close(); /* close first */
return $team_id; /* return here */
}
else { echo "<!-- Error 107 -->"; }
$stmt->close();
하는 것이 현명할 것입니다.sudo shutdown -r now
테스트를 시작하기 전에 기계를 확인합니다.이렇게 하면 모호하지 않은 캐시에 숨어 있는 준비된 쿼리를 사용하지 않고 시작할 수 있습니다.
테스트하려면 백업 주기가 한두 번 필요합니다.
이렇게 해도 문제가 해결될 경우, 이 특정 mysqli edge 사례에서 잘못된 오류 메시지가 표시됩니다(충분히 미세하지는 않습니다.
언급URL : https://stackoverflow.com/questions/66844811/error-prepared-statement-needs-to-be-re-prepared
'programing' 카테고리의 다른 글
도커는 가상 시스템과 어떻게 다릅니까? (0) | 2023.08.12 |
---|---|
큰 텍스트 파일에 문자열이 포함된 모든 줄을 최대한 빨리 가져오시겠습니까? (0) | 2023.08.12 |
Swift 3 - 장치 토큰이 '32B'로 구문 분석 중입니다.YTES' (0) | 2023.08.12 |
동적 웹 모듈 3.0 -- 3.1 (0) | 2023.08.12 |
스프링 보안:콩의 정의 없음예외:[또는 스프링 프레임워크] 유형의 적격한 원두가 없습니다.security.config.config.confirmation.ObjectPostProcessor]을(를) 찾았습니다. (0) | 2023.08.12 |