@accountnujen

Почему может возникать mysql ошибка 2006, если timeout 28800?

Уже который раз ловлю вот такую ошибку, однако она хаотично появляется без повода и без предпосылки:
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away in /var/www/web/libra.php:56 Stack trace: #0 /var/www/web/libra.php(56): PDO->query() #1 /var/www/web/streamer.php(127): getDB() #2 {main} thrown in /var/www/web/libra.php on line 56

Может неделю работать и выкинуть ошибку, а может и двух дней не отработать.

Если коротко: скрипт поддерживает вечное соединение с камерой и опрашивает её на новые видео, записывая путь к файлу каждого видео в БД. В случае разрыва соединения, он обращается к базе и получает информацию о последнем удачном полученном видео с камеры. В тот момент, когда соединение будет восстановлено, он должен проверить: "не появилось ли новых видео с момента возникновения ошибки, до успешного переподключения". 2006 ошибку ловлю именно после того, как случается разрыв с камерой и он пытается достать из базы последнее успешное взаимодействие.

на 56 строке в libra.php у меня функция получения данных из бд, а именно строка fetchAll():
function getDB($action, $data = false) {
	global $pdo;
	# все пустые
	if ($action === "get0") {
		$sql ="SELECT * FROM joblist WHERE status = 0";
		($data) ? $sql.= $data : null;
	} else
	# все с даты
	if ($action === "getdate") {
		$sql ="SELECT * FROM joblist WHERE DATE(time) >= '$data' AND action = 'get_video' AND status = 1";
	}
	# последняя запись
	if ($action === "getlast") {
		$sql ="SELECT * FROM joblist ORDER BY id DESC LIMIT 1";
	}

	return $pdo->query($sql)->fetchAll(); # 56 строка
}

а в streamer на 127 у меня получение времени разрыва соединения с хостом через curl.
if ($status === 1) {
	$status = 0;
	# указываем время возникновения ошибки #
	$time_err = getDB("getlast")[0]["time"] ?? date("Y-m-d H:i:s"); # 127 строка
	p(["Последнее время из БД"=>$time_err]);
}


В сети указывают на проблему с timeout, мол на продакшене у многих стоит не локальное значение, но у меня не так. У меня и interactive_timeout, и mysqlx_wait_timeout, и wait_timeout = 28800. Ещё пишут про буфер, однако у меня в данных SELECT * FROM joblist ORDER BY id DESC LIMIT 1, что не очень похоже на переполненный буфер.
  • Вопрос задан
  • 63 просмотра
Пригласить эксперта
Ответы на вопрос 1
pickHabr
@pickHabr
fullstack разработчик
Ещё пишут про буфер, однако у меня в данных SELECT * FROM joblist ORDER BY id DESC LIMIT 1, что не очень похоже на переполненный буфер.

Это единственный запрос, который выполняется к этой базе?

MySQL server has gone away - означает, что клиент потерял соединение с MySql сервером. Если есть другие запросы, которые сильно нагружают базу, то стоит попробовать увеличить буфер или настроить кластер или увеличить память. Если серьезной нагрузки нет, то стоит посмотреть в сторону смены сервера, на котором крутится mysql, на случай если проблема связана с сетью.

Еще стоит глянуть что происходит в логах самого mysql, есть ли там что-то интересное.

В качестве быстрого решения можно обернуть выполнение запроса в try catch, внутри catch пересоздать подключение и повторить попытку. Либо в catch делать запись например в файл что был фейл, завершать скрипт, а после перезапуска (например кроном) как-то это обрабатывать
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы