PDO에서 LOB를 넣으려고 MySQL server has gone away.

5402 단어 MySQLPHPmariadbPDO

PDOException이 나왔다.


  • SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
  • PHP 측 오류는 Error while sending QUERY packet.
  • 위치는 상대적으로 큰 크기의 LOB를 찌르는 쿼리의 execute() 위치
  • 그러나 PHP의 memory_limit (= 128MB)에 맞는 정도이고, max_execution_time (= 30 초)에 맞는 정도
  • MySQL의 로그에는 아무것도 나오지 않는다

  • 조사한 것


  • wait_timeout 값이 작습니까?
  • 설정도 괴롭히지 않고, mysql -uhoge -p -e "show variables like '%timeout%'" 해도 디폴트의 28800 초가 되어 있다.
  • execute() 의 직전에 $pdo->query("SELECT 1") 라든지 실행해 보면 보통으로 실행할 수 있었다.

  • max_allowed_packet 값이 작습니까?
  • 설정을 변경하여 크게 하고 있다. mysql -uhoge -p -e "show variables like '%allowed%'" 하지만 설정대로 되어 있다.


  • 쿼리 전에 연결을 닫고 있습니까?
  • 위에서도 쓴 대로 직전에 실행한 쿼리는 통과한다.


  • LOB가 크기 때문에?
  • 작은 LOB로하면 오류가 발생하지 않습니다




  • 원인


    setAttribute(PDO::ATTR_EMULATE_PREPARES, true); 하고 있었던 것 같은? ? ?
    에뮬레이션을 끄면 낫다.

    쿼리를 덤프해 보았습니다.


    $pdo = new PDO();
    $pdo->beginTransaction();
    
    $pdo->query("SELECT 1");
    $stmt = $pdo->prepare("INSERT INTO foo(file) values (?)");
    $stmt->bindValue(1,LOB,PDO::PARAM_LOB);
    $stmt->execute();
    
    $pdo->commit();
    
  • 에뮬레이션 ON, 큰 LOB (25MB)
  • Connect   hoge@localhost as anonymous on po
    Query     START TRANSACTION
    Query     SELECT 1
    Prepare   INSERT INTO foo (file) VALUES (?)
    Execute   INSERT INTO foo (file) VALUES (LOB)
    

    에뮬레이션 ON인데 정적 플레이스홀더와 같은 움직임을 하고 있다.
    Quit도 COMMIT도 하고 있지 않다. Connect가 사라지고 있기 때문에, 정말로 server has gone away 무엇을 알 수 있다.
  • 에뮬레이션 ON, 작은 LOB (1 문자)
  • Connect   hoge@localhost as anonymous on po
    Query     START TRANSACTION
    Query     SELECT 1
    Query     INSERT INTO foo (file) VALUES (LOB)
    Query     COMMIT
    Quit
    

    정상 동작
  • 에뮬레이션 OFF, 큰 LOB (25MB)
  • Connect   hoge@localhost as anonymous on po
    Query     START TRANSACTION
    Prepare   INSERT INTO foo (file) VALUES (?)
    Prepare   SELECT 1
    Execute   SELECT 1
    Execute   INSERT INTO foo (file) VALUES (LOB)
    Query     COMMIT
    Quit
    

    정상 동작

    정리하면


    PDO::ATTR_EMULATE_PREPARESTRUE 일 때 LOB를 삽입하려고하면 연결이 사라집니다.



    그런 것 들은 적도 없고, 조사해도 나오지 않고, 원인은 이것 이외의 곳… 하지만 false로 하면 낫고…

    환경


  • CentOS Linux release 7.4.1708 (Core)
  • PHP 7.1.15
  • mysql Ver 15.1 Distrib 10.2.13-MariaDB, for Linux (x86_64) using readline 5.1

  • 결론



    잘 모르겠습니다

    좋은 웹페이지 즐겨찾기