Gymterview
middle

Что делать, если changeset уже применён, но в нём обнаружена ошибка?

Правильный подход зависит от того, на каком окружении changeset уже применён. Главное правило: на production никогда не изменять уже применённые changeset-ы.

1. Создать новый changeset с исправлением (рекомендуемый подход)

Пример
<!-- Исходный changeset (уже применён, не трогаем!) -->
<changeSet id="20" author="dev">
    <createTable tableName="clients">
        <column name="id" type="BIGINT" autoIncrement="true">
            <constraints primaryKey="true"/>
        </column>
        <column name="name" type="VARCHAR(50)"/>  <!-- Ошибка: слишком маленький размер -->
    </createTable>
</changeSet>

<!-- Новый changeset с исправлением -->
<changeSet id="21" author="dev">
    <modifyDataType tableName="clients" columnName="name" newDataType="VARCHAR(255)"/>
</changeSet>

2. Откатить и применить заново (только dev/test)

Пример
liquibase rollbackCount 1

Затем исправить changeset и выполнить update. Этот подход допустим только на dev/test окружениях, где changeset ещё не был применён на production.

3. Использовать runOnChange=“true” (для процедур и представлений)

Пример
<changeSet id="create-view-active-clients" author="dev" runOnChange="true">
    <createView viewName="active_clients">
        SELECT * FROM clients WHERE status = 'ACTIVE'
    </createView>
</changeSet>

При изменении такого changeset Liquibase перевыполнит его вместо ошибки checksum.

4. Удалить запись из DATABASECHANGELOG (крайний случай)

Пример
DELETE FROM DATABASECHANGELOG
WHERE ID = '20' AND AUTHOR = 'dev' AND FILENAME = 'db/changelog/changes/020-create-clients.xml';

После этого можно исправить changeset и применить его заново. Этот подход опасен и допустим только на dev-окружении.

Общее правило

Никогда не изменять уже применённые changeset-ы на production. Всегда создавать новый changeset с исправлением.

На собеседовании: интервьюер проверяет, понимаете ли вы принцип иммутабельности changeset-ов. Правильный ответ — создать новый changeset. Частая ошибка — предлагать изменить старый changeset и сделать clearCheckSums, что на production приведёт к непредсказуемым последствиям.