База данных WordPress потеряла автоинкремент

Вопрос или проблема

После восстановления базы данных WordPress из резервной копии, похоже, что все таблицы потеряли авто-инкремент в столбцах первичного ключа. Я читал в другом посте, что это может быть связано с тем, что InnoDB сохраняет значение авто-инкремента в памяти. Ранее я восстанавливал и переносил базы данных без таких проблем. Кто-то сталкивался с подобной проблемой? Спасибо заранее за любую помощь.

У меня была подобная проблема, я ее решил, и поскольку этот вопрос часто встречается в Google, он может помочь другим.

Я перенес несколько баз данных WordPress с AWS RDS MySQL на MySQL, работающий на экземпляре EC2, используя сервис миграции баз данных. Я не знал, что он не копирует индексы, ключи, авто-инкремент или вообще что-либо, кроме основ. Конечно, лучший подход – это создать дамп базы данных с помощью mysqldump и импортировать его вручную, но в одной установке WordPress были значительные изменения, и я не хотел их повторять. Вместо этого я вручную восстановил значения авто-инкремента и индексы.

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

ALTER TABLE wp_termmeta MODIFY COLUMN meta_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_terms MODIFY COLUMN term_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_term_taxonomy MODIFY COLUMN term_taxonomy_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_commentmeta MODIFY COLUMN meta_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_comments MODIFY COLUMN comment_ID bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_links MODIFY COLUMN link_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_options MODIFY COLUMN option_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_postmeta MODIFY COLUMN meta_id bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_users MODIFY COLUMN ID bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_posts MODIFY COLUMN ID bigint(20) unsigned NOT NULL auto_increment;
ALTER TABLE wp_usermeta MODIFY COLUMN umeta_id bigint(20) unsigned NOT NULL auto_increment;

CREATE INDEX term_id on wp_termmeta (term_id);
CREATE INDEX meta_key on wp_termmeta (meta_key(191));
CREATE INDEX slug on wp_terms (slug(191));
CREATE INDEX name on wp_terms (name(191));
CREATE UNIQUE INDEX term_id_taxonomy on wp_term_taxonomy (term_id, taxonomy);
CREATE INDEX taxonomy on wp_term_taxonomy (taxonomy );
CREATE INDEX comment_id on wp_commentmeta (comment_id);
CREATE INDEX meta_key on wp_commentmeta (meta_key(191));
CREATE INDEX comment_post_ID on wp_comments (comment_post_ID);
CREATE INDEX comment_approved_date_gmt on wp_comments (comment_approved,comment_date_gmt);
CREATE INDEX comment_date_gmt on wp_comments (comment_date_gmt);
CREATE INDEX comment_parent on wp_comments (comment_parent);
CREATE INDEX comment_author_email on wp_comments (comment_author_email(10));
CREATE INDEX link_visible on wp_links (link_visible);
CREATE UNIQUE INDEX option_name on wp_options (option_name);
CREATE INDEX post_id on wp_postmeta (post_id);
CREATE INDEX meta_key on wp_postmeta (meta_key);
CREATE INDEX post_name on wp_posts (post_name(191));
CREATE INDEX type_status_date on wp_posts (post_type,post_status,post_date,ID);
CREATE INDEX post_parent on wp_posts (post_parent);
CREATE INDEX post_author on wp_posts (post_author);
CREATE INDEX user_login_key on wp_users (user_login);
CREATE INDEX user_nicename on wp_users (user_nicename);
CREATE INDEX user_email on wp_users (user_email);
CREATE INDEX user_id on wp_usermeta (user_id);
CREATE INDEX meta_key on wp_usermeta (meta_key(191));

ALTER TABLE wp_terms AUTO_INCREMENT = 10000;
ALTER TABLE wp_term_taxonomy AUTO_INCREMENT = 10000;
ALTER TABLE wp_commentmeta AUTO_INCREMENT = 10000;
ALTER TABLE wp_comments AUTO_INCREMENT = 10000;
ALTER TABLE wp_links AUTO_INCREMENT = 10000;
ALTER TABLE wp_options AUTO_INCREMENT = 10000;
ALTER TABLE wp_postmeta AUTO_INCREMENT = 10000;
ALTER TABLE wp_users AUTO_INCREMENT = 10000;
ALTER TABLE wp_posts AUTO_INCREMENT = 10000;
ALTER TABLE wp_usermeta AUTO_INCREMENT = 10000;

Заметки

  • Вам следует проверить свои таблицы и убедиться, что вы установили авто-инкремент на значение, которое имеет смысл для данной таблицы.
  • Если вы получите ошибку “alter table causes auto_increment resequencing resulting in duplicate entry 1” (или 0, или что-то еще). Обычно это исправляется удалением записи с ID 0 или 1 в таблице. Обратите внимание, что с этим нужно быть осторожным, так как это может удалить важную строку.

Почему это произошло? Вот что пошло не так в моем случае:

Если вы экспортировали свою базу данных с помощью phpadmin и получили ошибку при повторном импорте, код, который добавляет первичный ключ, не выполняется, потому что он находится в конце SQL-файла, а не в его создании.

Прежде чем я это понял, я обновился до phpmyadmin 5 бета-версии, и он импортировал файлы с ключом, хотя у меня все еще была ошибка.

Первый урок – не позволяйте вашему импорту завершиться с ошибками, даже если ваши таблицы на месте. У меня произошел сбой на таблице, которая начиналась с wp_w, поэтому она шла после пользователя и испортила мои авто-инкременты.

Если вы посмотрите внизу вашего SQL-экспорта, вы найдете команду alter table для добавления первичного ключа и авто-инкремента.

Вам не нужно указывать авто-инкремент, он автоматически знает, каким будет следующее значение, например:

ALTER TABLE wp_posts CHANGE ID ID  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;

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

DELETE FROM wp_posts  WHERE ID=0;

Вот полный набор обновлений. Если ваша таблица содержит эти значения, это вызовет ошибку.

DELETE FROM wp_termmeta  WHERE meta_id=0;
DELETE FROM wp_terms  WHERE term_id=0;
DELETE FROM wp_term_taxonomy  WHERE term_taxonomy_id=0;
DELETE FROM wp_commentmeta  WHERE meta_id=0;
DELETE FROM wp_comments  WHERE comment_ID=0;
DELETE FROM wp_links  WHERE link_id=0;
DELETE FROM wp_options  WHERE option_id=0;
DELETE FROM wp_postmeta  WHERE meta_id=0;
DELETE FROM wp_users  WHERE ID=0;
DELETE FROM wp_posts  WHERE ID=0;
DELETE FROM wp_usermeta  WHERE umeta_id=0;

ALTER TABLE  wp_termmeta ADD PRIMARY KEY(meta_id);
ALTER TABLE  wp_terms ADD PRIMARY KEY(term_id);
ALTER TABLE  wp_term_taxonomy ADD PRIMARY KEY(term_taxonomy_id);
ALTER TABLE  wp_commentmeta ADD PRIMARY KEY(meta_id);
ALTER TABLE  wp_comments ADD PRIMARY KEY(comment_ID);
ALTER TABLE  wp_links ADD PRIMARY KEY(link_id);
ALTER TABLE  wp_options ADD PRIMARY KEY(option_id);
ALTER TABLE  wp_postmeta ADD PRIMARY KEY(meta_id);
ALTER TABLE  wp_users ADD PRIMARY KEY(ID);
ALTER TABLE  wp_posts ADD PRIMARY KEY(ID);
ALTER TABLE  wp_usermeta ADD PRIMARY KEY(umeta_id);

ALTER TABLE wp_termmeta CHANGE meta_id meta_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_terms CHANGE term_id term_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_term_taxonomy CHANGE term_taxonomy_id term_taxonomy_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_commentmeta CHANGE meta_id meta_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_comments CHANGE comment_ID comment_ID  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_links CHANGE link_id link_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_options CHANGE option_id option_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_postmeta CHANGE meta_id meta_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_users CHANGE ID ID  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_posts CHANGE ID ID  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_usermeta CHANGE umeta_id umeta_id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;

Почему это произошло? Трудно сказать точно, потому что есть много переменных, которые нужно учитывать: ошибки при экспорте или импорте, версия MySQL и т.д.

Это скорее специфический вопрос базы данных MySQL и не имеет большого отношения к самому WordPress. Чтобы получить конкретный, не спекулятивный ответ на вопрос почему, я предлагаю задать его в SO или DBA с множеством деталей о вашем процессе резервного копирования.


Решение: ALTER TABLE table_name AUTO_INCREMENT = increment_number

  • Это устанавливает AUTO_INCREMENT вручную на выбранное число
  • Значение increment_number должно быть по меньшей мере на одно число больше, чем ваше текущее максимальное число первичного ключа этой таблицы, который автоинкрементируется
  • Также не забудьте изменить table_name

Пример: ALTER TABLE wp_posts AUTO_INCREMENT = 2043 <- самое большое число в столбце ID + 1

Дополнительные заметки:

  • Вам нужно будет повторить это для каждой таблицы, в которой поврежден авто-инкремент
  • Может быть способ изменить все таблицы сразу, но я не гуру SQL (исправьте меня, если это так)
  • Это займет какое-то время для больших таблиц, потому что ALTER TABLE вызывает перестройку всей таблицы

Больше информации: здесь и здесь

Я написал обновление для этого.

Я использую встроенную схему WP Core, чтобы убедиться, что все таблицы WP Core присутствуют (даже в будущем, когда будет выпущена версия 5.1.1 или выше). Это удаляет поврежденные строки и заново добавляет ключи и первичные ключи. Бесплатный скрипт (и больше объяснений) можно увидеть здесь: https://wpindexfixer.tools.managedwphosting.nl/

Не нужно угадывать значение авто-инкремента тоже.

Я забыл импортировать индексы из конца файла MySQL, так что столкнулся с такой же проблемой, и сложно делать запрос на авто-инкремент один за одним, поэтому я создал скрипт. Он принимает динамическую таблицу и проверяет первичный ключ. Если скрипт находит первичный ключ, то он будет применен к авто-инкременту динамически.

Возьмите переменную подключения к базе данных из вашего wp-config.php и сохраните ее в корне вашего WordPress и запустите по URL.

// Конфигурация базы данных
$host="localhost";
$dbuser="dbuser";
$dbpassword   = 'dbpassword';
$dbname="database";

// подключение к БД
$conn = new mysqli($host, $dbuser, $dbpassword);
try {
    $connection = new PDO("mysql:host=$host;dbname=$dbname", $dbuser, $dbpassword, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode="NO_ZERO_DATE"'));
    $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Подключение успешно";
} catch (PDOException $e) {
    exit("Подключение не удалось: " . $e->getMessage());
}

// получение всех таблиц из БД
$stmt = $connection->prepare('SHOW TABLES');
$stmt->execute();
$table_names = array();
foreach ($stmt->fetchAll() as $row) {
    $table_names[] = $row[0];
}

// для всех таблиц
foreach ($table_names as $table_name) {

    // получение имени первичного ключа
    $stmt = $connection->prepare("show keys from $table_name where Key_name='PRIMARY'");
    $stmt->execute();
    $key_name = $stmt->fetch()['Column_name'];

    // определение типа первичного ключа
    $stmt = $connection->prepare("show fields from $table_name where Field = '$key_name'");
    $stmt->execute();
    $key_type = $stmt->fetch()['Type'];

    // если первичный ключ уже существует, тогда добавляем авто-инкремент
    if ($key_name) {

        try {
            // если авто-инкремент отсутствует, может быть строка с key=0. вычисляем следующий доступный первичный ключ
            $sql = "select (ifnull( max($key_name), 0)+1) as next_id from $table_name";
            $stmt = $connection->prepare($sql);
            $stmt->execute();
            $next_id = $stmt->fetch()['next_id'];

            // даем разумный первичный ключ строке, у которой key = 0, если она существует
            $sql = "update $table_name set $key_name = $next_id where $key_name = 0";
            $stmt = $connection->prepare($sql);
            $stmt->execute();

            // устанавливаем авто-инкремент для первичного ключа
            $sql = "alter table $table_name modify column $key_name $key_type auto_increment";
            $stmt = $connection->prepare($sql);
            $stmt->execute();

        } catch (PDOException $e) {
            echo $e->getMessage() . '\n';
        }
    } else {
        echo "первичный ключ не найден в таблице $table_name.\n";
    }
}
$connection = null;

У меня недавно была подобная проблема с WordPress 6.5.4 – таблица пользователей потеряла свой авто-инкремент и пыталась вставить каждого нового пользователя, созданного в панели управления, с ID пользователя 0.

Я исправил это, экспортировав таблицу пользователей, удалив таблицу пользователей и затем создав ее снова с правильной структурой таблицы следующим образом:

CREATE TABLE `tn_users` (`ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,`user_login` varchar(60) NOT NULL DEFAULT '',`user_pass` varchar(255) NOT NULL DEFAULT '',`user_nicename` varchar(50) NOT NULL DEFAULT '',`user_email` varchar(100) NOT NULL DEFAULT '',`user_url` varchar(100) NOT NULL DEFAULT '',`user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',`user_activation_key` varchar(255) NOT NULL DEFAULT '',`user_status` int(11) NOT NULL DEFAULT 0,`display_name` varchar(250) NOT NULL DEFAULT '',`spam` tinyint(2) NOT NULL DEFAULT 0,`deleted` tinyint(2) NOT NULL DEFAULT 0,PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

После этого загрузите SQL экспорт в текстовый редактор и просто скопируйте и вставьте INSERT инструкции в ваш PHPMyAdmin, чтобы он теперь вставлял старые данные с правильными ID значениями.

Ответ или решение

Восстановление автонумерации в базе данных WordPress после отката

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

Причины проблемы

После восстановления базы данных автонумерация может потеряться по нескольким причинам:

  1. Ошибка экспорта/импорта: Если экспортировали базу данных через phpMyAdmin и получили ошибку при повторном импорте, это может привести к тому, что секция создания первичных ключей не выполнится.

  2. Неудачная миграция: Использование инструментов миграции, таких как Amazon RDS Database Migration Service, может не переносить индексы, ключи и автонумерацию, оставляя таблицы с некорректной структурой.

  3. Кэширование в InnoDB: Значения автонумерации могут храниться в памяти, и их сброс не всегда происходит корректно после восстановления данных.

Шаги для восстановления автонумерации

Чтобы восстановить автонумерацию в таблицах WordPress, выполните следующие действия:

  1. Проверьте таблицы: Убедитесь, что таблицы корректно созданы и существуют. Если какие-либо таблицы повреждены, удалите их и создайте заново с правильной структурой.

  2. Установите правильную автонумерацию: Используйте следующий SQL-код для восстановления автонумерации в каждой таблице:

ALTER TABLE wp_terms MODIFY COLUMN term_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_term_taxonomy MODIFY COLUMN term_taxonomy_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_commentmeta MODIFY COLUMN meta_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_comments MODIFY COLUMN comment_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_links MODIFY COLUMN link_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_options MODIFY COLUMN option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_postmeta MODIFY COLUMN meta_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_users MODIFY COLUMN ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_posts MODIFY COLUMN ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE wp_usermeta MODIFY COLUMN umeta_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
  1. Настройте текущие значения автонумерации: Кто-то из пользователей может столкнуться с ошибкой, когда значение автонумерации не соответствует текущему наибольшему значению первичного ключа. Используйте следующую команду для установки начального значения автонумерации:
ALTER TABLE wp_posts AUTO_INCREMENT = 2043; -- Замените 2043 на максимальный ID + 1
  1. Удаление дубликатов, если это необходимо: Если в таблицах присутствуют записи с ID равным нулю, это может мешать установке автонумерации. Удалите такие записи перед изменением:
DELETE FROM wp_posts WHERE ID=0;
-- Повторите для других таблиц
  1. Создание индексов: Не забудьте пересоздать индексы для таблиц, если это необходимо. Например:
CREATE INDEX term_id ON wp_termmeta(term_id);

Заключение

Восстановление автонумерации в базе данных WordPress может вызвать определенные трудности, особенно после миграции или восстановления из резервной копии. Главное — тщательно следить за структурой таблиц и проводить исправления при помощи SQL-запросов. Помните о регулярном резервном копировании, чтобы избежать потери данных в будущем.

Если у вас остались вопросы или необходима помощь, не стесняйтесь обращаться по специализированным форумам или привлекать профессионалов для решения сложных случаев.

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

Капча загружается...