#Симптом и границы применимости
Миграция структуры MySQL завершается ошибкой внешнего ключа: 1215, errno 150, 1451 или 1452. Инструкция относится к таблицам InnoDB; исправление зависит от типа столбцов, индексов и наличия связанных строк.
#Как отличить возможные причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Несовпадение описанияТип и знак связываемых столбцов не совпадают либо символьные столбцы имеют разную кодировку. | Ошибка при ADD CONSTRAINT | Сверить SHOW CREATE TABLE |
| Нет связанной записиУ дочерней записи нет родительского ключа либо удаляется родительская запись с потомками. | Ошибка 1451/1452 при DML | Исправить порядок миграции и данные |
| Нет нужного индексаВнешний ключ опирается на неподходящий индекс или движок. | errno 150 в диагностике InnoDB | Проверить индекс и InnoDB |
#Пошаговая диагностика и безопасное исправление
- 1. Уточните номер ошибки и точную операциюОткройте журнал миграции, найдите первую ошибку и сохраните запрос целиком. 1215/errno 150 относится к созданию ограничения, а 1451/1452 — к действиям над связанными строками. Не запускайте неудачную миграцию повторно вслепую.
- 2. Сделайте восстанавливаемую копию перед изменением схемыВыполните штатное резервное копирование и пробное восстановление в отдельную базу. Убедитесь, что у вас есть файл миграции, схема до миграции и возможность отменить развёртывание. ALTER TABLE может блокировать таблицу.
- 3. Посмотрите текущее описание обеих таблицОткройте клиент mysql или инструмент администрирования, подключитесь к нужной схеме и выполните обе команды с реальными названиями таблиц. Сравните engine, INT UNSIGNED, индексы, collation и наличие целевых ключей.
- Консоль mysql, чтение структурыSQLКомандаКонсоль mysql, чтение структуры. appdb и названия таблиц — заменяемые примеры.
SHOW CREATE TABLE appdb.parent_table;SHOW CREATE TABLE appdb.child_table;
- 4. Уточните техническую причину отказа InnoDBЕсли ошибка возникла сразу после ALTER TABLE, в той же административной сессии запросите диагностическое сообщение движка. Найдите LATEST FOREIGN KEY ERROR; этот раздел может относиться к последнему сбою другого соединения, поэтому сопоставьте время.
- В интерактивном клиенте mysql \G — завершающий формат вывода, не точка с запятойSQLКомандаВ интерактивном клиенте mysql \G — завершающий формат вывода, не точка с запятой.
SHOW ENGINE INNODB STATUS\G
- 5. Проверьте связанные строки без удаленияДля 1452 найдите дочерние строки, у которых нет соответствующего родителя, используя LEFT JOIN в копии базы. Не запускайте DELETE и не подставляйте имена таблиц без подтверждения структуры.
- Только чтение; пример для parent_id и id, замените по реальной схемеSQLКомандаТолько чтение; пример для parent_id и id, замените по реальной схеме.
SELECT c.parent_id FROM appdb.child_table AS c LEFT JOIN appdb.parent_table AS p ON p.id=c.parent_id WHERE c.parent_id IS NOT NULL AND p.id IS NULL LIMIT 20;
- 6. Исправьте проект миграции, а не защиту базыНа тестовой копии приведите типы колонок к совместимым, обеспечьте индексы и сначала создайте родительские записи. Если ошибка при удалении, отдельно согласуйте бизнес-правила ON DELETE; не включайте CASCADE без понимания последствий.
- 7. Повторите миграцию и сравните результатЗапустите исправленную миграцию на тесте, затем вновь прочитайте SHOW CREATE TABLE и проверьте контрольные строки приложения. Только после успешного восстановления и окна обслуживания применяйте в рабочей среде.
#Как проверить, что проблема устранена
Нужное ограничение присутствует в SHOW CREATE TABLE, миграция повторно проходит на копии и все связи данных сохраняются.
#Если исправление не помогло
Сохраните первую ошибку ALTER TABLE и вывод SHOW ENGINE INNODB STATUS; передайте разработчику миграции. Включение foreign_key_checks=0 не исправляет повреждённые связи и не проверяет их повторно после включения.