Вопрос или проблема
После восстановления базы данных 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 после восстановления базы данных из резервной копии, вам не обязательно паниковать. В данной статье мы разберем основные причины, по которым это может происходить, и предоставим детальное руководство по восстановлению автонумерации, чтобы вернуть вашу базу данных в рабочее состояние.
Причины проблемы
После восстановления базы данных автонумерация может потеряться по нескольким причинам:
-
Ошибка экспорта/импорта: Если экспортировали базу данных через phpMyAdmin и получили ошибку при повторном импорте, это может привести к тому, что секция создания первичных ключей не выполнится.
-
Неудачная миграция: Использование инструментов миграции, таких как Amazon RDS Database Migration Service, может не переносить индексы, ключи и автонумерацию, оставляя таблицы с некорректной структурой.
-
Кэширование в InnoDB: Значения автонумерации могут храниться в памяти, и их сброс не всегда происходит корректно после восстановления данных.
Шаги для восстановления автонумерации
Чтобы восстановить автонумерацию в таблицах WordPress, выполните следующие действия:
-
Проверьте таблицы: Убедитесь, что таблицы корректно созданы и существуют. Если какие-либо таблицы повреждены, удалите их и создайте заново с правильной структурой.
-
Установите правильную автонумерацию: Используйте следующий 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;
- Настройте текущие значения автонумерации: Кто-то из пользователей может столкнуться с ошибкой, когда значение автонумерации не соответствует текущему наибольшему значению первичного ключа. Используйте следующую команду для установки начального значения автонумерации:
ALTER TABLE wp_posts AUTO_INCREMENT = 2043; -- Замените 2043 на максимальный ID + 1
- Удаление дубликатов, если это необходимо: Если в таблицах присутствуют записи с ID равным нулю, это может мешать установке автонумерации. Удалите такие записи перед изменением:
DELETE FROM wp_posts WHERE ID=0;
-- Повторите для других таблиц
- Создание индексов: Не забудьте пересоздать индексы для таблиц, если это необходимо. Например:
CREATE INDEX term_id ON wp_termmeta(term_id);
Заключение
Восстановление автонумерации в базе данных WordPress может вызвать определенные трудности, особенно после миграции или восстановления из резервной копии. Главное — тщательно следить за структурой таблиц и проводить исправления при помощи SQL-запросов. Помните о регулярном резервном копировании, чтобы избежать потери данных в будущем.
Если у вас остались вопросы или необходима помощь, не стесняйтесь обращаться по специализированным форумам или привлекать профессионалов для решения сложных случаев.