Изменение схемы (Schema Change)
Схему таблицы Doris можно изменить с помощью ALTER TABLE. Эта статья посвящена изменениям схемы, связанным со столбцами. Способы изменения различных индексов описаны в разделе Индексы таблиц.
Два типа операций Schema Change
Doris поддерживает два типа операций Schema Change: легковесные и тяжеловесные. Они существенно различаются по сложности выполнения, скорости и потреблению ресурсов. Чтобы быстро выбрать подходящий тип, воспользуйтесь таблицей ниже:
| Характеристика | Легковесные операции Schema Change | Тяжеловесные операции Schema Change |
|---|---|---|
| Скорость выполнения | Секунды (почти в реальном времени) | Минуты / часы / дни (зависит от объёма данных; чем больше объём, тем медленнее) |
| Требуется перезапись данных | Нет, изменяются только метаданные | Да, требуется перезапись файлов данных |
| Влияние на производительность системы | Незначительное влияние | Возможно снижение производительности системы, особенно во время преобразования данных |
| Потребление ресурсов | Низкое | Высокое, используются вычислительные ресурсы; во время операции объём хранилища, занимаемый данными таблицы, удваивается |
| Типичные операции | Добавление / удаление столбцов значений, переименование столбцов, изменение длины VARCHAR | Изменение типов данных столбцов, переход от NOT NULL к NULL, изменение первичных ключей, изменение порядка столбцов и т. д. |
Легковесные операции Schema Change
Изменяют только метаданные, не затрагивая физические файлы данных. Обычно такие операции завершаются за секунды и оказывают минимальное влияние на производительность системы. К ним относятся:
- Добавление или удаление столбцов значений.
- Переименование столбцов.
- Изменение длины столбцов VARCHAR (кроме ключевых столбцов таблиц UNIQUE и DUP).
Тяжеловесные операции Schema Change
Предполагают перезапись или преобразование файлов данных, при этом фактическое изменение или реорганизация выполняется компонентом Backend (BE) в фоновом режиме. Все операции, не относящиеся к легковесным, являются тяжеловесными, например:
- Изменение типа данных столбца.
- Переход столбца от NOT NULL к NULL.
- Изменение порядка сортировки столбцов.
Порядок выполнения:
- В фоновом режиме запускается задание преобразования данных, которое перезаписывает исходные данные в новые файлы отдельно для каждого tablet.
- Во время преобразования выполняется «двойная запись»: новые данные записываются и в новый, и в старый tablet.
- После завершения преобразования старый tablet удаляется, а его место занимает новый.
Примеры использования
В таблице ниже приведены распространённые сценарии и соответствующие конструкции. Используйте её для выбора нужной операции:
| Пользовательский сценарий | Синтаксис операции |
|---|---|
| Переименование столбца | RENAME COLUMN |
| Добавление ключевого столбца или столбца значений | ADD COLUMN |
| Добавление нескольких столбцов одновременно | ADD COLUMN (...) |
| Удаление столбца | DROP COLUMN |
| Изменение типа / позиции столбца | MODIFY COLUMN |
| Изменение порядка столбцов | ORDER BY |
Переименование столбца
ALTER TABLE [database.]table RENAME COLUMN old_column_name new_column_name;
Подробное описание синтаксиса см. в разделе ALTER TABLE RENAME.
Добавление столбца
Примечания:
- При добавлении столбца значений в модель с агрегацией необходимо указать
agg_type. - При добавлении ключевого столбца в модель без агрегации (например, DUPLICATE KEY) необходимо указать ключевое слово
KEY.
Пример 1: добавление столбца в таблицу без агрегации
-
Инструкция создания таблицы:
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int,
col5 int
) DUPLICATE KEY(col1, col2, col3)
DISTRIBUTED BY RANDOM BUCKETS 10; -
Добавьте ключевой столбец
key_colпослеcol1:ALTER TABLE example_db.my_table ADD COLUMN key_col INT KEY DEFAULT "0" AFTER col1; -
Добавьте столбец значений
value_colпослеcol4:ALTER TABLE example_db.my_table ADD COLUMN value_col INT DEFAULT "0" AFTER col4;
Пример 2: добавление столбца в таблицу с агрегацией
-
Инструкция создания таблицы:
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col1, col2, col3)
DISTRIBUTED BY HASH(col1) BUCKETS 10; -
Добавьте ключевой столбец
key_colпослеcol1:ALTER TABLE example_db.my_table ADD COLUMN key_col INT DEFAULT "0" AFTER col1; -
Добавьте столбец значений
value_colпослеcol4с типом агрегации SUM:ALTER TABLE example_db.my_table ADD COLUMN value_col INT SUM DEFAULT "0" AFTER col4;
Добавление нескольких столбцов
Примечания:
- При добавлении столбцов значений в модель с агрегацией необходимо указать
agg_type. - При добавлении ключевых столбцов в модель с агрегацией необходимо указать ключевое слово
KEY.
Добавление нескольких столбцов в таблицу с агрегацией:
-
Инструкция создания таблицы:
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col1, col2, col3)
DISTRIBUTED BY HASH(col1) BUCKETS 10; -
Добавьте несколько столбцов одновременно:
ALTER TABLE example_db.my_table
ADD COLUMN (c1 INT DEFAULT "1", c2 FLOAT SUM DEFAULT "0");
Удаление столбца
Примечания:
- Столбцы секционирования удалить нельзя.
- Ключевые столбцы таблицы UNIQUE удалить нельзя.
Удаление столбца из example_db.my_table:
-
Инструкция создания таблицы:
CREATE TABLE IF NOT EXISTS example_db.my_table(
col1 int,
col2 int,
col3 int,
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col1, col2, col3)
DISTRIBUTED BY HASH(col1) BUCKETS 10; -
Удалите столбец
col4изexample_db.my_table:ALTER TABLE example_db.my_table DROP COLUMN col4;
Изменение типа и позиции столбца
Примечания:
- При изменении столбца значений в модели с агрегацией необходимо указать
agg_type. - При изменении ключевого столбца в модели без агрегации необходимо указать ключевое слово
KEY. - При изменении типа столбца способ агрегации и значение по умолчанию должны оставаться такими же, как у исходного столбца.
- Переход столбца от NOT NULL к NULL поддерживается и выполняется как тяжеловесная операция Schema Change. Переход от NULL к NOT NULL не поддерживается.
- Столбцы секционирования и распределения по бакетам нельзя изменять никаким способом.
- При изменении столбцов учитывайте возможную потерю точности. Поддерживаемые преобразования типов перечислены ниже в разделе Поддерживаемые преобразования типов.
Пример:
-
Инструкция создания таблицы:
CREATE TABLE IF NOT EXISTS example_db.my_table(
col0 int,
col1 int DEFAULT "1",
col2 int,
col3 varchar(32),
col4 int SUM,
col5 varchar(32) REPLACE DEFAULT "abc"
) AGGREGATE KEY(col0, col1, col2, col3)
DISTRIBUTED BY HASH(col0) BUCKETS 10; -
Измените тип ключевого столбца
col1наBIGINTи переместите его послеcol2(как для ключевого столбца, так и для столбца значений необходимо указывать полное определение столбца):ALTER TABLE example_db.my_table
MODIFY COLUMN col1 BIGINT KEY DEFAULT "1" AFTER col2; -
Измените максимальную длину столбца
col5в базовой таблице. Исходное определениеcol5:VARCHAR(32) REPLACE DEFAULT "abc"(изменяется только длина VARCHAR; способ агрегации и значение по умолчанию должны оставаться прежними):ALTER TABLE example_db.my_table
MODIFY COLUMN col5 VARCHAR(64) REPLACE DEFAULT "abc"; -
Измените длину поля ключевого столбца:
ALTER TABLE example_db.my_table
MODIFY COLUMN col3 varchar(50) KEY NULL COMMENT 'to 50'; -
Измените столбец с NOT NULL на NULL (тяжеловесная операция Schema Change):
ALTER TABLE example_db.my_table
MODIFY COLUMN col2 INT NULL;
Поддерживаемые преобразования типов
При изменении типов столбцов учитывайте возможную потерю точности. В настоящее время поддерживаются следующие преобразования:
| Исходный тип | Целевой тип | Описание |
|---|---|---|
| TINYINT/SMALLINT/INT/BIGINT/LARGEINT/FLOAT/DOUBLE | Числовой тип с более широким диапазоном | - |
| TINYINT/SMALLINT/INT/BIGINT/LARGEINT/FLOAT/DOUBLE/DECIMAL | VARCHAR | - |
| VARCHAR | VARCHAR | Поддерживается только изменение максимальной длины |
| VARCHAR/CHAR | TINYINT/SMALLINT/INT/BIGINT/LARGEINT/FLOAT/DOUBLE | - |
| VARCHAR/CHAR | DATE | Поддерживаются шесть форматов: %Y-%m-%d, %y-%m-%d, %Y%m%d, %y%m%d, %Y/%m/%d, %y/%m/%d |
| DATETIME | DATE | Сохраняются только год, месяц и день, например, 2019-12-09 21:47:05 преобразуется в 2019-12-09 |
| DATE | DATETIME | Часы, минуты и секунды автоматически заполняются нулями, например, 2019-12-09 преобразуется в 2019-12-09 00:00:00 |
| FLOAT | DOUBLE | - |
| INT | DATE | Если данные INT некорректны, преобразование завершается ошибкой, а исходные данные остаются без изменений |
| Типы, отличные от DATE и DATETIME | STRING | STRING нельзя преобразовать ни в какой другой тип |
Изменение порядка столбцов
Примечания:
- Необходимо перечислить все столбцы таблицы.
- Столбцы значений должны располагаться после ключевых столбцов.
Пример:
-
Инструкция создания таблицы:
CREATE TABLE IF NOT EXISTS example_db.my_table(
k1 int DEFAULT "1",
k2 int,
k3 varchar(32),
k4 date,
v1 int SUM,
v2 int MAX,
) AGGREGATE KEY(k1, k2, k3, k4)
DISTRIBUTED BY HASH(k1) BUCKETS 10; -
Измените порядок столбцов в
example_db.my_table:ALTER TABLE example_db.my_table
ORDER BY (k3, k1, k2, k4, v2, v1);
Управление заданиями
Просмотр заданий
Для просмотра хода выполнения заданий Schema Change используйте команду SHOW ALTER TABLE COLUMN. Она показывает как выполняющиеся, так и завершённые задания. Если задание затрагивает материализованные представления, команда выводит несколько строк, по одной для каждого материализованного представления. Пример:
mysql > SHOW ALTER TABLE COLUMN\G;
*************************** 1. row ***************************
JobId: 20021
TableName: tbl1
CreateTime: 2019-08-05 23:03:13
FinishTime: 2019-08-05 23:03:42
IndexName: tbl1
IndexId: 20022
OriginIndexId: 20017
SchemaVersion: 2:792557838
TransactionId: 10023
State: FINISHED
Msg:
Progress: NULL
Timeout: 86400
1 row in set (0.00 sec)
Отмена заданий
Если состояние задания отличается от FINISHED и CANCELLED, задание Schema Change можно отменить следующей командой:
CANCEL ALTER TABLE COLUMN FROM tbl_name;
Ограничения
| Категория | Ограничение |
|---|---|
| Параллельное выполнение | Для одной таблицы одновременно может выполняться только одно задание Schema Change |
| Неизменяемые столбцы | Столбцы секционирования и распределения по бакетам изменять нельзя |
| Удаление ключевых столбцов | Если таблица с агрегацией содержит столбцы значений с агрегацией REPLACE, ключевые столбцы удалить нельзя; ключевые столбцы таблицы Unique также удалить нельзя |
| Значение по умолчанию при агрегации | При добавлении столбца значений с типом агрегации SUM или REPLACE значение по умолчанию не может достоверно отражать результат агрегации и не имеет смысла для исторических данных, поскольку детальная информация в них уже утрачена |
| Изменение типа | При изменении типа столбца способ агрегации и значение по умолчанию должны совпадать с исходным определением столбца |
| Изменение допустимости NULL | Переход от NOT NULL к NULL поддерживается (тяжеловесная операция Schema Change). Переход от NULL к NOT NULL не поддерживается |
| Неподдерживаемые изменения | Изменение типа агрегации или значения по умолчанию не поддерживается |
Связанные настройки
Настройки FE
| Параметр | Значение по умолчанию | Описание |
|---|---|---|
alter_table_timeout_second | 86400 (секунд) | Время ожидания завершения заданий по умолчанию |
Настройки BE
| Параметр | Значение по умолчанию | Описание |
|---|---|---|
alter_tablet_worker_count | 3 | Количество потоков на стороне BE для преобразования исторических данных. Это значение можно увеличить, чтобы ускорить задания Schema Change, однако слишком большое количество потоков может увеличить нагрузку на IO и повлиять на другие операции |
alter_index_worker_count | 3 | Количество потоков на стороне BE для построения индексов по историческим данным (в настоящее время поддерживаются только инвертированные индексы). Рекомендации по настройке те же, что и выше |
После изменения настроек BE необходимо перезапустить BE, чтобы изменения вступили в силу.