Касательно mysql знаю три варианта:
1. Утилита
pt-online-schema-change. Создаёт пустую копию исходной таблицы, делает на ней alter, копирует данные из исходной таблицы и в конце меняет местами старую и новую таблицы.
Пользовался этой утилитой пару раз. Хорошо работает.
2. В mysql 5.6 появилась возможность делать alter без блокировок
средствами самой субд. Нужно в alter добавить парочку новых параметров:
ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;
Этот вариант я сам не пробовал, поэтому прокомментировать не могу.
3. Самый сложный вариант с использованием двух инстансов mysql, связанных master-master репликацией:
- Делаем alter на втором сервере
- Ждём, когда второй сервер догонится по репликации
- Переключаем сервис на вторую базу
- Ждем какое-то время, смотрим, нормально ли приложение работает с новой схемой, нет ли деградации или ошибок
- Делаем alter на первой базе
- Ждём догона репликации
- Возвращаем сервис на первую базу
С этим вариантом я работаю постоянно. Выглядит просто, но на деле много нюансов.
Нужно обязательно пропускать alter мимо репликации:
SET sql_log_bin = 0;
ALTER TABLE tbl_name ...;
Важно не забыть про sql_log_bin = 0, иначе alter по репликации переедет на соседний сервер и залочит таблицу уже там. А переключать сервис нельзя, пока репликация не догонится.
Если меняется структура таблицы - добавляется/удаляется колонка или меняется их порядок, нужно обязательно проследить чтобы тип репликации обязательно был STATEMENT. Иначе репликация приляжет на первом же запросе в формате ROW с примерно такой странной ошибкой:
Column 25 of table 'mydb.mytable' cannot be converted from type 'varchar(255)' to type 'bigint(20) unsigned'
А со STATEMENT нужно следить чтобы приложение нигде не понижало уровень изоляции ниже REPEATABLE READ, иначе получит ошибку:
Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.