PHP Warning: Error while sending QUERY packet.

Ошибка PHP Warning:  Error while sending QUERY packet, с таким я столкнулся, когда написал демона на PHP, который в самом начале подключается к базе, а потом ждет задачки из RabbitMQ и выполняет их на базе MariaDB.

Если у вас умирающий скрипт, который некоторое время подумает, а потом снова к базе обращается и может произойти отключение в этот момент, то нужно в my.cnf прибавить таймаут, например, сделать его пару минут

wait_timeout = 120

Но у меня таймаут может быть хоть триста дней, для этого я решил наоборот его убавить, чтобы отловить этот момент и да, если выполняю запросы к базе, то все отлично, отсчитываю 10 сек, снова выполняю и скрипт вылетает, т.к. соединение с базой уже отвалилось. Нужно тут уже сам скрипт подпиливать.

У меня свой класс для работы базы на mysqli, конечно, первым делом подумал о том, что можно проверку соединения делать в момент запроса, но не добавит ли нам это лишних затрат по времени, когда например надо 5 миллионов записей в базу залить, там даже индексы и те добавляют некоторую задержку и я сперва забивал базу данными, потом индексировал поля.

Лучшим решением будет проверка соединения в момент запуска функции, а функция моя чаще выполняет 2-3 запроса и делает это за доли секунды.

Итак, скрипт висит на фоне, висит так пару суток, тут к нему прилетает запрос от Rabbit, он запускает функцию обработки, которая некоторые данные цепляет из базы и тут перед выполнением наших запросиков надо бы проверить соединение и переподключиться...

class DB {
	public $l, 
			$db_name, 
			$last_res, 
			$cnt = 0, 
			$debug=0, 
			$last_rows;
	private $c = []; //connect config

	public function connect(&$c)
	{
		if (isset($c['socket']) && !empty($c['socket'])) 
			@$this->l = new mysqli(NULL, $c['user'], $c['pass'], $c['db_name'], NULL, $c['socket']);
		 else 
			@$this->l = new mysqli($c['host'], $c['user'], $c['pass'], $c['db_name']);

		if ($this->l->connect_errno) 
		{
			http_response_code(503);
			exit("ERROR CONNECT DB");
		}
	}

	function __construct(&$c) {
		$this->connect($c);
		$this->c = &$c;
	}


	public function check_conn () 
	{
		if ($this->l->ping()===false) 
		{
			//проверим еще раз не переподключился ли он автоматом
		    if ($this->l->ping()===false)
		    	$this->connect($this->c);
		} 	
	}

//тут еще дофига методов, но я их не покажу
}

$l - это у нас переменная $mysqli

Я дважды проверил через $mysql->ping, т.к. в некоторых ситуациях в момент выполнения этой функции происходит автоматический реконнект, по умолчанию оно отключено, и даже если включено, то mysqlnd игнорит...

Показать комментарии