WordPress версии 5 - Другое обновление уже выполняется
Я знаю, что похожий вопрос уже задавался ранее, но это НЕ дубликат, так как вопрос касается именно WordPress 5+ и все предложенные решения из похожего вопроса были опробованы без результата.
Проблема:
У меня установлен WordPress версии 5.01, и есть технические проблемы. Логи PHP указывают, что необходимо переустановить ядро WordPress (ошибки синтаксиса в основных SQL-запросах с пустыми $vars
).
Однако при попытке переустановки WordPress через админ-панель появляется сообщение:
Другое обновление уже выполняется
Я перепробовал все решения из этого вопроса, но они либо не работают, либо неприменимы (все было проверено):
- Файл
.maintenance
был отключен вручную. - В таблице
<...>_options
отсутствует тег блокировки обновлений.lock
, хотя в PHP-коде это подтверждается. - Все плагины были отключены.
- Блокировка не снимается автоматически через 15 минут.
Но я до сих пор не могу найти ни причину появления уведомления, ни само уведомление в PHP-коде, чтобы вручную его отменить (ссылка здесь).
Вопрос:
Как отменить сообщение "Другое обновление уже выполняется" в WordPress 5? Вопрос касается именно WP5, так как система, похоже, изменилась по сравнению с версиями до 5.0.
Обновление
Мне нужно не просто обходное решение проблемы, а объяснение, как именно генерируется текст "Другое обновление уже выполняется" в WordPress 5.
Буду благодарен за любые подсказки по этому вопросу.

вы можете попробовать выполнить ручное обновление, если вы не вносили изменений в основные файлы WordPress (если вносили, советую записать их и применить снова после обновления). Просто зайдите на WordPress.org, скачайте последнюю версию WordPress и скопируйте её в корневую папку на сервере. Убедитесь, что перезаписываете только основные файлы WordPress, не трогая папку wp-content. Введите свои данные в файл wp-config.php, и, скорее всего, это решит вашу проблему.
P.S. Не забудьте сделать резервную копию базы данных и исходных папок WordPress перед продолжением.

Вы также получите эту ошибку, если WordPress не может вставить lock
в таблицу wp_options
. Это может произойти, если таблица настроена неправильно, например, при копировании из другого источника. Поле option_id
должно быть автоинкрементным, иначе обновление завершится ошибкой. Проверьте, можете ли вы вручную вставить запись блокировки в базу данных:
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('core_updater.lock', '1', 'no');
Если поле option_id
не является автоинкрементным и этот запрос завершается ошибкой, вам нужно сделать поле option_id
автоинкрементным. Возможно, перед этим потребуется удалить индекс в этом поле.

Не уверен, поможет ли это расширить обсуждение и разобраться в проблеме, но я сузил сообщение об ошибке до строк 118-122 в файле class-core-upgrade.php (wp-admin/includes)
// Блокировка для предотвращения множественных обновлений ядра.
$lock = WP_Upgrader::create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS );
if ( ! $lock ) {
return new WP_Error( 'locked', $this->strings['locked'] );
}
Функция create_lock находится в файле class-wp-upgrader.php на строках 885-918
Добавив echo перед возвратами, я смог сузить проблему до этих строк в функции (899-901)
// Если блокировка не может быть создана и нет существующей блокировки, выходим.
if ( ! $lock_result ) {
return false;
}
По какой-то причине я могу выполнить запрос выше через RouteXL, и блокировка создается, но WordPress не может вставить запрос на строке 893
$lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() ) );
Добавив эту строку сразу после 893
echo $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() );
я получаю вывод этого кода при попытке обновления
INSERT IGNORE INTO `wp_options` ( `option_name`, `option_value`, `autoload` ) VALUES ('core_updater.lock', '1606851384', 'no') /* LOCK */
Я выполнил этот запрос вручную, и он корректно вставляет строку в базу данных MySQL, используя те же учетные данные, что и мой WordPress.
Я не совсем понимаю, почему WordPress не может выполнить это, хотя вручную с теми же учетными данными все работает.

Я изменил функцию create_lock, чтобы она выдавала коды ошибок и дополнительную информацию. Также я убрал IGNORE из INSERT в запросе, и теперь наконец-то получаю ошибку при попытке обновления в MySQL:
update-core.php теперь выводит:
Обновление WordPress
QUERY[ INSERT INTO `wp_options` ( `option_name`, `option_value`, `autoload` ) VALUES ('core_updater.lock', '1606853111', 'no') /* LOCK */ ]
QUERY ERROR[ Duplicate entry 'core_updater.lock' for key 'option_name' ]
Здесь происходит ошибка
Другое обновление уже выполняется.
Duplicate entry 'core_updater.lock' for key 'option_name' Вот почему происходит сбой!
Самое странное? Я не вижу этой строки или значения в своей таблице wp_options! Очень и очень странно! Теперь мне нужно понять, почему система считает это дубликатом, хотя такой опции нет в моей базе данных!
class-wp-upgrader.php (изменен для диагностики)
public static function create_lock( $lock_name, $release_timeout = null ) {
global $wpdb;
if ( ! $release_timeout ) {
$release_timeout = HOUR_IN_SECONDS;
}
$lock_option = $lock_name . '.lock';
// Попытка установить блокировку
$q = $wpdb->prepare( "INSERT INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() );
$lock_result = $wpdb->query( $q );
echo "QUERY[ $q ]<br>";
echo "QUERY ERROR[ ".$wpdb->last_error." ]<br>";
//$test_result = $wpdb->query( "INSERT INTO wp_options (option_name, option_value, autoload) VALUES('ZZZ', '1', 'no')");
//if( ! $test_result ) echo "test failed";
if ( ! $lock_result )
{
$lock_result = get_option( $lock_option );
// Если блокировку не удалось создать и её нет - выходим
if ( ! $lock_result ) {
echo "Здесь происходит ошибка<br>";
return false;
}
// Проверяем, действительна ли ещё блокировка. Если да - выходим
if ( $lock_result > ( time() - $release_timeout ) ) {
return false;
}
// Должна существовать просроченная блокировка - очищаем её и пробуем снова
WP_Upgrader::release_lock( $lock_name );
return WP_Upgrader::create_lock( $lock_name, $release_timeout );
}
// Обновляем блокировку, так как на этом этапе мы точно её получили, осталось только запустить действия
update_option( $lock_option, time() );
return true;
}
