Перейти к основному содержимому
Версия: 2.0.x

Загрузка данных с помощью INSERT

В этой теме описывается, как загружать данные в Selena с помощью SQL оператора - INSERT.

Подобно MySQL и многим другим системам управления базами данных, Selena поддерживает загрузку данных во внутреннюю таблицу с помощью INSERT. Вы можете вставить одну или несколько строк напрямую с помощью предложения VALUES для тестирования функции или DEMO. Вы также можете вставить данные, определенные результатами запроса, во внутреннюю таблицу из внешней таблицы. Начиная с Selena v1.5.2, вы можете напрямую загружать данные из файлов в облачном хранилище, используя команду INSERT и табличную функцию FILES().

Selena v1.5.2 дополнительно поддерживает перезапись данных в таблицу с помощью INSERT OVERWRITE. Оператор INSERT OVERWRITE интегрирует следующие операции для реализации функции перезаписи:

  1. Создает временные partitions в соответствии с partitions, которые хранят исходные данные.
  2. Вставляет данные во временные partitions.
  3. Меняет местами исходные partitions с временными partitions.

ПРИМЕЧАНИЕ

Если вам необходимо проверить данные перед их перезаписью, вместо использования INSERT OVERWRITE вы можете следовать вышеуказанным процедурам, чтобы перезаписать ваши данные и проверить их перед заменой partitions.

Начиная с v1.5.2, Selena поддерживает новую семантику - Dynamic Overwrite для INSERT OVERWRITE с partitioned таблицами. Для получения дополнительной информации см. Dynamic Overwrite.

Предостережения

  • Вы можете отменить синхронную транзакцию INSERT только нажав клавиши Ctrl и C из вашего клиента MySQL.
  • Вы можете отправить асинхронную задачу INSERT, используя SUBMIT TASK.
  • Что касается текущей версии Selena, транзакция INSERT завершается ошибкой по умолчанию, если данные любых строк не соответствуют схеме таблицы. Например, транзакция INSERT завершается ошибкой, если длина поля в любой строке превышает ограничение длины для соответствующего поля в таблице. Вы можете установить переменную сеанса enable_insert_strict в false, чтобы разрешить транзакции продолжать работу, отфильтровывая строки, которые не соответствуют таблице.
  • Если вы часто выполняете оператор INSERT для загрузки небольших батчей данных в Selena, создается избыточное количество версий данных. Это серьезно влияет на производительность запросов. Рекомендуется в производственной среде не загружать данные с помощью команды INSERT слишком часто или использовать её как рутинную процедуру для ежедневной загрузки данных. Если ваше приложение или аналитический сценарий требует решений для загрузки потоковых данных или небольших батчей данных отдельно, рекомендуется использовать Apache Kafka® в качестве источника данных и загружать данные через Routine Load.
  • Если вы выполняете оператор INSERT OVERWRITE, Selena создает временные partitions для partitions, которые хранят исходные данные, вставляет новые данные во временные partitions и меняет местами исходные partitions с временными partitions. Все эти операции выполняются на узле FE Leader. Следовательно, если узел FE Leader выходит из строя во время выполнения команды INSERT OVERWRITE, вся транзакция загрузки завершится ошибкой, и временные partitions будут усечены.

Подготовка

Проверка привилегий

Вы можете загружать данные в таблицы Selena только как пользователь, имеющий привилегию INSERT на эти таблицы Selena. Если у вас нет привилегии INSERT, следуйте инструкциям в разделе GRANT, чтобы предоставить привилегию INSERT пользователю, которого вы используете для подключения к вашему cluster Selena. Синтаксис: GRANT INSERT ON TABLE <table_name> IN DATABASE <database_name> TO { ROLE <role_name> | USER <user_identity>}.

Создание объектов

Создайте базу данных с именем load_test, создайте таблицу insert_wiki_edit в качестве целевой таблицы и таблицу source_wiki_edit в качестве исходной таблицы.

ПРИМЕЧАНИЕ

Примеры, продемонстрированные в этой теме, основаны на таблице insert_wiki_edit и таблице source_wiki_edit. Если вы предпочитаете работать со своими собственными таблицами и данными, вы можете пропустить подготовку и перейти к следующему шагу.

CREATE DATABASE IF NOT EXISTS load_test;
USE load_test;
CREATE TABLE insert_wiki_edit
(
event_time DATETIME,
channel VARCHAR(32) DEFAULT '',
user VARCHAR(128) DEFAULT '',
is_anonymous TINYINT DEFAULT '0',
is_minor TINYINT DEFAULT '0',
is_new TINYINT DEFAULT '0',
is_robot TINYINT DEFAULT '0',
is_unpatrolled TINYINT DEFAULT '0',
delta INT DEFAULT '0',
added INT DEFAULT '0',
deleted INT DEFAULT '0'
)
DUPLICATE KEY(
event_time,
channel,
user,
is_anonymous,
is_minor,
is_new,
is_robot,
is_unpatrolled
)
PARTITION BY RANGE(event_time)(
PARTITION p06 VALUES LESS THAN ('2015-09-12 06:00:00'),
PARTITION p12 VALUES LESS THAN ('2015-09-12 12:00:00'),
PARTITION p18 VALUES LESS THAN ('2015-09-12 18:00:00'),
PARTITION p24 VALUES LESS THAN ('2015-09-13 00:00:00')
)
DISTRIBUTED BY HASH(user);

CREATE TABLE source_wiki_edit
(
event_time DATETIME,
channel VARCHAR(32) DEFAULT '',
user VARCHAR(128) DEFAULT '',
is_anonymous TINYINT DEFAULT '0',
is_minor TINYINT DEFAULT '0',
is_new TINYINT DEFAULT '0',
is_robot TINYINT DEFAULT '0',
is_unpatrolled TINYINT DEFAULT '0',
delta INT DEFAULT '0',
added INT DEFAULT '0',
deleted INT DEFAULT '0'
)
DUPLICATE KEY(
event_time,
channel,user,
is_anonymous,
is_minor,
is_new,
is_robot,
is_unpatrolled
)
PARTITION BY RANGE(event_time)(
PARTITION p06 VALUES LESS THAN ('2015-09-12 06:00:00'),
PARTITION p12 VALUES LESS THAN ('2015-09-12 12:00:00'),
PARTITION p18 VALUES LESS THAN ('2015-09-12 18:00:00'),
PARTITION p24 VALUES LESS THAN ('2015-09-13 00:00:00')
)
DISTRIBUTED BY HASH(user);

ВАЖНО

Начиная с v1.5.2, Selena может автоматически устанавливать количество buckets (BUCKETS) при создании таблицы или добавлении partition. Вам больше не нужно вручную устанавливать количество buckets. Подробную информацию см. в установка количества buckets.

Вставка данных через INSERT INTO VALUES

Вы можете добавить одну или несколько строк в определенную таблицу, используя команду INSERT INTO VALUES. Несколько строк разделяются запятой (,). Подробные инструкции и справочные параметры см. в SQL Reference - INSERT.

ВНИМАНИЕ

Вставка данных через INSERT INTO VALUES применяется только к ситуации, когда вам необходимо проверить DEMO с небольшим набором данных. Это не рекомендуется для массового тестирования или производственной среды. Для загрузки массы данных в Selena см. Варианты загрузки для других вариантов, которые подходят для ваших сценариев.

Следующий пример вставляет две строки в таблицу источника данных source_wiki_edit с меткой insert_load_wikipedia. Label - это уникальный идентификационный label для каждой транзакции загрузки данных в базе данных.

INSERT INTO source_wiki_edit
WITH LABEL insert_load_wikipedia
VALUES
("2015-09-12 00:00:00","#en.wikipedia","AustinFF",0,0,0,0,0,21,5,0),
("2015-09-12 00:00:00","#ca.wikipedia","helloSR",0,1,0,1,0,3,23,0);

Вставка данных через INSERT INTO SELECT

Вы можете загрузить результат запроса к исходной таблице данных в целевую таблицу с помощью команды INSERT INTO SELECT. Команда INSERT INTO SELECT выполняет операции ETL на данных из исходной таблицы данных и загружает данные во внутреннюю таблицу в Selena. Источником данных может быть одна или несколько внутренних или внешних таблиц или даже файлы данных в облачном хранилище. Целевая таблица ДОЛЖНА быть внутренней таблицей в Selena. Подробные инструкции и справочные параметры см. в SQL Reference - INSERT.

Вставка данных из внутренней или внешней таблицы во внутреннюю таблицу

ПРИМЕЧАНИЕ

Вставка данных из внешней таблицы идентична вставке данных из внутренней таблицы. Для простоты мы демонстрируем только вставку данных из внутренней таблицы в следующих примерах.

  • Следующий пример вставляет данные из исходной таблицы в целевую таблицу insert_wiki_edit.
INSERT INTO insert_wiki_edit
WITH LABEL insert_load_wikipedia_1
SELECT * FROM source_wiki_edit;
  • Следующий пример вставляет данные из исходной таблицы в partitions p06 и p12 целевой таблицы insert_wiki_edit. Если partition не указан, данные будут вставлены во все partitions. В противном случае данные будут вставлены только в указанные partition(s).
INSERT INTO insert_wiki_edit PARTITION(p06, p12)
WITH LABEL insert_load_wikipedia_2
SELECT * FROM source_wiki_edit;

Выполните запрос к целевой таблице, чтобы убедиться, что в ней есть данные.

MySQL > select * from insert_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.00 sec)

Если вы усечете partitions p06 и p12, данные не будут возвращены в запросе.

MySQL > TRUNCATE TABLE insert_wiki_edit PARTITION(p06, p12);
Query OK, 0 rows affected (0.01 sec)

MySQL > select * from insert_wiki_edit;
Empty set (0.00 sec)
  • Следующий пример вставляет столбцы event_time и channel из исходной таблицы в целевую таблицу insert_wiki_edit. Значения по умолчанию используются в столбцах, которые здесь не указаны.
INSERT INTO insert_wiki_edit
WITH LABEL insert_load_wikipedia_3
(
event_time,
channel
)
SELECT event_time, channel FROM source_wiki_edit;
примечание

Начиная с v1.5.2, указание списка столбцов в операторе INSERT INTO для таблицы Primary Key будет выполнять Partial Updates (вместо Full Upsert в более ранних версиях). Если список столбцов не указан, система будет выполнять Full Upsert.

Вставка данных непосредственно из файлов во внешнем источнике с использованием FILES()

Начиная с v1.5.2, Selena поддерживает прямую загрузку данных из файлов в облачном хранилище, используя команду INSERT и функцию FILES(), поэтому вам не нужно сначала создавать внешний catalog или файловую внешнюю таблицу. Кроме того, FILES() может автоматически определять схему таблицы файлов, значительно упрощая процесс загрузки данных.

Следующий пример вставляет строки данных из файла Parquet parquet/insert_wiki_edit_append.parquet в bucket AWS S3 inserttest в таблицу insert_wiki_edit:

INSERT INTO insert_wiki_edit
SELECT * FROM FILES(
"path" = "s3://inserttest/parquet/insert_wiki_edit_append.parquet",
"format" = "parquet",
"aws.s3.access_key" = "XXXXXXXXXX",
"aws.s3.secret_key" = "YYYYYYYYYY",
"aws.s3.region" = "us-west-2"
);

Перезапись данных через INSERT OVERWRITE VALUES

Вы можете перезаписать определенную таблицу одной или несколькими строками, используя команду INSERT OVERWRITE VALUES. Несколько строк разделяются запятой (,). Подробные инструкции и справочные параметры см. в SQL Reference - INSERT.

ВНИМАНИЕ

Перезапись данных через INSERT OVERWRITE VALUES применяется только к ситуации, когда вам необходимо проверить DEMO с небольшим набором данных. Это не рекомендуется для массового тестирования или производственной среды. Для загрузки массы данных в Selena см. Варианты загрузки для других вариантов, которые подходят для ваших сценариев.

Выполните запрос к исходной таблице и целевой таблице, чтобы убедиться, что в них есть данные.

MySQL > SELECT * FROM source_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.02 sec)

MySQL > SELECT * FROM insert_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.01 sec)

Следующий пример перезаписывает исходную таблицу source_wiki_edit двумя новыми строками.

INSERT OVERWRITE source_wiki_edit
WITH LABEL insert_load_wikipedia_ow
VALUES
("2015-09-12 00:00:00","#cn.wikipedia","GELongstreet",0,0,0,0,0,36,36,0),
("2015-09-12 00:00:00","#fr.wikipedia","PereBot",0,1,0,1,0,17,17,0);

Перезапись данных через INSERT OVERWRITE SELECT

Вы можете перезаписать таблицу результатом запроса к исходной таблице данных с помощью команды INSERT OVERWRITE SELECT. Оператор INSERT OVERWRITE SELECT выполняет операции ETL на данных из одной или нескольких внутренних или внешних таблиц и перезаписывает внутреннюю таблицу данными. Подробные инструкции и справочные параметры см. в SQL Reference - INSERT.

ПРИМЕЧАНИЕ

Загрузка данных из внешней таблицы идентична загрузке данных из внутренней таблицы. Для простоты мы демонстрируем только перезапись целевой таблицы данными из внутренней таблицы в следующих примерах.

Выполните запрос к исходной таблице и целевой таблице, чтобы убедиться, что они содержат разные строки данных.

MySQL > SELECT * FROM source_wiki_edit;
+---------------------+---------------+--------------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+--------------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #cn.wikipedia | GELongstreet | 0 | 0 | 0 | 0 | 0 | 36 | 36 | 0 |
| 2015-09-12 00:00:00 | #fr.wikipedia | PereBot | 0 | 1 | 0 | 1 | 0 | 17 | 17 | 0 |
+---------------------+---------------+--------------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.02 sec)

MySQL > SELECT * FROM insert_wiki_edit;
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #en.wikipedia | AustinFF | 0 | 0 | 0 | 0 | 0 | 21 | 5 | 0 |
| 2015-09-12 00:00:00 | #ca.wikipedia | helloSR | 0 | 1 | 0 | 1 | 0 | 3 | 23 | 0 |
+---------------------+---------------+----------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.01 sec)
  • Следующий пример перезаписывает таблицу insert_wiki_edit данными из исходной таблицы.
INSERT OVERWRITE insert_wiki_edit
WITH LABEL insert_load_wikipedia_ow_1
SELECT * FROM source_wiki_edit;
  • Следующий пример перезаписывает partitions p06 и p12 таблицы insert_wiki_edit данными из исходной таблицы.
INSERT OVERWRITE insert_wiki_edit PARTITION(p06, p12)
WITH LABEL insert_load_wikipedia_ow_2
SELECT * FROM source_wiki_edit;

Выполните запрос к целевой таблице, чтобы убедиться, что в ней есть данные.

MySQL > select * from insert_wiki_edit;
+---------------------+---------------+--------------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| event_time | channel | user | is_anonymous | is_minor | is_new | is_robot | is_unpatrolled | delta | added | deleted |
+---------------------+---------------+--------------+--------------+----------+--------+----------+----------------+-------+-------+---------+
| 2015-09-12 00:00:00 | #fr.wikipedia | PereBot | 0 | 1 | 0 | 1 | 0 | 17 | 17 | 0 |
| 2015-09-12 00:00:00 | #cn.wikipedia | GELongstreet | 0 | 0 | 0 | 0 | 0 | 36 | 36 | 0 |
+---------------------+---------------+--------------+--------------+----------+--------+----------+----------------+-------+-------+---------+
2 rows in set (0.01 sec)

Если вы усечете partitions p06 и p12, данные не будут возвращены в запросе.

MySQL > TRUNCATE TABLE insert_wiki_edit PARTITION(p06, p12);
Query OK, 0 rows affected (0.01 sec)

MySQL > select * from insert_wiki_edit;
Empty set (0.00 sec)
примечание

Для таблиц, использующих стратегию PARTITION BY column, INSERT OVERWRITE поддерживает создание новых partitions в целевой таблице путем указания значения ключа partition. Существующие partitions перезаписываются как обычно.

Следующий пример создает partitioned таблицу activity и создает новый partition в таблице при вставке данных в нее:

CREATE TABLE activity (
id INT NOT NULL,
dt VARCHAR(10) NOT NULL
) ENGINE=OLAP
DUPLICATE KEY(`id`)
PARTITION BY (`id`, `dt`)
DISTRIBUTED BY HASH(`id`);

INSERT OVERWRITE activity
PARTITION(id='4', dt='2022-01-01')
WITH LABEL insert_activity_auto_partition
VALUES ('4', '2022-01-01');
  • Следующий пример перезаписывает целевую таблицу insert_wiki_edit столбцами event_time и channel из исходной таблицы. Значение по умолчанию присваивается столбцам, в которые данные не перезаписываются.
INSERT OVERWRITE insert_wiki_edit
WITH LABEL insert_load_wikipedia_ow_3
(
event_time,
channel
)
SELECT event_time, channel FROM source_wiki_edit;

Dynamic Overwrite

Начиная с v1.5.2, Selena поддерживает новую семантику - Dynamic Overwrite для INSERT OVERWRITE с partitioned таблицами.

В настоящее время поведение по умолчанию INSERT OVERWRITE следующее:

  • При перезаписи partitioned таблицы в целом (то есть без указания предложения PARTITION), новые записи данных заменят данные в соответствующих им partitions. Если есть partitions, которые не задействованы, они будут усечены, в то время как другие будут перезаписаны.
  • При перезаписи пустой partitioned таблицы (то есть без partitions в ней) и указании предложения PARTITION система возвращает ошибку ERROR 1064 (HY000): Getting analyzing error. Detail message: Unknown partition 'xxx' in table 'yyy'.
  • При перезаписи partitioned таблицы и указании несуществующего partition в предложении PARTITION система возвращает ошибку ERROR 1064 (HY000): Getting analyzing error. Detail message: Unknown partition 'xxx' in table 'yyy'.
  • При перезаписи partitioned таблицы записями данных, которые не соответствуют ни одному из указанных partitions в предложении PARTITION, система либо возвращает ошибку ERROR 1064 (HY000): Insert has filtered data in strict mode (если включен строгий режим), либо фильтрует несоответствующие записи данных (если строгий режим отключен).

Поведение новой семантики Dynamic Overwrite сильно отличается:

При перезаписи partitioned таблицы в целом новые записи данных заменят данные в соответствующих им partitions. Если есть partitions, которые не задействованы, они будут оставлены без изменений, вместо того чтобы быть усеченными или удаленными. И если есть новые записи данных, соответствующие несуществующему partition, система создаст partition.

Семантика Dynamic Overwrite отключена по умолчанию. Чтобы включить её, необходимо установить системную переменную dynamic_overwrite в true.

Включить Dynamic Overwrite в текущем сеансе:

SET dynamic_overwrite = true;

Вы также можете установить её в подсказке оператора INSERT OVERWRITE, чтобы она вступила в силу только для этого оператора:

Пример:

INSERT /*+set_var(dynamic_overwrite = true)*/ OVERWRITE insert_wiki_edit
SELECT * FROM source_wiki_edit;

Вставка данных в таблицу с generated столбцами

Generated столбец - это специальный столбец, значение которого получается из предопределенного выражения или вычисления на основе других столбцов. Generated столбцы особенно полезны, когда ваш запрос включает вычисления дорогостоящих выражений, например, запрос определенного поля из значения JSON или вычисление данных ARRAY. Selena вычисляет выражение и сохраняет результаты в generated столбцах во время загрузки данных в таблицу, тем самым избегая вычисления выражения во время запросов и улучшая производительность запросов.

Вы можете загружать данные в таблицу с generated столбцами, используя INSERT.

Следующий пример создает таблицу insert_generated_columns и вставляет в нее строку. Таблица содержит два generated столбца: avg_array и get_string. avg_array вычисляет среднее значение данных ARRAY в data_array, а get_string извлекает строки из пути JSON a в data_json.

CREATE TABLE insert_generated_columns (
id INT(11) NOT NULL COMMENT "ID",
data_array ARRAY<INT(11)> NOT NULL COMMENT "ARRAY",
data_json JSON NOT NULL COMMENT "JSON",
avg_array DOUBLE NULL
AS array_avg(data_array) COMMENT "Get the average of ARRAY",
get_string VARCHAR(65533) NULL
AS get_json_string(json_string(data_json), '$.a') COMMENT "Extract JSON string"
) ENGINE=OLAP
PRIMARY KEY(id)
DISTRIBUTED BY HASH(id);

INSERT INTO insert_generated_columns
VALUES (1, [1,2], parse_json('{"a" : 1, "b" : 2}'));

ПРИМЕЧАНИЕ

Прямая загрузка данных в generated столбцы не поддерживается.

Вы можете запросить таблицу, чтобы проверить данные в ней.

mysql> SELECT * FROM insert_generated_columns;
+------+------------+------------------+-----------+------------+
| id | data_array | data_json | avg_array | get_string |
+------+------------+------------------+-----------+------------+
| 1 | [1,2] | {"a": 1, "b": 2} | 1.5 | 1 |
+------+------------+------------------+-----------+------------+
1 row in set (0.02 sec)

Вставка данных с PROPERTIES

Начиная с v1.5.2, операторы INSERT поддерживают настройку PROPERTIES, которые могут служить для различных целей. PROPERTIES переопределяют соответствующие им переменные.

Включение строгого режима

Начиная с v1.5.2, вы можете включить строгий режим и установить max_filter_ratio для INSERT из FILES(). Строгий режим для INSERT из FILES() имеет такое же поведение, как и для других методов загрузки.

Если вы хотите загрузить набор данных с некоторыми несоответствующими строками, вы можете либо отфильтровать эти несоответствующие строки, либо загрузить их и присвоить NULL значения несоответствующим столбцам. Вы можете достичь этого, используя свойства strict_mode и max_filter_ratio.

  • Для фильтрации несоответствующих строк: установите strict_mode в true, а max_filter_ratio в желаемое значение.
  • Для загрузки всех несоответствующих строк со значениями NULL: установите strict_mode в false.

Следующий пример вставляет строки данных из файла Parquet parquet/insert_wiki_edit_append.parquet в bucket AWS S3 inserttest в таблицу insert_wiki_edit, включает строгий режим для фильтрации несоответствующих записей данных и допускает не более 10% ошибочных данных:

INSERT INTO insert_wiki_edit
PROPERTIES(
"strict_mode" = "true",
"max_filter_ratio" = "0.1"
)
SELECT * FROM FILES(
"path" = "s3://inserttest/parquet/insert_wiki_edit_append.parquet",
"format" = "parquet",
"aws.s3.access_key" = "XXXXXXXXXX",
"aws.s3.secret_key" = "YYYYYYYYYY",
"aws.s3.region" = "us-west-2"
);
примечание

strict_mode и max_filter_ratio поддерживаются только для INSERT из FILES(). INSERT из таблиц не поддерживает эти свойства.

Установка длительности тайм-аута

Начиная с v1.5.2, вы можете установить длительность тайм-аута для операторов INSERT с помощью свойств.

Следующий пример вставляет данные из исходной таблицы source_wiki_edit в целевую таблицу insert_wiki_edit с длительностью тайм-аута, установленной на 2 секунды.

INSERT INTO insert_wiki_edit
PROPERTIES(
"timeout" = "2"
)
SELECT * FROM source_wiki_edit;
примечание

Начиная с v1.5.2, вы также можете установить длительность тайм-аута INSERT, используя системную переменную insert_timeout, которая применяется к операциям, включающим INSERT (например, UPDATE, DELETE, CTAS, обновление материализованных представлений, сбор статистики и PIPE). В версиях ранее v1.5.2 соответствующая переменная - query_timeout.

Сопоставление столбцов по имени

По умолчанию INSERT сопоставляет столбцы в исходной и целевой таблицах по их позициям, то есть сопоставлению столбцов в операторе.

Следующий пример явно сопоставляет каждый столбец в исходной и целевой таблицах по их позициям:

INSERT INTO insert_wiki_edit (
event_time,
channel,
user
)
SELECT event_time, channel, user FROM source_wiki_edit;

Сопоставление столбцов изменится, если вы измените порядок channel и user либо в списке столбцов, либо в операторе SELECT.

INSERT INTO insert_wiki_edit (
event_time,
channel,
user
)
SELECT event_time, user, channel FROM source_wiki_edit;

Здесь загруженные данные, вероятно, не то, что вы хотите, потому что channel в целевой таблице insert_wiki_edit будет заполнен данными из user в исходной таблице source_wiki_edit.

Добавив предложение BY NAME в оператор INSERT, система обнаружит имена столбцов в исходной и целевой таблицах и сопоставит столбцы с одинаковым именем.

примечание
  • Вы не можете указать список столбцов, если указано BY NAME.
  • Если BY NAME не указано, система сопоставляет столбцы по позиции столбцов в списке столбцов и операторе SELECT.

Следующий пример сопоставляет каждый столбец в исходной и целевой таблицах по их именам:

INSERT INTO insert_wiki_edit BY NAME
SELECT event_time, user, channel FROM source_wiki_edit;

В этом случае изменение порядка channel и user не изменит сопоставление столбцов.

Асинхронная загрузка данных с использованием INSERT

Загрузка данных с помощью INSERT отправляет синхронную транзакцию, которая может завершиться ошибкой из-за прерывания сеанса или тайм-аута. Вы можете отправить асинхронную транзакцию INSERT, используя SUBMIT TASK. Эта функция поддерживается с Selena v1.5.2.

  • Следующий пример асинхронно вставляет данные из исходной таблицы в целевую таблицу insert_wiki_edit.
SUBMIT TASK AS INSERT INTO insert_wiki_edit
SELECT * FROM source_wiki_edit;
  • Следующий пример асинхронно перезаписывает таблицу insert_wiki_edit данными из исходной таблицы.
SUBMIT TASK AS INSERT OVERWRITE insert_wiki_edit
SELECT * FROM source_wiki_edit;
  • Следующий пример асинхронно перезаписывает таблицу insert_wiki_edit данными из исходной таблицы и увеличивает тайм-аут запроса до 100000 секунд, используя подсказку.
SUBMIT /*+set_var(insert_timeout=100000)*/ TASK AS
INSERT OVERWRITE insert_wiki_edit
SELECT * FROM source_wiki_edit;
  • Следующий пример асинхронно перезаписывает таблицу insert_wiki_edit данными из исходной таблицы и указывает имя задачи как async.
SUBMIT TASK async
AS INSERT OVERWRITE insert_wiki_edit
SELECT * FROM source_wiki_edit;

Вы можете проверить статус асинхронной задачи INSERT, запросив представление метаданных task_runs в Information Schema.

Следующий пример проверяет статус задачи INSERT async.

SELECT * FROM information_schema.task_runs WHERE task_name = 'async';

Проверка статуса задания INSERT

Проверка через результат

Синхронная транзакция INSERT возвращает различный статус в соответствии с результатом транзакции.

  • Транзакция успешна

Selena возвращает следующее, если транзакция успешна:

Query OK, 2 rows affected (0.05 sec)
{'label':'insert_load_wikipedia', 'status':'VISIBLE', 'txnId':'1006'}
  • Транзакция завершена неудачно

Если все строки данных не удалось загрузить в целевую таблицу, транзакция INSERT завершается ошибкой. Selena возвращает следующее, если транзакция завершается ошибкой:

ERROR 1064 (HY000): Insert has filtered data in strict mode, tracking_url=http://x.x.x.x:yyyy/api/_load_error_log?file=error_log_9f0a4fd0b64e11ec_906bbede076e9d08

Вы можете определить проблему, проверив лог с помощью tracking_url.

Проверка через Information Schema

Вы можете использовать оператор SELECT для запроса результатов одного или нескольких заданий загрузки из таблицы loads в базе данных information_schema. Эта функция поддерживается с v1.5.2.

Пример 1: Запрос результатов заданий загрузки, выполненных в базе данных load_test, сортировка результатов по времени создания (CREATE_TIME) в порядке убывания и возврат только верхнего результата.

SELECT * FROM information_schema.loads
WHERE database_name = 'load_test'
ORDER BY create_time DESC
LIMIT 1\G

Пример 2: Запрос результата задания загрузки (с меткой insert_load_wikipedia), выполненного в базе данных load_test:

SELECT * FROM information_schema.loads
WHERE database_name = 'load_test' and label = 'insert_load_wikipedia'\G

Возвращается следующее:

*************************** 1. row ***************************
JOB_ID: 21319
LABEL: insert_load_wikipedia
DATABASE_NAME: load_test
STATE: FINISHED
PROGRESS: ETL:100%; LOAD:100%
TYPE: INSERT
PRIORITY: NORMAL
SCAN_ROWS: 0
FILTERED_ROWS: 0
UNSELECTED_ROWS: 0
SINK_ROWS: 2
ETL_INFO:
TASK_INFO: resource:N/A; timeout(s):300; max_filter_ratio:0.0
CREATE_TIME: 2023-08-09 10:42:23
ETL_START_TIME: 2023-08-09 10:42:23
ETL_FINISH_TIME: 2023-08-09 10:42:23
LOAD_START_TIME: 2023-08-09 10:42:23
LOAD_FINISH_TIME: 2023-08-09 10:42:24
JOB_DETAILS: {"All backends":{"5ebf11b5-365e-11ee-9e4a-7a563fb695da":[10006]},"FileNumber":0,"FileSize":0,"InternalTableLoadBytes":175,"InternalTableLoadRows":2,"ScanBytes":0,"ScanRows":0,"TaskNumber":1,"Unfinished backends":{"5ebf11b5-365e-11ee-9e4a-7a563fb695da":[]}}
ERROR_MSG: NULL
TRACKING_URL: NULL
TRACKING_SQL: NULL
REJECTED_RECORD_PATH: NULL
1 row in set (0.01 sec)

Для получения информации о полях в результатах см. Information Schema > loads.

Проверка через команду curl

Вы можете проверить статус транзакции INSERT, используя команду curl.

Запустите терминал и выполните следующую команду:

curl --location-trusted -u <username>:<password> \
http://<fe_address>:<fe_http_port>/api/<db_name>/_load_info?label=<label_name>

Следующий пример проверяет статус транзакции с меткой insert_load_wikipedia.

curl --location-trusted -u <username>:<password> \
http://x.x.x.x:8030/api/load_test/_load_info?label=insert_load_wikipedia

ПРИМЕЧАНИЕ

Если вы используете учетную запись, для которой не установлен пароль, вам необходимо ввести только <username>:.

Возвращается следующее:

{
"jobInfo":{
"dbName":"load_test",
"tblNames":[
"source_wiki_edit"
],
"label":"insert_load_wikipedia",
"state":"FINISHED",
"failMsg":"",
"trackingUrl":""
},
"status":"OK",
"msg":"Success"
}

Конфигурация

Вы можете установить следующие параметры конфигурации для транзакции INSERT:

  • Конфигурация FE
Конфигурация FEОписание
insert_load_default_timeout_secondТайм-аут по умолчанию для транзакции INSERT. Единица измерения: секунда. Если текущая транзакция INSERT не завершена в течение времени, установленного этим параметром, она будет отменена системой, и статус будет CANCELLED. Что касается текущей версии Selena, вы можете указать только единый тайм-аут для всех транзакций INSERT, используя этот параметр, и вы не можете установить другой тайм-аут для конкретной транзакции INSERT. По умолчанию 3600 секунд (1 час). Если транзакция INSERT не может быть завершена в указанное время, вы можете увеличить тайм-аут, настроив этот параметр.
  • Переменные сеанса
Переменная сеансаОписание
enable_insert_strictЗначение переключателя для управления тем, является ли транзакция INSERT толерантной к недопустимым строкам данных. Когда оно установлено в true, транзакция завершается ошибкой, если любая из строк данных является недопустимой. Когда оно установлено в false, транзакция успешна, когда по крайней мере одна строка данных была загружена правильно, и будет возвращена метка. По умолчанию true. Вы можете установить эту переменную с помощью команды SET enable_insert_strict = {true or false};.
insert_timeoutТайм-аут для оператора INSERT. Единица измерения: секунда. Вы можете установить эту переменную с помощью команды SET insert_timeout = xxx;.