MySQL и MariaDB LinuxWindowsmacOS

Как исправить MySQL Commands out of sync в mysqli

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Ошибка клиента MySQL «Commands out of sync; you can’t run this command now» означает, что приложение пытается отправить новую команду, пока предыдущий результат или набор результатов ещё не обработан. Особенно часто это происходит в PHP mysqli после multi_query или CALL хранимой процедуры. Проблема относится к последовательности вызовов клиента, а не к повреждению таблицы; перезапуск mysqld не нужен.

В этой статье
  1. Что означает неисправность
  2. Возможные причины и признаки
  3. Пошаговая диагностика и решение
  4. Команды для диагностики и проверки
  5. Пример для отдельной тестовой базы или учебного проекта
  6. Проверка результата и дальнейшие действия

#Что означает неисправность

Ошибка клиента MySQL «Commands out of sync; you can’t run this command now» означает, что приложение пытается отправить новую команду, пока предыдущий результат или набор результатов ещё не обработан. Особенно часто это происходит в PHP mysqli после multi_query или CALL хранимой процедуры. Проблема относится к последовательности вызовов клиента, а не к повреждению таблицы; перезапуск mysqld не нужен.

#Возможные причины и признаки

Возможная причинаКак узнатьЧто делать
После multi_query остался второй результатДрайвер ожидает извлечения и освобождения всех результатов предыдущего набора команд.Первый запрос возвращает строки, а следующий query внезапно даёт Commands out of sync.Пройти more_results/next_result и освободить каждый mysqli_result.
CALL процедуры возвращает дополнительные наборыПроцедура или драйвер могут оставлять ещё результаты после первого набора строк.Ошибка возникает только после CALL, обычный SELECT работает.Использовать поддерживаемый драйвером порядок чтения всех результатов.
Результат из неблокирующего чтения ещё не освобождёнПри unbuffered fetch приложение прерывает выборку и отправляет новый запрос тем же соединением.После вызова use_result/неполного fetch возникает ошибка порядка команд.Прочитать оставшийся набор или вызвать free на соответствующем объекте результата.

#Пошаговая диагностика и решение

  1. Определите, где возникает ошибка и какой драйвер используетсяВ журнале PHP найдите ошибку Commands out of sync и строку исходного кода, где вызывается query/prepare/execute. Запишите, выполнялся ли до этого multi_query, CALL или use_result. Если используете PDO, Python либо нативный клиент, ищите документацию именно этого драйвера — примеры mysqli далее нельзя подставлять без изменений.
  2. Проследите операции в одном соединенииВ редакторе кода найдите создание $mysqli, затем все запросы до проблемного места. Составьте последовательность: multi_query → store_result → free → more_results → next_result → query. Если новый query стоит раньше окончания обработки всех результатов, ошибка ожидаема. Не пытайтесь устранить её открытием бесконечного числа новых соединений, поскольку это вызовет другие сбои.
  3. Проверьте, не используется ли multi_query без необходимостиДля одного SELECT, INSERT или UPDATE в mysqli используйте обычный query или подготовленный запрос и освобождайте полученный mysqli_result. Multi_query необходим только тогда, когда явно требуется несколько SQL-операторов в одном вызове. Удаление лишнего multi_query снижает вероятность ошибки и не ослабляет защиту от SQL-инъекций.
  4. Обрабатывайте каждый возвращённый набор по порядкуПосле успешного multi_query вызовите store_result для текущего результата; если это mysqli_result, прочитайте строки и освободите объект методом free. Затем проверьте more_results и вызовите next_result, чтобы перейти дальше, включая служебные результаты. Ошибку перехода проверяйте через errno/error, а не считайте любой false подтверждением завершения.
  5. Разделите работу с данными и SQL из пользовательского вводаНикогда не вставляйте в multi_query текст из HTML-формы, параметра URL или запроса внешней системы. Для значений используйте mysqli prepared statements с bind_param. При разборе нескольких запросов убедитесь, что SQL написан приложением, а не собран из пользовательских строк, иначе на исправленной цепочке можно открыть SQL-инъекцию.
  6. Проверьте обработку CALL хранимой процедурыЕсли сначала вызывается CALL, прочитайте все строки результата, а затем завершите извлечение остальных наборов в порядке, предусмотренном mysqli. Проверьте, что хранимая процедура не возвращает дополнительные SELECT, которые забыты в клиентском коде. В тестовом проекте временно замените сложную процедуру простой с двумя SELECT и убедитесь, что дальнейший SELECT теперь разрешён.
  7. Прогоните короткий безопасный пример в тестовом PHPСоздайте файл вне публичного каталога веб-сервера, настройте доступ к отдельной тестовой БД и поместите пример чтения результатов. Запускайте через php имя_файла.php в терминале, где установлен PHP CLI и расширение mysqli. Пароль берите из безопасной конфигурации или окружения, не пишите его в коде и не выводите в журнал.
  8. Проверьте запрос после освобождения всех результатовКогда цикл по всем наборам завершится, выполните через то же соединение простой SELECT 1 AS ok. Ожидается ok=1 и отсутствие Commands out of sync. Если ошибка повторилась, снимите трассу порядка вызовов, отдельно проверьте использование use_result и обработку исключений; верните прежнюю версию кода, если исправление нарушило чтение результатов.

#Команды для диагностики и проверки

SQLКоманда
В консоли MySQL команда лишь проверяет подключение, но сама по себе не воспроизводит клиентский сбой; реальную проверку нужно делать через то же mysqli-соединение после обработки всех результатов.
SELECT 1 AS ok;

#Пример для отдельной тестовой базы или учебного проекта

PHP
Учебный PHP-файл только для доверенной тестовой базы и вне общедоступной папки сайта. Задайте DB_HOST, DB_USER, DB_PASSWORD и DB_NAME в окружении безопасным способом. Вывод: first_value=1, second_value=2, ok=1. PHP 8.1+ при ошибках mysqli по умолчанию может бросать mysqli_sql_exception.
<?php
$mysqli = new mysqli(
    getenv('DB_HOST') ?: '127.0.0.1',
    getenv('DB_USER') ?: '',
    getenv('DB_PASSWORD') ?: '',
    getenv('DB_NAME') ?: ''
);
$mysqli->set_charset('utf8mb4');
$mysqli->multi_query('SELECT 1 AS first_value; SELECT 2 AS second_value');
do {
    $result = $mysqli->store_result();
    if ($result instanceof mysqli_result) {
        while ($row = $result->fetch_assoc()) {
            var_export($row); echo PHP_EOL;
        }
        $result->free();
    }
    if (!$mysqli->more_results()) {
        break;
    }
    if (!$mysqli->next_result()) {
        throw new RuntimeException($mysqli->error);
    }
} while (true);
$result = $mysqli->query('SELECT 1 AS ok');
var_export($result->fetch_assoc());
$result->free();

#Проверка результата и дальнейшие действия

Исправление подтверждено, если на одном и том же mysqli-соединении все два SELECT возвращают результаты, а следующий SELECT 1 выполняется без Commands out of sync. Если появляются неожиданные пустые результаты, проверьте очередность вызовов и ошибки next_result, а не пропускайте их. Откат — возвращение исходного кода из контроля версий, если новая обработка нарушает бизнес-логику.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.