programing

mysql 쿼리의 최대 실행 시간을 설정하는 방법은 무엇입니까?

oldcodes 2023. 9. 16. 09:52
반응형

mysql 쿼리의 최대 실행 시간을 설정하는 방법은 무엇입니까?

php의 set_time_limit()와 같은 sql 쿼리의 최대 실행 시간을 설정하고 싶습니다.어떻게 해야 할까?

좀 더 오래된 줄 알았는데, 이 말에 의하면

MySQL 5.7.4에는 최상위 읽기 전용 SELECT 문에 대해 밀리초 단위로 지정된 서버측 실행 시간 제한을 설정할 수 있는 기능이 도입되었습니다.

SELECT 
/*+ MAX_EXECUTION_TIME(1000) */ --in milliseconds
* 
FROM table;

읽기 전용 SELECT 문에만 적용됩니다.

업데이트: 이 변수는 MySQL 5.7.4에서 추가되어 다음으로 이름이 변경되었습니다.max_execution_timeMySQL 5.7.8. (출처)

mysql 네이티브 드라이버(php 5.3 이후 일반적)와 mysqli 확장자를 사용하는 경우 비동기 쿼리로 다음을 수행할 수 있습니다.

<?php

// Heres an example query that will take a long time to execute.
$sql = "
    select *
    from information_schema.tables t1
    join information_schema.tables t2
    join information_schema.tables t3
    join information_schema.tables t4
    join information_schema.tables t5
    join information_schema.tables t6
    join information_schema.tables t7
    join information_schema.tables t8
";

$mysqli = mysqli_connect('localhost', 'root', '');
$mysqli->query($sql, MYSQLI_ASYNC | MYSQLI_USE_RESULT);
$links = $errors = $reject = [];
$links[] = $mysqli;

// wait up to 1.5 seconds
$seconds = 1;
$microseconds = 500000;

$timeStart = microtime(true);

if (mysqli_poll($links, $errors, $reject, $seconds, $microseconds) > 0) {
    echo "query finished executing. now we start fetching the data rows over the network...\n";
    $result = $mysqli->reap_async_query();
    if ($result) {
        while ($row = $result->fetch_row()) {
            // print_r($row);
            if (microtime(true) - $timeStart > 1.5) {
                // we exceeded our time limit in the middle of fetching our result set.
                echo "timed out while fetching results\n";
                var_dump($mysqli->close());
                break;
            }
        }
    }
} else {
    echo "timed out while waiting for query to execute\n";

    // kill the thread to stop the query from continuing to execute on 
    // the server, because we are abandoning it.
    var_dump($mysqli->kill($mysqli->thread_id));
    var_dump($mysqli->close());
}

가 제 sqli_query에게 드리려는 깃발들은 중요한 것들을 성취합니다.이것은 클라이언트 드라이버에게 비동기 모드를 사용하도록 지시하는 한편, 더 상세한 코드를 사용하도록 강요하지만, 시간 초과를 사용할 수 있게 해줍니다(그리고 원한다면 동시 쿼리를 발행할 수도 있습니다!).다른 플래그는 클라이언트에게 전체 결과를 메모리로 버퍼링하지 말라고 알려줍니다.

기본적으로 php는 php 코드가 결과의 행에 대한 액세스를 시작하기 전에 쿼리의 전체 결과 집합을 메모리로 가져오도록 mysql 클라이언트 라이브러리를 구성합니다.큰 결과를 전송하는 데 시간이 오래 걸릴 수 있습니다.비활성화하면 버퍼링이 완료될 때까지 기다리는 동안 시간이 초과될 위험이 있습니다.

제한 시간 초과 여부를 확인해야 하는 곳은 두 곳입니다.

  • 실제 쿼리 실행
  • 결과(데이터)를 가져오는 동안

PDO와 일반 mysql 확장자에서 유사한 결과를 얻을 수 있습니다.비동기 쿼리를 지원하지 않기 때문에 쿼리 실행 시간에 대한 제한 시간을 설정할 수 없습니다.그러나 버퍼링되지 않은 결과 집합을 지원하므로 적어도 데이터 가져오기에 시간 초과를 구현할 수 있습니다.

많은 쿼리의 경우 mysql은 결과를 거의 즉시 스트리밍할 수 있으므로 버퍼링되지 않은 쿼리만으로도 특정 쿼리에 대한 타임아웃을 어느 정도 효과적으로 구현할 수 있습니다.예를 들면, a.

select * from tbl_with_1billion_rows

행 스트리밍을 바로 시작할 수 있지만,

select sum(foo) from tbl_with_1billion_rows

첫번째 행을 사용자에게 반환하기 전에 전체 테이블을 처리해야 합니다.이 후자의 경우는 비동기 쿼리의 시간 초과로 인해 저장됩니다.그것은 또한 평범하고 오래된 데드락이나 다른 것들로부터 여러분을 구해줄 것입니다.

ps - 연결 자체에 타임아웃 로직을 포함하지 않았습니다.

다음과 같이 쿼리를 다시 작성하십시오.

select /*+ MAX_EXECUTION_TIME(1000) */ * from table


이 문은 지정된 시간 이후에 쿼리를 종료합니다.

다른 S.O. 질문에서 답을 찾을 수 있습니다.

MySQL - 쿼리 실행에 허용되는 최대 시간을 제한할 수 있습니까?

데이터베이스 서버에서 매초 실행되는 cron 작업을 연결하고 다음과 같은 작업을 수행합니다.

  • SHOW PROCESS List
  • 원하는 최대 시간보다 쿼리 시간이 큰 모든 연결 찾기
  • 각 프로세스에 대해 KILL [process id] 실행

2023년 5월 업데이트 : 아래 답변에서 릭 제임스가 추천페르코나의 pt-kill을 확인합니다.

pt_kill 옵션이 있습니다.그러나 지속적으로 모니터링하는 것이 아니라 온디맨드 방식입니다.@Rafa가 제안한 대로 합니다.그러나 참조--sentinel어떻게 접근할 것인가에 대한 힌트로cron.

리눅스 명령줄에서 다음과 같은 원라이너를 실행하고 크론탭에 고정시켜 일정한 간격으로 실행할 수도 있습니다.

이 예에서는 최소 1시간(3600초) 동안 실행되는 모든 SELECT 쿼리를 즉시 삭제합니다.

mysql -e "SELECT group_concat(concat('KILL ',id,';') separator ' ') AS cmd FROM information_schema.processlist WHERE user NOT IN ('slave','replica') AND info LIKE 'SELECT %' AND time > 3600;" | grep KILL | mysql

위에서 다음 항목을 교체할 수 있습니다.

NOT IN (["safe list" of mysql users you NEVER want to touch; e.g. replication users])

time > [N seconds for slow queries you want to target]

참고: 맹목적으로 KILL 명령을 실행하면 오류가 발생할 수 있습니다.극도로 조심해서 사용하세요!

언급URL : https://stackoverflow.com/questions/415905/how-to-set-a-maximum-execution-time-for-a-mysql-query

반응형