У нас был точно такой же сценарий, но с postgresql, и я знаю, как 50M заполняет весь диапазон int, его пробелы в идентификаторах, пробелы, возникающие при удалении строк во времени или другие факторы, связанные с незавершенными транзакциями и т. Д.
Я объясню, что мы в итоге сделали, но сначала серьезно, тестирование миграции данных для 50M строк на 2k строк не является хорошим тестом.
Может быть несколько решений этой проблемы, в зависимости от таких факторов, как, например, какой провайдер БД вы используете? Мы использовали mazon RDS, и у него есть ограничения на время выполнения и то, что они называют IOPS (ввод / вывод) операции), если мы выполним такой интенсивный запрос к БД с такими ограничениями, у нее закончится квота IOPS на середине пути, а когда квота IOPS закончится, БД окажется слишком медленной и отчасти бесполезной. Нам пришлось отменить наш запрос и позволить IOPS наверстать упущенное, что занимает от 30 минут до 1 часа.
Если у вас нет таких ограничений и у вас есть БД в помещении или что-то в этом роде, то есть еще один фактор, который заключается в том, можете ли вы позволить себе простои? **
Если вы можете позволить себе простои и у вас нет ограничений по типу IOPS для вашей БД , вы можете выполнить этот запрос напрямую, что займет много времени (может быть полчаса или около того, в зависимости от большого количества факторы) и тем временем
- Таблица будет заблокирована, так как строки изменяются, поэтому убедитесь, что не только эта таблица не получает никаких записей, но и нет чтения во время процесса , чтобы убедиться, что ваш процесс завершается гладко, без каких-либо тупиковых ситуаций.
Что мы сделали, избегая простоев и ограничений IOPS Amazon RDS:
В моем случае у нас было еще около 40M идентификаторов в таблице, когда мы поняли, что это закончится, и мы хотели избежать простоев. Поэтому мы выбрали многошаговый подход:
- Создайте новый столбец big_int, назовите его new_id или что-то в этом роде (индексируйте его уникально с начала), это будет иметь значение null.
- Запись фоновых заданий, которые запускаются каждую ночь несколько раз и заполняют столбец
new_id
из столбца id
. Мы засыпали около 4-5 миллионов строк каждую ночь, и намного больше в выходные дни (поскольку в нашем приложении не было трафика по выходным).
- Когда вы попали в обратную засыпку, теперь нам придется прекратить любой доступ к этой таблице (мы просто отключили наше приложение на несколько минут ночью) и создать новую последовательность, начиная со значения max (new_id), или используйте существующую последовательность и привяжите ее к столбцу new_id со значением по умолчанию
nextval
этой последовательности.
- Теперь переключите первичный ключ с id на new_id, перед этим сделайте new_id не нулевым.
- Удалить столбец идентификатора.
- Переименуйте new_id в id.
- И возобновить работу вашей БД.
Это выше минимальная запись о том, что мы сделали, вы можете погуглить несколько хороших статей об этом, одна из них . Этот подход не нов и довольно распространен, поэтому я уверен, что вы найдете даже некоторые специфичные для mysql, или вы можете просто настроить пару вещей в этой статье выше, и вам будет хорошо.