programing

일반 오류 해결 방법: 2006 MySQL 서버가 사라졌습니다.

linuxpc 2023. 8. 29. 20:12
반응형

일반 오류 해결 방법: 2006 MySQL 서버가 사라졌습니다.

저는 MySQL 데이터베이스에 수백 개의 레코드를 삽입하는 작업을 하고 있습니다.

정확히 176개의 레코드를 삽입한 후 다음 오류가 발생합니다.

[PDOException] SQLSTATE[HY000]:일반 오류: 2006 MySQL 서버가 사라졌습니다.

제가 어떻게 해결할 수 있을까요?

그 과정은 PHP로 진행됩니다.

감히 말씀드리지만 문제는wait_timeout공유 호스트에서는 30초로 설정되고 로컬 호스트에서는 28800으로 설정됩니다.

세션에 대해 변경할 수 있으므로 쿼리를 발행할 수 있습니다. SET session wait_session=28800

업데이트 OP는 변수도 변경해야 한다고 결정했습니다.interactive_timeout뿐만 아니라.이것은 모든 사람에게 필요할 수도 있고 필요하지 않을 수도 있습니다.

아래 코드는 변경 전과 변경 후의 설정을 보여주며 변경되었음을 확인합니다.

따라서 쿼리 시작 부분에 wait_message=28800(및 interactive_message=28800)을 설정하고 완료되었는지 확인합니다.

다음 위치에 자신의 DB 자격 증명을 삽입해야 합니다.DB_SERVER, DB_USER, DB_PASS, DB_NAME

업데이트 또한 이 방법이 효과가 있으면 wait_timeout을 더 높게 설정하여 수행 중인 작업을 명확히 하고자 합니다.28800으로 설정하는 것은 8시간이고 양이 많습니다.

다음은 이 사이트에서 온 것입니다.wait_timeout을 300으로 설정할 것을 권장합니다. 이를 시도하고 몇 주 후에 결과를 보고하겠습니다.

wait_timeout 변수는 MySQL이 유휴 연결을 종료하기 전에 대기하는 시간을 나타냅니다.기본 wait_timeout 변수는 8시간인 28800초입니다.엄청 많네요.

wait_timeout을 너무 낮게 설정하면(예: 30, 60, 90) MySQL 오류 메시지가 사라집니다.따라서 구성을 결정해야 합니다.

<?php

$db = new db();

$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";

$results = $db->query("SET session wait_timeout=28800", FALSE);
// UPDATE - this is also needed
$results = $db->query("SET session interactive_timeout=28800", FALSE);

$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";


class db {

    public $mysqli;

    public function __construct() {
        $this->mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
        if (mysqli_connect_errno()) {
            exit();
        }
    }

    public function __destruct() {
        $this->disconnect();
        unset($this->mysqli);
    }

    public function disconnect() {
        $this->mysqli->close();
    }

    function query($q, $resultset) {

        /* create a prepared statement */
        if (!($stmt = $this->mysqli->prepare($q))) {
            echo("Sql Error: " . $q . ' Sql error #: ' . $this->mysqli->errno . ' - ' . $this->mysqli->error);
            return false;
        }

        /* execute query */
        $stmt->execute();

        if ($stmt->errno) {
            echo("Sql Error: " . $q . ' Sql error #: ' . $stmt->errno . ' - ' . $stmt->error);
            return false;
        }
        if ($resultset) {
            $result = $stmt->get_result();
            for ($set = array(); $row = $result->fetch_assoc();) {
            $set[] = $row;
            }
            $stmt->close();
            return $set;
        }
    }
}

@mseifert 감사합니다.

당신의 아이디어는 두 개의 변수를 사용하여 동일하게 작동했습니다.

대화형_대화형 & wait_timeout

로컬 데이터베이스에서 구성을 복사했습니다.

SHOW VARIABLES LIKE  '%timeout%'

로컬 db:

enter image description here

원격 db:

enter image description here

연결 및 연결 해제 내부에서 이 작업을 수행하고 작업을 수행했습니다.

mysql_query("SET SESSION interactive_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'interactive_timeout';");
$row = mysql_fetch_array($result);
$interactive_timeout = $row["Value"];
echo("interactive_timeout" . " = " . $interactive_timeout . "\n");

mysql_query("SET SESSION wait_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'wait_timeout';");
$row = mysql_fetch_array($result);
$wait_timeout = $row["Value"];
echo("wait_timeout" . " = " . $wait_timeout . "\n");

놀랍게도 그것은 GoDaddy와 함께 작동했습니다.

당신이 나에게 원래의 아이디어를 주었기 때문에 나는 당신의 답변을 유효한 @mseifert로 받아들이겠습니다.

정말 감사해요.

이것이 다른 개발자들에게 2006년 MySQL 오류를 해결하는 데 미래에 유용하기를 바랍니다.

저의 경우, 클라이언트 측에서 이 오류가 발생했을 때 서버 측에서

(Got a packet bigger than 'max_allowed_packet' bytes)

그래서 저는 max_allowed_packet의 값을 늘렸고, 지금까지 더 이상의 문제는 없었습니다.

Google Cloud Platform에서 DB를 편집하고 Database 플래그를 추가한 후 값을 max_allowed_message=134217728로 설정합니다.

(2^27 = 128M)

숫자만 입력할 수 있기 때문에.

정기적으로 다음 문서를 수행할 수 있습니다.

https://dev.mysql.com/doc/refman/8.0/en/packet-too-large.html

코드는 다음과 같습니다.

// your codes
$pdo = db::connection()->getPdo();
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);

따라서 sql 쿼리 전에 아래 코드를 추가합니다.

$pdo = db::connection()->getPdo();

// Increase interactive_timeout
$prepend_sql = "SET SESSION interactive_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);

// Increase wait_timeout 
$prepend_sql = "SET SESSION wait_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);

// your codes
/* $pdo = db::connection()->getPdo(); */
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);

클라이언트가 SSL을 사용하여 연결하려고 하는 반면 MySQL/MariaDB 서버는 SSL을 사용하지 않을 수 있습니다.

해결책은 연결이 활성화되어 있는지 확인하는 것입니다. 연결을 다시 설정하지 않으면 여기서 완벽하게 작동했습니다.

<?php

require_once ('config.php');

class DB {

    private static $instance;
    
    private function __construct() {
        ;
    }
    
    public static function getInstance() {
        if (!isset(self::$instance)) {
            try {
                self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
                self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
            } catch (PDOException $e) {
                echo $e->getMessage();
            }
        }
        
        try {
            $testConn = self::$instance->prepare('SELECT 1');
            $testConn->execute();
            $testConn = $testConn->fetchAll(PDO::FETCH_ASSOC)[0];
        } catch (Exception $ex) {
            try {
                self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
                self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
            } catch (PDOException $e) {
                echo $e->getMessage();
            }
        }

        return self::$instance;
    }

    public static function prepare($sql) {
        return self::getInstance()->prepare($sql);
    }
    
    public static function lastInsertId() {
        return self::getInstance()->lastInsertId();
    }

}

언급URL : https://stackoverflow.com/questions/33250453/how-to-solve-general-error-2006-mysql-server-has-gone-away

반응형