Почему миграция таблицы MySQL без gh-ost останавливает сервис
Самая дорогая миграция — та, что выглядит безобидно: добавить колонку, поменять тип, перестроить индекс. Инструмент отправляет ALTER TABLE на таблицу с сотнями миллионов строк, и на этапе подготовки запрос захватывает блокировку метаданных. Пока она держится, в очередь встают уже не только записи по этой таблице, но и обычные чтения: соединения копятся, время отклика растёт в разы, приложение начинает отдавать ошибки раньше, чем администратор успевает заметить причину.
Дальше срабатывает арифметика. Если операция требует пересборки таблицы, база читает и записывает копию всех строк — накладные расходы растут линейно от объёма, и часы работы превращаются в ночное окно, которое никто не гарантирует. На репликах изменение проигрывается последовательно и с задержкой, поэтому чтение с реплик отдаёт устаревшие данные, а откат уже начатой перестройки без потерь невозможен.
Онлайн-миграция схемы закрывает это разделением работы. gh-ost читает бинарный лог основного узла, создаёт теневую копию таблицы в новом виде и переносит строки небольшими порциями, самостоятельно подбирая темп по нагрузке на сервер и отставанию реплик. Изменения, пришедшие во время переноса, докатываются из лога, поэтому копия остаётся актуальной. Переключение выполняется атомарной перестановкой имён — блокировка таблицы держится доли секунды, а не часы.
Процесс можно приостановить, возобновить и проверить в любой момент; исходная таблица остаётся до подтверждения результата и служит точкой возврата. Дальше разбираем, как это закрывается на практике: порядок шагов, контроль отставания реплик и критерии, по которым переключение безопасно.
Что меняется на практике: время блокировки и класс отказов
Переход на онлайн-схему меняет не «удобство», а измеримые параметры: время блокировки записи, простой сервиса при миграции, окно отката миграции. gh-ost не держит блокирующий ALTER на боевой таблице — он строит копию рядом и переносит в неё изменения из журнала репликации, а блокировка записи сводится к короткому переключению в самом конце. На таблицах в сотни миллионов строк копирование идёт часами, и всё это время сервис принимает запись.
Нагрузка на мастер и поведение реплик
Основная работа идёт в отдельной таблице-призраке: чтение строк порциями, запись чанками, паузы между ними. Мастер получает дополнительную нагрузку от копирования, но её ограничивают явно — числом строк в секунду и порогом по загрузке реплик. Если отставание реплик растёт выше заданного порога, миграция сама приостанавливается и продолжается, когда реплики догнали. Отставание реплик становится управляемой величиной вместо аварии на проде.
Окно отката и ушедший класс отказов
Пока переключение не выполнено, откат — это остановка процесса и удаление таблицы-призрака: боевая таблица не тронута, данные в ней актуальны. После переключения откат — обратный обмен по сохранённой схеме, и он тоже не требует простоя. Уходит целый класс отказов: блокировки на время ALTER, падение миграции на середине по таймауту, деградация реплик под нагрузкой. Вместо «миграция прошла или всё упало» появляется управляемый процесс с предсказуемым окном отката.
Сравнение подходов: gh-ost, триггеры и перестройка таблицы
Способ миграции выбирают по профилю нагрузки, а не по объёму таблицы: важно, сколько времени допустимо держать операцию и что произойдёт при обрыве. Ниже — пять маршрутов и ограничения, из-за которых один из них приходится исключать сразу.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| gh-ost: чтение журнала и перенос в теневую таблицу | Большие таблицы под постоянной записью | Нужен доступ к журналу репликации и место под теневую копию |
| Триггерная миграция | Серверы, где журнал репликации недоступен | Триггеры удваивают нагрузку на запись, конфликтуют с существующими |
| Перестройка в новую таблицу с переключением | Смена типа столбца, разбиение или слияние таблиц | Период догона изменений и короткая блокировка на переименование |
| Миграция через реплику | Переезд между серверами и версиями | Отставание репликации, проверка сходимости данных |
| Обслуживаемое окно | Малые таблицы и операции, несовместимые с онлайном | Простой на всё время копирования |
Где ломается триггерный подход
Таблицы без первичного ключа, частые обновления одного ряда и уже существующие триггеры: накладные расходы на запись удваиваются, а отставание копирования растёт быстрее, чем оно догоняется.
Где gh-ost требует проверки
Внешние ключи, широкие строки и серверы с отключённым журналом репликации. Перед запуском сверяют схему, темп записи и место под теневую таблицу — иначе процесс придётся останавливать и перезапускать.
Этапы онлайн-миграции: от замера нагрузки до переключения трафика
Порядок работ в онлайн-миграции не произвольный: gh-ost создаёт теневую таблицу, порциями копирует в неё строки и параллельно применяет изменения из журнала репликации, поэтому ошибка в схеме или в запросах всплывает уже под боевой нагрузкой. План миграции базы данных строится так, чтобы каждый риск снимался до переключения таблицы, а не после.
Подготовка и проверки
- Аудит схемы и запросов — фиксируем состав индексов, внешние ключи, триггеры и обращения к таблице в коде; ищем всё, что инструмент не переносит автоматически.
- Замер нагрузки — снимаем профиль чтения и записи, суточный пик, скорость роста таблицы; по этим данным считаем ожидаемое время копирования и допустимый порог отставания реплик.
- Тестовый прогон миграции — на восстановленной копии боевых данных прогоняем цикл целиком, включая откат и проверку планов запросов до и после.
Запуск, переключение и контроль
- Запуск копирования — gh-ost стартует с автоматическим торможением по отставанию реплик и по нагрузке на ведущий узел.
- Наблюдение за очередью — следим за скоростью переноса и задержкой реплик; при выходе за порог процесс приостанавливается, не затрагивая чтение.
- Переключение таблицы — смена имён выполняется одной атомарной операцией с краткой блокировкой записи, затем старое имя остаётся доступным для отката.
- Контроль после миграции — сверяем контрольные суммы строк, сравниваем отклик по ключевым запросам и держим прежнюю таблицу, пока метрики не выйдут на ровный фон.
Артефакты миграции: конфигурации, схемы репликации, регламенты
Миграция заканчивается не в момент переключения трафика, а когда в репозитории лежит комплект, по которому задачу повторит другой инженер, а дежурная смена откатит её без автора. Поэтому все артефакты храним рядом с конфигурацией запуска и обновляем в том же изменении, что и сам прогон — иначе документация по миграции расходится с реальностью в первый же инцидент.
- Параметры запуска: точка подключения, реплика-источник, пороги нагрузки и отставания, интервалы проверок, условия автоматической паузы — с пояснением, почему выбрано именно такое значение.
- Схема потоков данных: как процесс читает журнал изменений с реплики, пишет в теневую таблицу и выполняет финальное переключение; отдельно помечаем точки, где миграцию можно безопасно прервать.
- Схема репликации: топология «мастер — реплики», допустимое отставание, способ проверки перед стартом и роль каждой реплики в процессе.
- Служебные таблицы миграции: полный перечень создаваемых объектов, их назначение, срок жизни и ответственный за удаление; политика доступа — приложение и дежурный в них не пишут.
- Регламент отката: признаки, при которых прогон останавливается, порядок отмены, что делать с уже переключённым трафиком и сколько времени отводится на решение.
- Инструкция для дежурной смены: какие метрики смотреть, какие отклонения считать тревожными и в какой момент поднимать ответственного инженера.
- Журнал прогона: результаты теста на копии, фактические значения против плановых, зафиксированные расхождения и вывод о повторном запуске.
Каждый пункт проходит ревью до старта, а не после: регламент отката, который никто не читал, в момент сбоя бесполезен.
Кейс: плановая миграция крупной таблицы без остановки сервиса
Таблицу заказов на несколько сотен миллионов строк переводили на новую схему на живом сервисе: обращения идут круглосуточно, а обычный ALTER блокирует запись на всё время копирования. Перешли на gh-ost — инструмент читает журнал изменений и переносит строки порциями, поэтому рабочая таблица остаётся доступной и на запись, и на чтение.
| Метрика | До | После |
|---|---|---|
| Блокировка записи при переключении | десятки секунд, окно простоя ночью | доли секунды, пользователи не заметили |
| Доля неуспешных запросов | 0,4% в пиковые часы | 0 |
| Отставание реплик | до нескольких минут | в пределах штатного порога |
| Ручные операции | ночная смена по чек-листу | две команды под контролем дежурного |
Что пошло не по плану
За час до переключения реплика не успевала за потоком изменений. Вместо переключения по расписанию мы остановили шаг и дали реплике догнать источник — простой не понадобился. После этого кейса в процесс добавили порог: пока отставание выше заданного, переключение не запускается.
Откат проверили заранее: старая таблица остаётся на месте, возврат — одна операция, без восстановления из копии. На следующей миграции это сократило подготовку и позволило провести работу без окна обслуживания.
Что делать, если реплика отстаёт в момент переключения?
Отставание реплики — самый частый сценарий, в котором онлайн-миграция перестаёт быть безопасной. Пока gh-ost переносит строки в теневую таблицу, реплики получают тот же поток событий, но применяют его медленнее мастера.
Если переключить чтение на отставшую реплику, приложение увидит состояние до части изменений. Теряются не все строки, а отдельные — такие расхождения диагностируются хуже всего.
Признаки отставания видны заранее: растёт задержка применения журнала, копится очередь необработанных событий, а пик записи в момент переключения добавляет всплеск. Встроенный индикатор врёт на длинных транзакциях — надёжнее служебная таблица-пульс, которую gh-ost обновляет отдельным потоком.
Перед переключением ставим жёсткие условия: задержка ниже порога держится непрерывно всё окно наблюдения, очередь событий пуста, отставания нет ни на одной реплике под трафиком. Отдельно сверяем число строк и контрольные суммы по блокам между теневой и исходной таблицей — это подтверждает целостность данных, а не только факт завершения копирования.
Откат миграции закладываем заранее: gh-ost оставляет исходную таблицу, поэтому возврат — это остановка процесса и обратное переименование, трафик возвращается на прежнюю схему за секунды. Удалять артефакты до сверки нельзя, иначе откатываться будет некуда.
Если отставание продолжает расти, несмотря на ограничение нагрузки, переключение не делаем: ищем узкое место — диск, сеть, тяжёлые запросы на реплике — и возвращаемся к переносу после его устранения.
Технические сомнения: блокировки, откат и отставание реплики
Инженерные сомнения вокруг онлайн-миграции обычно сводятся к четырём вопросам: держит ли процесс блокировку на рабочей таблице, что произойдёт при обрыве соединения, какие права нужны на мастере и не разъедутся ли реплики при параллельном переносе. Ниже — короткие ответы по каждому пункту и требования к окружению, которые мы проверяем до старта.
Таблица встанет на блокировку при миграции?
Нет. gh-ost читает журнал изменений и переносит их в теневую копию, а рабочая таблица продолжает принимать запись и чтение. Блокировка возникает только на финальном переключении имён и держится доли секунды, поэтому очередь запросов не успевает вырасти.
Что будет, если процесс миграции прервётся?
Операция останавливается на текущем этапе: теневая таблица и вспомогательные объекты удаляются, исходные данные остаются нетронутыми. Запуск можно повторить — перед стартом состояние синхронизации проверяется заново, а неполная копия не попадает в работу.
Нужен ли прямой доступ к мастер-серверу?
Да: запись изменений и переключение идут через мастер, поэтому нужны права на создание таблиц, триггеров и переименование. Реплики при этом используются только для контроля отставания, отдельных учётных записей под них не требуется.
Можно ли мигрировать несколько таблиц одновременно?
Да, но параллельный запуск по многим таблицам создаёт конкуренцию за дисковые операции и ускоряет отставание реплики. Безопаснее вести перенос волнами по одной-двум таблицам, сверяя задержку репликации между этапами.
Обсудим вашу миграцию: схема, риски, план работ
Вводный разговор занимает около часа и идёт по существу: разбираем вашу схему, объём данных и требования к доступности, чтобы увидеть, где перенос может задеть живой трафик. По итогам вы получаете не общие обещания, а план работ по миграции с этапами, ответственными и точками остановки.
- Оценка объёма миграции: размер таблиц, число реплик, пиковая скорость записи и доля длинных транзакций — от этого зависит темп переноса.
- Режим работы gh-ost: перенос через реплику или с основной ноды, лимиты нагрузки, порог отставания, при котором процесс сам приостанавливается.
- Окно миграции: когда делаем финальное переключение, сколько держим исходную таблицу как страховку, как возвращаем трафик назад.
- Роли и связь: кто подтверждает старт, кого поднимаем при отклонении, где ведём журнал действий по шагам.
- Критерии успеха: сходятся контрольные суммы, отставание реплик в норме, время ответа приложения не выросло.
- Порядок действий при сбое: останавливаем перенос, возвращаем трафик на исходную таблицу, разбираем журнал и назначаем повторный запуск.
Заранее договариваемся, что считаем неудачей и по какому признаку откатываемся — тогда решение принимается по факту, а не в спешке. Чтобы обсудить миграцию предметно, опишите задачу: вернёмся с оценкой объёма, планом работ и составом команды.







