Изменение типа столбца таблицы MySQL с INT на BIGINT - PullRequest
1 голос
/ 02 июля 2019

У меня есть таблица с чуть менее 50 миллионами строк.Он достиг предела для INT (2147483647).На данный момент таблица не записывается в.

Я планирую изменить столбец ID с INT на BIGINT.Я использую миграцию Rails, чтобы сделать это со следующей миграцией:

  def up
    execute('ALTER TABLE table_name MODIFY COLUMN id BIGINT(8) NOT NULL AUTO_INCREMENT')
  end

Я проверил это локально на наборе данных из 2000 строк, и он работал нормально.Выполнение команды ALTER TABLE на 50 миллионах должно быть в порядке, так как таблица в данный момент не используется?

Я хотел проверить перед запуском миграции.Любой вклад будет оценен, спасибо!

1 Ответ

0 голосов
/ 02 июля 2019

У нас был точно такой же сценарий, но с postgresql, и я знаю, как 50M заполняет весь диапазон int, его пробелы в идентификаторах, пробелы, возникающие при удалении строк во времени или другие факторы, связанные с незавершенными транзакциями и т. Д.

Я объясню, что мы в итоге сделали, но сначала серьезно, тестирование миграции данных для 50M строк на 2k строк не является хорошим тестом.

Может быть несколько решений этой проблемы, в зависимости от таких факторов, как, например, какой провайдер БД вы используете? Мы использовали mazon RDS, и у него есть ограничения на время выполнения и то, что они называют IOPS (ввод / вывод) операции), если мы выполним такой интенсивный запрос к БД с такими ограничениями, у нее закончится квота IOPS на середине пути, а когда квота IOPS закончится, БД окажется слишком медленной и отчасти бесполезной. Нам пришлось отменить наш запрос и позволить IOPS наверстать упущенное, что занимает от 30 минут до 1 часа.

Если у вас нет таких ограничений и у вас есть БД в помещении или что-то в этом роде, то есть еще один фактор, который заключается в том, можете ли вы позволить себе простои? **

Если вы можете позволить себе простои и у вас нет ограничений по типу IOPS для вашей БД , вы можете выполнить этот запрос напрямую, что займет много времени (может быть полчаса или около того, в зависимости от большого количества факторы) и тем временем

  • Таблица будет заблокирована, так как строки изменяются, поэтому убедитесь, что не только эта таблица не получает никаких записей, но и нет чтения во время процесса , чтобы убедиться, что ваш процесс завершается гладко, без каких-либо тупиковых ситуаций.

Что мы сделали, избегая простоев и ограничений IOPS Amazon RDS:

В моем случае у нас было еще около 40M идентификаторов в таблице, когда мы поняли, что это закончится, и мы хотели избежать простоев. Поэтому мы выбрали многошаговый подход:

  1. Создайте новый столбец big_int, назовите его new_id или что-то в этом роде (индексируйте его уникально с начала), это будет иметь значение null.
  2. Запись фоновых заданий, которые запускаются каждую ночь несколько раз и заполняют столбец new_id из столбца id. Мы засыпали около 4-5 миллионов строк каждую ночь, и намного больше в выходные дни (поскольку в нашем приложении не было трафика по выходным).
  3. Когда вы попали в обратную засыпку, теперь нам придется прекратить любой доступ к этой таблице (мы просто отключили наше приложение на несколько минут ночью) и создать новую последовательность, начиная со значения max (new_id), или используйте существующую последовательность и привяжите ее к столбцу new_id со значением по умолчанию nextval этой последовательности.
  4. Теперь переключите первичный ключ с id на new_id, перед этим сделайте new_id не нулевым.
  5. Удалить столбец идентификатора.
  6. Переименуйте new_id в id.
  7. И возобновить работу вашей БД.

Это выше минимальная запись о том, что мы сделали, вы можете погуглить несколько хороших статей об этом, одна из них . Этот подход не нов и довольно распространен, поэтому я уверен, что вы найдете даже некоторые специфичные для mysql, или вы можете просто настроить пару вещей в этой статье выше, и вам будет хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...