Перейти к содержанию
Learning Platform
Глоссарий Troubleshooting
Урок 15.06 · 30 мин
Продвинутый
schema migrationsADD COLUMNDROP COLUMNMODIFY COLUMNmutationON CLUSTERReplicated database

Schema-миграции: стоимость DDL-операций

Изменения схемы в ClickHouse имеют разную стоимость в зависимости от типа операции. ADD COLUMN выполняется мгновенно, но MODIFY COLUMN с изменением несовместимого типа запустит background mutation, которая может переписывать данные часами. Понимание стоимости каждой DDL-операции — ключ к безопасным миграциям в production без неожиданных простоев.


Стоимость DDL-операций

В ClickHouse части (parts) не переписываются немедленно при большинстве DDL-команд. Вместо этого изменения применяются к метаданным, а физическая запись происходит при следующем merge или через background mutation.

ОперацияПоведениеСтоимость
ADD COLUMNMetadata-only, мгновенно. Старые части синтезируют default-значение при чтенииМинимальная
DROP COLUMNМгновенно. Части не переписываются до следующего mergeНизкая (merge всё равно произойдёт)
MODIFY COLUMN (совместимый тип)Мгновенно (например, Int32 -> Int64, String остаётся String)Нет
MODIFY COLUMN (несовместимый тип)Запускает background mutation — переписывает все частиВысокая — может занять часы

ADD COLUMN

-- Мгновенное добавление колонки -- metadata only
ALTER TABLE events ADD COLUMN session_id String DEFAULT '';

-- Старые части продолжают работать: session_id будет возвращать default-значение
-- без физической перезаписи данных
SELECT session_id FROM events LIMIT 5;
-- Вернёт: '' '' '' '' ''

Добавление колонки в ClickHouse не реписывает ни одной части. Существующие части при чтении синтезируют значение из DEFAULT или возвращают тип-по-умолчанию.

DROP COLUMN

-- Мгновенное удаление колонки -- части не переписываются немедленно
ALTER TABLE events DROP COLUMN old_metric;

-- Физическое удаление произойдёт при следующем merge старых частей
-- До тех пор diskspace не освобождается
WARNING

DROP COLUMN мгновенно запрещает доступ к колонке, но физически данные остаются на диске до следующего merge. Для принудительного освобождения места используйте OPTIMIZE TABLE events FINAL (но только в dev/staging — в production это дорогая операция).

MODIFY COLUMN

-- Мгновенно: совместимый тип (расширение диапазона)
ALTER TABLE events MODIFY COLUMN user_id Int64;  -- Int32 -> Int64, instant

-- Запускает mutation: несовместимый тип
ALTER TABLE events MODIFY COLUMN status_code Int32;  -- String -> Int32: mutation!
WARNING

MODIFY COLUMN с несовместимым типом (например, String -> Int32) запускает background mutation. Проверьте после ALTER:

SELECT count() FROM system.mutations WHERE is_done = 0 AND table = 'events';

Пока мutation не завершена (is_done = 0), данные переписываются в фоне. На больших таблицах это может занять часы.


ON CLUSTER DDL: порядок имеет значение

В шардированном или реплицированном кластере DDL-команды с ON CLUSTER требуют строгого порядка: сначала меняется схема на всех узлах, затем деплоится новый код приложения.

-- Правильный порядок: сначала DDL на кластере
ALTER TABLE events ON CLUSTER 'mycluster' ADD COLUMN new_col String DEFAULT '';

-- Убедитесь, что команда выполнена на ВСЕХ узлах:
SELECT hostname(), count() FROM clusterAllReplicas('mycluster', system.columns)
WHERE table = 'events' AND name = 'new_col'
GROUP BY hostname();

-- Только после этого -- деплой нового кода, читающего new_col
WARNING

Если задеплоить новый код ДО выполнения ALTER TABLE ON CLUSTER, часть узлов не будет знать о новой колонке. Это split-brain: одни реплики отвечают данными, другие возвращают ошибку “unknown column”. Всегда выполняйте DDL ON CLUSTER ПЕРЕД деплоем кода.

Проверка завершения DDL на всех узлах кластера:

-- Убедиться, что все реплики знают о новой колонке
SELECT hostname(), name, type
FROM clusterAllReplicas('mycluster', system.columns)
WHERE database = 'default' AND table = 'events' AND name = 'new_col'
ORDER BY hostname();

Replicated Database Engine: автоматическая репликация DDL

ReplicatedMergeTree таблицы используют ClickHouse Keeper для репликации данных. Но для репликации самих DDL-команд (CREATE TABLE, ALTER TABLE) требуется Replicated database engine.

-- Создание Replicated базы данных
CREATE DATABASE prod_db
ENGINE = Replicated('/clickhouse/databases/prod_db', '{shard}', '{replica}');

-- Теперь любой DDL внутри prod_db автоматически реплицируется:
-- не нужно добавлять ON CLUSTER к каждому ALTER TABLE
CREATE TABLE prod_db.events (
    event_time DateTime,
    user_id    UInt64,
    action     LowCardinality(String)
) ENGINE = ReplicatedMergeTree()
ORDER BY (user_id, event_time);
-- Таблица создаётся на всех узлах кластера автоматически

Replicated database engine — рекомендованный подход для кластеров, где DDL должен применяться ко всем узлам без ручного ON CLUSTER. Подробнее об архитектуре репликации — в Модуле 09 урок 08.

-- Проверка состояния Replicated базы данных
SELECT database, shard_name, replica_name, is_recovery
FROM system.clusters
WHERE cluster LIKE '%prod%';

Мониторинг миграций

-- Все активные mutations (is_done = 0 -- ещё не завершены)
SELECT
    database,
    table,
    mutation_id,
    command,
    is_done,
    parts_to_do,
    parts_to_do_names
FROM system.mutations
WHERE is_done = 0
ORDER BY create_time;

-- Активные background merges и mutations
SELECT
    database,
    table,
    result_part_name,
    reason,
    progress
FROM system.merges
WHERE reason IN ('TTL_DELETE', 'MUTATE_PART', 'MERGE_PARTS')
ORDER BY start_time DESC;

Ключевые выводы

  1. ADD COLUMN — metadata-only: Мгновенно, без перезаписи частей. Старые части синтезируют default-значение при чтении. Безопасно в production в любой момент.
  2. DROP COLUMN — мгновенно для доступа: Колонка недоступна сразу, но физическое удаление данных на диске происходит при следующем merge частей.
  3. MODIFY COLUMN с несовместимым типом запускает mutation: Проверяйте system.mutations WHERE is_done = 0 после любого MODIFY COLUMN — особенно при смене типа на несовместимый.
  4. ON CLUSTER DDL ordering: DDL выполняется на всех узлах кластера ПЕРЕД деплоем нового кода. Обратный порядок вызывает split-brain состояние.
  5. Replicated database engine автоматически реплицирует DDL без ON CLUSTER — рекомендован для production кластеров с частыми изменениями схемы.
PostgreSQL heap: ALTER TABLE, REWRITE и MVCC при изменении схемы dbt: SQL-based migrations, schema versioning и CI/CD

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 12