Sobes.tech
Senior

Come faresti una migrazione complessa (aggiunta di una colonna obbligatoria in una tabella con 300 milioni di record) usando Liquibase?

sobes.tech AI

Risposta dell'AI

Добавление обязательной (NOT NULL) колонки в таблицу с 300 млн записей — задача, требующая аккуратного подхода, чтобы не заблокировать таблицу и не вызвать долгие простои.

Подход через Liquibase можно разбить на несколько шагов:

  1. Добавить новую колонку как NULLABLE

    • Это быстро, не блокирует таблицу.
    • В Liquibase: <addColumn> с атрибутом nullable="true".
  2. Заполнить колонку значениями по умолчанию или вычисленными

    • Сделать это пакетно, чтобы не перегружать базу.
    • Можно использовать скрипты или отдельные изменения в Liquibase с <update>.
  3. Проверить, что все записи заполнены

    • Убедиться, что нет NULL.
  4. Изменить колонку на NOT NULL

    • В Liquibase: <modifyDataType> или <addNotNullConstraint>.
    • Это может занять время, но теперь без NULL.
  5. Добавить индекс или ограничения, если нужно

Пример changelog Liquibase:

<changeSet id="1" author="me">
  <addColumn tableName="big_table">
    <column name="new_column" type="varchar(255)" nullable="true"/>
  </addColumn>
</changeSet>

<changeSet id="2" author="me">
  <update tableName="big_table">
    <column name="new_column" value="default_value"/>
  </update>
</changeSet>

<changeSet id="3" author="me">
  <addNotNullConstraint tableName="big_table" columnName="new_column" columnDataType="varchar(255)"/>
</changeSet>

Если база поддерживает, можно использовать онлайн-миграции (например, PostgreSQL с ALTER TABLE ... ALTER COLUMN SET NOT NULL после заполнения), либо использовать инструменты для онлайн-миграций (gh-ost, pt-online-schema-change для MySQL).

Важно:

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