Симптомы потери автоинкремента таблицами WordPress

  • 19.07.15
  • 12:15
  • 31608
  • 2

У одного ресурса, работающего на WordPress, возникли такие проблемы:

  • невозможно создать пост любого типа;
  • пользователи не могут зарегистрироваться;
  • при комментировании WordPress заявляет, что посетитель «комментирует слишком быстро» или что «комментарий сохранить не удалось», хотя сам комментарий после создания может корректно отображаться;
  • ни манипуляции с плагинами/темами, ни переустановка/обновление WordPress результата не дают.

Причина проблемы кроется в отсутствии автоинкремента и, возможно, первичных ключей у некоторых таблиц — WordPress перекладывает на БД определение идентификаторов новых постов, комментариев, регистрируемых пользователей, термов и т.д.

Лечение описывается в заметке о лечении, а симптомы выглядят так:

Посты

Экран нового поста при неполадках

Если автоинкремент отсутствует у wp_posts, то на экране нового поста любого типа (wp-admin/post-new.php) WordPress выдаёт сообщение «Вы редактируете страницу, на которой отображаются свежие записи», скрывает редактор текста поста и перекраивает метабокс «Опубликовать».

При этом в таблице wp_posts создаётся запись с нулевым идентификатором и значениями по умолчанию в остальных полях. Статус таких постов — черновик, в списке постов они не отображаются.

В таблицу метаданных wp_postmeta никаких изменений не вносится. При восстановлении БД посты с нулевыми идентификаторами можно удалить без каких-либо опасений.

Пользователи

Ошибка: регистрация не удалась

Отсутствие автоинкремента у wp_users приводит к проблемам с регистрацией пользователей. Все регистрирующиеся увидят сообщение о неудачной регистрации, а их информация будет добавлена в wp_users с нулевым идентификатором (если первичный ключ не потерян, добавление произойдёт только в первый раз). Писем о регистрации WordPress в этом случае не отправляет.

Создание нового пользователя администратором даёт такой результат: Новый пользователь без логина, имени и почты.

Новый пользователь отображается без логина, имени и почты.

Новая запись также добавлена в wp_users, в wp_usermeta никаких изменений не внесено. В списке на экране «Все пользователи» (wp-admin/users.php) некорректная запись отображается только одна, вне зависимости от их количества в таблице. Удалить такого пользователя штатными средствами нельзя: клик по ссылке «Удалить» никаких действий не производит, а ссылка на редактирование его профиля ведёт к профилю текущего авторизованного администратора.

Авторизоваться пользователь с нулевым идентификатором не сможет, даже если пароль будет ему известен. С ненулевым — после восстановления идентификаторов — сможет, но так как метаданные у него полностью отсутствуют, то в админку он не попадёт: для этого требуются полномочия хотя бы подписчика, а они хранятся в метаданных (в полях вида "{$prefix}capabilities", где $prefix — префикс таблиц того сайта, на которые распространяются эти полномочия — wp_capabilities, например).

Комментарии

Комментарии находятся в таблице wp_comments. Симптомы отсутствия автоинкремента у поля comment_ID выглядят так:

  • после отправки нового комментария WordPress сообщает о невозможности его добавления;
  • добавленный комментарий может корректно отображаться, вопреки сообщению;
  • комментарий, сделанный администратором, дублируется;
  • сообщений о сделанном комментарии модераторам не отправляется;
  • комментарий нельзя удалить, пометить как спам, одобрить или отредактировать.

Хуки действий 'wp_insert_comment', 'comment_post', 'set_comment_cookies' в такой ситуации не активируются. Если их обработчики помещают в метаданные комментария часть пришедшей с ним информации — такая информация для новых комментариев будет потеряна.

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

Сообщение об ошибке, выдаваемое при попытке комментирования, зависит от полномочий пользователя. Пользователь, не являющийся администратором (не обладающий правом 'manage_options'), получит сообщение «Вы комментируете слишком быстро. Попридержите коней.» (в нелокализованной версии эта строка выглядит как «You are posting comments too quickly. Slow down.»)

Вы комментируете слишком быстро. Попридержите коней.

Тут срабатывает механизм предотвращения флуда: оставленный комментарий после добавления в БД не признаётся добавленным (из-за нулевого идентификатора), после чего происходят некоторые проверки, в ходе которых время его создания сравнивается со временем последнего комментария текущего посетителя. Последним комментарием оказывается этот же самый, только что добавленный. Результат выглядит так, будто он добавляется одновременно с предыдущим, что и приводит к срабатыванию механизма. Минимальный интервал между двумя комментариями одного автора установлен в 15 секунд. На администраторов это ограничение не распространяется.

Сообщение, выдаваемое администратору, выглядит как: «ОШИБКА: Не удалось сохранить комментарий. Пожалуйста, повторите попытку позже.» Здесь механизм проверки на флуд не применяется. После первого добавления, признанного неудачным, проверяются только поля комментария. Затем он добавляется повторно. Результат оказывается тем же самым (нулём) и добавление комментария завершается с ошибкой.

ОШИБКА: Не удалось сохранить комментарий.

В итоге, если wp_comments не имеет первичного ключа, каждый комментарий администратора будет продублирован.

Некорректные комментарии на экране «Комментарии» (wp-admin/edit-comments.php) отображаются нормально, но обработке не поддаются: их невозможно удалить или пометить как спам, неодобренные нельзя одобрить. Удаление и перемещение в спам выполняются чисто косметически — после обновления страницы картина восстанавливается. При клике на «Свойства» открываются свойства самого верхнего комментария в наборе. На экране редактирования комментария выдаётся надпись «Оп-па, комментария с таким ID не найдено.» (нелокализованная версия — «Oops, no comment with this ID.»)

Что делать?

Инструктаж по решению проблем дан в заметке «Восстановление ключей в таблицах WordPress».

Замечание: на момент последней редакции этой заметки текущей версией WordPress является 4.2.2.

Комментарии
Ильдар Хакимов
15.09.2016
18:22:34

Спасибо! Вроде заработало, хотя и не все команды срабатывают, но для постов и оптионсов сработало. У меня проблема возникла когда скачал базу 64 мегабайта, массово заменил в ней некоторые строки и загрузил обратно, вышла 504 ошибка, видимо что-то не успело выполнится в пределах лимитов сервера.

Индикатор
Денис
19.08.2015
12:47:29

Спасибо, действительно не было ключей и автоинкремента

Индикатор
Оставить комментарий

Добавить комментарий