Iceberg Catalog
Doris поддерживает доступ к данным таблиц Iceberg через различные службы метаданных. Помимо чтения данных, Doris также поддерживает запись в таблицы Iceberg, включая INSERT, INSERT OVERWRITE, UPDATE, DELETE и MERGE INTO.
Быстрый старт с Apache Doris и Apache Iceberg.
Пользователи могут обращаться к таблицам Iceberg, использующим Hive Metastore для хранения метаданных, через Hive Catalog. Однако рекомендуется использовать непосредственно Iceberg Catalog, чтобы избежать некоторых проблем совместимости.
Сценарии использования
| Сценарий | Описание |
|---|---|
| Ускорение запросов | Используйте распределённый вычислительный движок Doris для прямого доступа к данным Iceberg и ускорения запросов. |
| Интеграция данных | Читайте данные Iceberg и записывайте их во внутренние таблицы Doris или выполняйте операции ZeroETL с помощью вычислительного движка Doris. |
| Обратная запись данных | Обрабатывайте данные из любого источника, поддерживаемого Doris, и записывайте их обратно в хранилище таблиц Iceberg. |
Настройка Catalog
Синтаксис
CREATE CATALOG [IF NOT EXISTS] catalog_name PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = '<iceberg_catalog_type>',
'warehouse' = '<warehouse>', --optional
{MetaStoreProperties},
{StorageProperties},
{IcebergProperties},
{CommonProperties}
);
-
<iceberg_catalog_type>Тип Iceberg Catalog. Поддерживаются следующие варианты:
-
hms: использует Hive Metastore в качестве службы метаданных. -
rest: служба метаданных, совместимая с интерфейсом Iceberg Rest Catalog. -
hadoop: обеспечивает прямой доступ к метаданным, хранящимся в файловой системе. -
glue: использует AWS Glue в качестве службы метаданных. -
dlf: использует Alibaba Cloud DLF в качестве службы метаданных. -
jdbc: использует Iceberg JDBC Catalog в качестве службы метаданных. -
s3tables: использует AWS S3 Tables Catalog для доступа к S3 Table Bucket.
-
-
<warehouse>Путь к хранилищу Iceberg. Этот параметр обязателен, если
<iceberg_catalog_type>имеет значениеhadoop.Путь
warehouseдолжен указывать на уровень выше путиDatabase. Например, если путь к таблице —s3://bucket/path/to/db1/table1, тоwarehouseдолжен иметь значениеs3://bucket/path/to/. -
{MetaStoreProperties}Раздел MetaStoreProperties предназначен для указания параметров подключения и аутентификации службы метаданных Metastore. См. раздел [Поддерживаемые службы метаданных].
-
{StorageProperties}Раздел StorageProperties предназначен для указания параметров подключения и аутентификации системы хранения. См. раздел [Поддерживаемые системы хранения].
-
{IcebergProperties}Раздел IcebergProperties предназначен для параметров, специфичных для Iceberg Catalog.
-
list-all-tablesПрименяется к Iceberg Catalog, использующему Hive Metastore в качестве службы метаданных. Значение по умолчанию —
true. По умолчанию операцияSHOW TABLESвыводит таблицы всех типов в текущей базе данных (Hive Metastore может хранить таблицы, не относящиеся к Iceberg). Этот подход обеспечивает наилучшую производительность.Если задано значение
false, Doris поочерёдно проверяет тип каждой таблицы и возвращает только таблицы Iceberg. При большом количестве таблиц этот режим работает медленно. -
iceberg.rest.view-enabledПоддерживается начиная с версии 4.0.6.
Действует только для Iceberg REST Catalog. Определяет, включены ли операции с представлениями (включая
listViews,loadView,viewExists,dropViewи т. д.). Значение по умолчанию —true.Некоторые реализации Iceberg REST Catalog предоставляют API таблиц, но API представлений в них недоступны или возвращают ошибки. При выполнении
SHOW TABLESDoris вызываетViewCatalog.listViews(), чтобы исключить представления из списка таблиц, поэтому такие службы REST могут приводить к сбоямSHOW TABLESи загрузки метаданных таблиц.В этом случае установите параметр в
false, и Doris будет пропускать все операции с представлениями, что позволит операциям с метаданными, таким какSHOW TABLES, работать корректно.
-
-
{CommonProperties}Раздел CommonProperties предназначен для общих свойств. Подробнее об общих свойствах см. в разделе Обзор Catalog.
Кэш метаданных
Для ускорения доступа к внешним источникам данных Apache Doris кэширует метаданные Iceberg. К ним относятся загруженные метаданные таблиц, данные разделов, манифесты, производные проекции разделов, идентификатор последнего снимка и определённый формат файлов.
В версиях до Doris 4.1.x кэширование метаданных в основном управляется глобально с помощью параметров конфигурации FE. Подробнее см. в разделе Кэш метаданных.
Начиная с Doris 4.1.x, кэш внешних метаданных Iceberg Catalog настраивается с помощью унифицированных ключей meta.cache.*. Приведённые ниже элементы относятся к текущей версии; Doris 4.1.x и 4.2.x используют другой набор элементов, описанный в версии 4.x этой страницы.
Настройка свойств кэша
Для каждого элемента кэша используется унифицированный формат ключей конфигурации: meta.cache.<engine>.<entry>.{enable,ttl-second,capacity,max-weight}. Для Iceberg значение <engine> — iceberg. Параметр meta.cache.iceberg.table.ttl-second задаёт общий TTL: это TTL по умолчанию для элементов table и partition, а также TTL кэшей без собственного токена <entry>. Значение 0 отключает их все, поэтому каждый запрос напрямую считывает последний снимок.
| Свойство | Пример | Значение |
|---|---|---|
enable | true/false | Включает или отключает этот элемент кэша. |
ttl-second | 600, 0, -1 | 0 отключает элемент (действует немедленно, можно использовать для просмотра последних данных); -1 означает отсутствие срока действия; другие положительные целые числа задают TTL в секундах с момента доступа. |
capacity | 10000 | Максимальное количество записей кэша. 0 отключает элемент. |
max-weight | 1GB | Поддерживается начиная с Doris 4.1.4. Необязательное ограничение оценочного объёма памяти, удерживаемой элементом. Должно быть положительным; 0 не допускается. Принимается только элементами, отмеченными ниже. |
Условия действия: элемент действует, если enable=true, ttl-second != 0 и capacity > 0. Ограничение памяти на уровне FE, Catalog или элемента дополнительно регулирует добавление записей на основе оценки памяти; см. Управление памятью кэша внешних метаданных.
Модули кэша
Следующие элементы имеют собственные ключи конфигурации и принимают max-weight:
Элемент (<entry>) | Префикс ключа свойства | ENTRY_NAME | Кэшируемое содержимое и влияние | Значения по умолчанию: включение / TTL / ёмкость |
|---|---|---|---|---|
table | meta.cache.iceberg.table. | iceberg-table | Загруженные метаданные таблиц Iceberg. Влияние: сокращает число обращений к Catalog и чтений файлов метаданных. | true / 86400 с / 1000 |
partition | meta.cache.iceberg.partition. | iceberg-partition | Необработанные данные разделов снимка таблицы. | true / как у table / 1000 |
manifest | meta.cache.iceberg.manifest. | iceberg-manifest | Разобранное содержимое манифестов. При планировании сканирования используется только при значении enable, равном true; значение по умолчанию — false. | true для самого кэша, false для его использования / без срока действия / 100000 |
partition_view | meta.cache.iceberg.partition_view. | iceberg.mvcc-partition-view, iceberg.list-partitions-view | Две производные проекции разделов с общим ограничением количества записей. | true / 86400 с / 1000 |
Следующие кэши не имеют токена <entry>. Они подчиняются ограничениям памяти Catalog и FE, а их TTL определяется параметром meta.cache.iceberg.table.ttl-second: iceberg-latest-snapshot (идентификатор последнего снимка), iceberg-format (определённый формат файлов), iceberg-comment (комментарии таблиц; создаётся только для REST Catalog с выдаваемыми учётными данными) и iceberg-equality-delete-field-ids.
Схема столбцов таблиц Iceberg кэшируется общим движком default (meta.cache.default.schema.*).
Если iceberg.rest.session имеет значение user, кэши table, partition, partition_view, latest-snapshot и format не создаются, поскольку общий кэш обходил бы индивидуальную авторизацию пользователей. REST Catalog с выдаваемыми учётными данными также не создаёт кэш table.
Сопоставление и преобразование устаревших параметров
| Устаревший ключ свойства | Унифицированный ключ | Описание |
|---|---|---|
schema.cache.ttl-second | meta.cache.default.schema.ttl-second | Срок действия кэша схемы таблицы |
Рекомендации
- Доступ к последним данным в реальном времени: если каждый запрос должен видеть последний снимок таблиц Iceberg, задайте для
meta.cache.iceberg.table.ttl-secondзначение0.-- Disable the table, partition, latest-snapshot, and format caches to read the latest snapshot live
ALTER CATALOG iceberg_ctl SET PROPERTIES ("meta.cache.iceberg.table.ttl-second" = "0"); - Оптимизация производительности:
- Включение кэша манифестов может существенно ускорить планирование запросов для больших таблиц. Если манифесты велики, ограничьте память кэша с помощью
max-weight:ALTER CATALOG iceberg_ctl SET PROPERTIES (
"meta.cache.iceberg.manifest.enable" = "true",
"meta.cache.iceberg.manifest.max-weight" = "1GB"
); - Успешное изменение свойства Catalog удаляет затронутые кэши метаданных и пересоздаёт их с новой конфигурацией при следующем обращении. Изменение
meta.cache.max-weightилиschema.cache.ttl-secondудаляет все кэши Catalog; изменениеmeta.cache.<engine>.<entry>.*удаляет кэши соответствующего движка. Уже выполняющиеся запросы не затрагиваются.
- Включение кэша манифестов может существенно ускорить планирование запросов для больших таблиц. Если манифесты велики, ограничьте память кэша с помощью
Наблюдаемость
Метрики кэша доступны в системной таблице information_schema.catalog_meta_cache_statistics. Столбец ENTRY_NAME содержит имена, перечисленные в таблице выше, а строка движка default соответствует общему кэшу схем таблиц:
SELECT engine_name, entry_name,
effective_enabled, ttl_second, capacity,
estimated_size, hit_rate, max_weight, estimated_weight
FROM information_schema.catalog_meta_cache_statistics
WHERE catalog_name = 'iceberg_ctl'
ORDER BY engine_name, entry_name;
См. документацию этой системной таблицы: catalog_meta_cache_statistics.
Поддерживаемые версии Iceberg
| Версия Doris | Версия Iceberg SDK |
|---|---|
| 2.1 | 1.6.1 |
| 3.0 | 1.6.1 |
| 3.1 | 1.9.1 |
| 4.0 | 1.9.1 |
| 4.1.4 / 4.1.4.1 | 1.10.1 |
| 4.1.5+ | 1.11.0 |
| dev (master) | 1.12.0 |
Ошибки метаданных и чтения (начиная с 4.1.5)
DESCRIBE,SHOW COLUMNSиSHOW CREATE TABLEсохраняют объявления обязательных и необязательных полей текущей схемы Iceberg. При сканировании по-прежнему обрабатываются поля, отсутствующие из-за эволюции схемы; отображаемое объявление NOT NULL не гарантирует, что поле существует в каждом историческом файле.- Версия dev передаёт метаданные разделов для записи на уровне строк в виде сериализованных данных разделов. Ошибка версии 4.1.5
Cannot produce Iceberg row IDs with unsupported partition types in spec ...относится к прежнему представлению Row ID и не применима к текущему представлению. - Отсутствие файла данных или файла удалений, на который ссылается зафиксированный снимок, приводит к сбою запроса, даже если задано
ignore_not_found_file_in_external_table=true. Восстановите отсутствующий объект или выберите допустимый снимок с полным набором файлов. schema.name-mapping.defaultдолжен содержать допустимый массив JSON Iceberg Name Mapping. Недопустимое значение приводит к сбою сканирования данных вместо перехода к текущим именам столбцов и возврата NULL. Исправьте или удалите это свойство с помощью системы записи, например Spark, затем обновите таблицу в Doris. Запросы к системным таблицам метаданных не выполняют эту проверку сканирования данных.
Поддерживаемые форматы Iceberg
- Поддерживаются форматы Iceberg V1/V2.
- Поддерживается чтение Position Delete и Equality Delete.
- Поддерживается чтение Deletion Vector (начиная с 4.1.0).
Поддерживаемые службы метаданных
- Hive Metastore
- AWS Glue
- Aliyun DLF
- Iceberg Rest Catalog
- Iceberg JDBC Catalog (поддерживается начиная с версии 4.1.0)
- FileSystem
Примечание: поддерживаемые типы служб и параметры немного различаются в разных версиях Doris. См. раздел [Примеры].
Матрица поддержки возможностей Iceberg Catalog
| Служба метаданных | Запросы к таблицам | Запросы к представлениям | Операции DDL | Обратная запись данных | Системные таблицы (поддерживаются начиная с 3.1+) |
|---|---|---|---|---|---|
| Hive MetaStore | ✅ | ✅ | ✅ | ✅ | ✅ |
| AWS Glue | ✅ | ✅ | ❌ | ❌ | ✅ |
| Aliyun DLF | ✅ | ✅ | ❌ | ❌ | ❌ |
| Iceberg Rest Catalog | ✅ | ✅ | Зависит от поставщика службы | Зависит от поставщика службы | Зависит от поставщика службы |
| FileSystem | ✅ | ✅ | ✅ | ✅ | ✅ |
Системная таблица labels поддерживается начиная с версии 5.0.0 и доступна только для Iceberg REST Catalog. См. раздел labels ниже.
Поддерживаемые системы хранения
- HDFS
- AWS S3
- Google Cloud Storage
- Azure Blob
- Apache Ozone (поддерживается начиная с 4.0.4)
- Aliyun OSS
- Tencent COS
- Huawei OBS
- MINIO
- SeaweedFS
Примечание: поддерживаемые типы служб и параметры немного различаются в разных версиях Doris. См. раздел [Примеры].
Поддерживаемые форматы данных
Начиная с версии 4.1.4, формат определяется для каждого файла данных (split), поэтому запросы к одной таблице Iceberg, содержащей одновременно файлы данных Parquet и ORC, выполняются корректно.
Начиная с версии 4.1.4, метаданные разделов Iceberg с преобразованием identity передаются с каждым split, а ключи разделов в пути охватывают столбцы identity всех спецификаций партиционирования таблицы. Благодаря этому значения столбцов разделов также корректно возвращаются для таблиц, прошедших эволюцию партиционирования.
Сопоставление типов столбцов
Полную таблицу сопоставления для Doris 4.2, правила точности и неподдерживаемые типы см. в разделе Сопоставление типов данных Iceberg и Doris.
Регистр имён столбцов
Doris сохраняет исходный регистр имён столбцов таблицы Iceberg и сопоставляет столбцы при чтении без учёта регистра. Запросы к столбцам, имена которых содержат прописные буквы или смешанный регистр (например, UserId или ORDER_ID), выполняются корректно.
В версиях ветки 4.0 до 4.0.8 столбцы при чтении определялись по точному совпадению имён, поэтому в таблицах Iceberg и Paimon с именами столбцов в смешанном регистре мог считываться неверный столбец или возникать ошибка запроса. Это исправлено в 4.0.8.
Сопоставление пространств имён
Иерархия метаданных Iceberg: Catalog -> Namespace -> Table. Пространство имён может иметь несколько уровней (Nested Namespace).
┌─────────┐
│ Catalog │
└────┬────┘
│
┌─────┴─────┐
┌──▼──┐ ┌──▼──┐
│ NS1 │ │ NS2 │
└──┬──┘ └──┬──┘
│ │
┌────▼───┐ ┌──▼──┐
│ Table1 │ │ NS3 │
└────────┘ └──┬──┘
│
┌──────┴───────┐
┌────▼───┐ ┌────▼───┐
│ Table2 │ │ Table3 │
└────────┘ └────────┘
Начиная с версии 3.1.2, Doris поддерживает сопоставление вложенных пространств имён для Iceberg Rest Catalog.
В приведённом выше примере таблицы сопоставляются с метаданными Doris следующим образом:
| Catalog | База данных | Таблица |
|---|---|---|
| Catalog | NS1 | Table1 |
| Catalog | NS2.NS3 | Table2 |
| Catalog | NS2.NS3 | Table3 |
Поддержку вложенных пространств имён необходимо включить явно. Подробнее см. в разделе Iceberg Rest Catalog
Примеры
Hive Metastore
Версия 3.1+
- HDFS
- S3
- OSS
- COS
- OBS
- GCS
- Azure Blob
- Ozone
- MinIO
Доступ к службам HMS и HDFS без аутентификации Kerberos
CREATE CATALOG iceberg_hms_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-hms-hdfs-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320',
'hadoop.username' = 'doris'
);
Доступ к службам HMS и HDFS с включённой аутентификацией Kerberos
CREATE CATALOG iceberg_hms_on_hdfs_kerberos_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-hms-hdfs-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.client.principal' = 'hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hive.metastore.client.keytab' = '/keytabs/hive-presto-master.keytab',
'hive.metastore.service.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hive.metastore.authentication.type' = 'kerberos',
'hadoop.security.auth_to_local' = 'RULE:[2:\$1@\$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal'='hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);
Доступ к HMS без аутентификации Kerberos
CREATE CATALOG iceberg_hms_on_s3_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 's3://selectdb-qa-datalake-test-hk/refactor-test/iceberg-hms-s3-warehouse',
's3.region' = 'ap-east-1',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
Получение учётных данных доступа к S3 с помощью IAM Assumed Role (3.1.2+)
CREATE CATALOG iceberg_hms_on_s3_iamrole PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 's3://bucket/warehouse',
's3.region' = 'us-east-1',
's3.role_arn' = 'arn:aws:iam::543815668950:role/role'
);
Доступ к HMS без аутентификации Kerberos
CREATE CATALOG iceberg_hms_on_oss_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'oss://bucket/iceberg/iceberg-hms-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9083',
'oss.region' = 'cn-beijing',
'oss.endpoint' = 'oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>'
);
Доступ к HMS с включённой аутентификацией Kerberos
CREATE CATALOG iceberg_hms_on_oss_kerberos_new_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'oss://bucket/iceberg/iceberg-hms-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.client.principal' = 'presto-server/presto-master.docker.cluster@LABS.TERADATA.COM',
'hive.metastore.client.keytab' = '/keytabs/presto-server.keytab',
'hive.metastore.authentication.type' = 'kerberos',
'hive.metastore.service.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hadoop.security.auth_to_local' = 'RULE:[2:\$1@\$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'oss.region' = 'cn-beijing',
'oss.endpoint' = 'oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>'
);
Доступ к HMS без аутентификации Kerberos
CREATE CATALOG `iceberg_hms_on_cos_catalog` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'cos://bucket/iceberg-hms-cos-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'cos.region' = 'ap-beijing',
'cos.endpoint' = 'cos.ap-beijing.myqcloud.com',
'cos.secret_key' = '<sk>',
'cos.access_key' = '<ak>'
);
Доступ к HMS с включённой аутентификацией Kerberos
CREATE CATALOG `iceberg_hms_on_cos_kerberos_new_catalog` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'cos://bucket/iceberg-hms-cos-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.service.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hive.metastore.client.principal' = 'hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hive.metastore.client.keytab' = '/keytabs/hive-presto-master.keytab',
'hadoop.security.auth_to_local' = 'RULE:[2:$1@$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:$1@$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:$1@$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'cos.region' = 'ap-beijing',
'cos.endpoint' = 'cos.ap-beijing.myqcloud.com',
'cos.secret_key' = '<sk>',
'cos.access_key' = '<ak>'
);
Доступ к HMS без аутентификации Kerberos
CREATE CATALOG test_iceberg_on_hms_obs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'obs://bucket/regression/iceberg',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'obs.region' = 'cn-north-4',
'obs.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
'obs.access_key' = '<ak>',
'obs.secret_key' = '<sk>'
);
Доступ к HMS с включённой аутентификацией Kerberos
CREATE CATALOG obs PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'obs://bucket/regression/iceberg1',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.service.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hive.metastore.client.principal' = 'hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hive.metastore.client.keytab' = '/keytabs/hive-presto-master.keytab',
'hive.metastore.authentication.type' = 'kerberos',
'hadoop.security.auth_to_local' = 'RULE:[2:\$1@\$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'obs.region' = 'cn-north-4',
'obs.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
'obs.access_key' = '<ak>',
'obs.secret_key' = '<sk>'
);
CREATE CATALOG `iceberg_hms_on_gcs_kerberos_new_catalog` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 'gs://bucket/iceberg_warehouse',
'gs.access_key' = '<ak>',
'gs.secret_key' = '<sk>',
'fs.gcs.support' = 'true'
);
Поддерживается начиная с 3.1.3
CREATE CATALOG iceberg_fs_on_azure_blob_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'abfs://<container>@<account_name>.dfs.core.windows.net/iceberg-warehouse',
'azure.account_name' = '<account_name>',
'azure.account_key' = '<account_key>',
'azure.endpoint' = 'https://<account_name>.blob.core.windows.net',
'fs.azure.support' = 'true'
);
Поддерживается начиная с 4.0.4
CREATE CATALOG iceberg_fs_on_ozone_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 's3a://bucket/iceberg_warehouse',
'fs.ozone.support' = 'true',
'ozone.endpoint' = 'http://ozone-s3g:9878',
'ozone.access_key' = '<ak>',
'ozone.secret_key' = '<sk>',
'ozone.region' = 'us-east-1',
'ozone.use_path_style' = 'true'
);
CREATE CATALOG test_iceberg_on_hms_minio_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 's3://warehouse/wh',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'fs.minio.support' = 'true',
'minio.use_path_style' = 'true',
'minio.endpoint' = 'http://127.0.0.1:19001',
'minio.access_key' = '<ak>',
'minio.secret_key' = '<sk>'
);
Версии 2.1 и 3.0
- HDFS
- S3
- OSS
- COS
- OBS
- MinIO
Доступ к службам HMS и HDFS без аутентификации Kerberos
CREATE CATALOG iceberg_hms_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-hms-hdfs-warehouse',
'hadoop.username' = 'doris',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320'
);
Доступ к службам HMS и HDFS с включённой аутентификацией Kerberos
CREATE CATALOG iceberg_hms_on_hdfs_kerberos_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-hms-hdfs-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.kerberos.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hive.metastore.authentication.type' = 'kerberos',
'hadoop.security.auth_to_local' = 'RULE:[2:\$1@\$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal'='hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);
CREATE CATALOG iceberg_hms_on_s3_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 's3://selectdb-qa-datalake-test-hk/refactor-test/iceberg-hms-s3-warehouse',
's3.region' = 'ap-east-1',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_hms_on_oss_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9083',
'warehouse' = 'oss://bucket/iceberg/iceberg-hms-warehouse',
'oss.region' = 'cn-beijing',
'oss.endpoint' = 'oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>'
);
CREATE CATALOG `iceberg_hms_on_cos_catalog` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'cos://bucket/iceberg-hms-cos-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'cos.region' = 'ap-beijing',
'cos.endpoint' = 'cos.ap-beijing.myqcloud.com',
'cos.secret_key' = '<sk>',
'cos.access_key' = '<ak>'
);
CREATE CATALOG test_iceberg_on_hms_obs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 'obs://bucket/regression/iceberg',
'obs.region' = 'cn-north-4',
'obs.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
'obs.access_key' = '<ak>',
'obs.secret_key' = '<sk>'
);
CREATE CATALOG test_iceberg_on_hms_minio_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 's3://warehouse/iceberg',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
's3.endpoint' = 'http://127.0.0.1:19001',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
AWS Glue
Версия 3.1+
- S3
AWS Glue и служба хранения S3 используют одни и те же учётные данные для аутентификации.
CREATE CATALOG `iceberg_glue_on_s3_catalog_` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'glue',
'warehouse' = 's3://bucket/iceberg-glue-s3-warehouse',
'glue.region' = 'ap-northeast-1',
'glue.endpoint' = 'https://glue.ap-northeast-1.amazonaws.com',
'glue.access_key' = '<ak>',
'glue.secret_key' = '<sk>'
);
Если учётные данные для аутентификации службы Glue отличаются от учётных данных S3, учётные данные S3 можно указать отдельно следующим образом.
CREATE CATALOG `iceberg_glue_on_s3_catalog_` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'glue',
'warehouse' = 's3://selectdb-qa-datalake-test/iceberg-glue-s3-warehouse',
'glue.region' = 'ap-northeast-1',
'glue.endpoint' = 'https://glue.ap-northeast-1.amazonaws.com',
'glue.access_key' = '<ak>',
'glue.secret_key' = '<sk>',
's3.endpoint' = 'https://s3.ap-northeast-1.amazonaws.com',
's3.region' = 'ap-northeast-1',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
CREATE CATALOG `glue_iceberg_iamrole` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'glue',
'warehouse' = 's3://bucket/warehouse',
'glue.region' = 'us-east-1',
'glue.endpoint' = 'https://glue.us-east-1.amazonaws.com',
'glue.role_arn' = '<role_arn>'
);
Версии 2.1 и 3.0
- S3
AWS Glue и служба хранения S3 используют одни и те же учётные данные для аутентификации.
В средах вне EC2 необходимо использовать aws configure, чтобы настроить учётные данные и создать файл credentials в каталоге ~/.aws.
CREATE CATALOG glue PROPERTIES (
'type'='iceberg',
'iceberg.catalog.type' = 'glue',
'glue.endpoint' = 'https://glue.us-east-1.amazonaws.com',
'glue.access_key' = '<ak>',
'glue.secret_key' = '<sk>'
);
Aliyun DLF
Версия 4.1+
- DLF 2.5+
CREATE CATALOG iceberg_dlf2_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://<region>-vpc.dlf.aliyuncs.com/iceberg',
'warehouse' = '<your-catalog-name>',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 'DlfNext',
'iceberg.rest.access-key-id' = '<ak>',
'iceberg.rest.secret-access-key' = '<sk>',
'iceberg.rest.signing-region' = '<region>',
'iceberg.rest.vended-credentials-enabled' = 'true',
'io-impl' = 'org.apache.iceberg.rest.DlfFileIO',
'fs.oss.support' = 'true'
);
Версия 3.1+
- DLF 1.0
CREATE CATALOG iceberg_dlf_catalog_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'dlf',
'warehouse' = 'oss://bucket/iceberg-dlf-oss-warehouse',
'dlf.uid' = '203225413946383283',
'dlf.catalog_id' = 'p2_regression_case',
'dlf.region' = 'cn-beijing',
'dlf.endpoint' = 'datalake.cn-beijing.aliyuncs.com',
'dlf.access_key' = '<ak>',
'dlf.secret_key' = '<sk>'
);
Версии 2.1 и 3.0
- DLF 1.0
CREATE CATALOG iceberg_dlf_catalog_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'dlf',
'warehouse' = 'oss://bucket/iceberg-dlf-oss-warehouse',
'dlf.uid' = '203225413946383283',
'dlf.catalog.id' = 'catalog_id',
'dlf.region' = 'cn-beijing',
'dlf.access_key' = '<ak>',
'dlf.secret_key' = '<sk>'
);
Iceberg Rest Catalog
Начиная с версии 4.1.4, если для iceberg.rest.signing-name задана управляемая служба подписи, например glue, s3tables или osstables, обязательно нужно также задать 'iceberg.rest.sigv4-enabled' = 'true'. В противном случае создание Catalog завершается ошибкой:
Rest Catalog requires sigv4-enabled set to true when signing-name is <name>
Если в существующем Catalog задан только signing-name, а sigv4-enabled не включён, после обновления проверка завершается ошибкой и это свойство необходимо добавить.
При использовании osstables обязательны и iceberg.rest.signing-region, и iceberg.rest.sigv4-enabled = 'true'. В противном случае возвращается следующая ошибка:
Rest Catalog requires signing-region and sigv4-enabled set to true when signing-name is osstables
Версия 3.1+
- S3
- OSS
- COS
- OBS
- GCS
- HDFS
- Без аутентификации
- Аутентификация OAuth2
- Выдаваемые учётные данные
CREATE CATALOG iceberg_static_s3 PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'ap-east-1'
);
CREATE CATALOG polaris_oauth2_credential_static_s3 PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'doris_test',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181/api/catalog',
'iceberg.rest.security.type' = 'oauth2',
'iceberg.rest.oauth2.credential' = 'root:secret123',
'iceberg.rest.oauth2.server-uri' = 'http://127.0.0.1:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:ALL',
's3.endpoint' = 'https://s3.us-west-2.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'us-west-2'
);
CREATE CATALOG gravitino_vended_s3 PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:9001/iceberg/',
'iceberg.rest.vended-credentials-enabled' = 'true'
);
- Без аутентификации
- Аутентификация OAuth2
CREATE CATALOG iceberg_static_oss PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
'oss.endpoint' = 'https://oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>',
'oss.region' = 'cn-beijing'
);
CREATE CATALOG polaris_oauth2_credential_static_oss PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'doris_test',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181/api/catalog',
'iceberg.rest.security.type' = 'oauth2',
'iceberg.rest.oauth2.credential' = 'root:secret123',
'iceberg.rest.oauth2.server-uri' = 'http://127.0.0.1:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:ALL',
'oss.endpoint' = 'https://oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>',
'oss.region' = 'cn-beijing'
);
- Без аутентификации
- Аутентификация OAuth2
CREATE CATALOG iceberg_static_cos PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
'cos.endpoint' = 'https://cos.ap-beijing.myqcloud.com',
'cos.access_key' = '<ak>',
'cos.secret_key' = '<sk>',
'cos.region' = 'ap-beijing'
);
CREATE CATALOG polaris_oauth2_credential_static_cos PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'doris_test',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181/api/catalog',
'iceberg.rest.security.type' = 'oauth2',
'iceberg.rest.oauth2.credential' = 'root:secret123',
'iceberg.rest.oauth2.server-uri' = 'http://127.0.0.1:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:ALL',
'cos.endpoint' = 'https://cos.ap-beijing.myqcloud.com',
'cos.access_key' = '<ak>',
'cos.secret_key' = '<sk>',
'cos.region' = 'ap-beijing'
);
- Без аутентификации
- Аутентификация OAuth2
CREATE CATALOG iceberg_static_obs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
'obs.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
'obs.access_key' = '<ak>',
'obs.secret_key' = '<sk>',
'obs.region' = 'cn-north-4'
);
CREATE CATALOG polaris_oauth2_credential_static_obs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'doris_test',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181/api/catalog',
'iceberg.rest.security.type' = 'oauth2',
'iceberg.rest.oauth2.credential' = 'root:secret123',
'iceberg.rest.oauth2.server-uri' = 'http://127.0.0.1:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:ALL',
'obs.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
'obs.access_key' = '<ak>',
'obs.secret_key' = '<sk>',
'obs.region' = 'cn-north-4'
);
- Без аутентификации
- Аутентификация OAuth2
CREATE CATALOG iceberg_static_gcs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'gs://warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
'gs.endpoint' = 'https://storage.googleapis.com',
'gs.access_key' = '<ak>',
'gs.secret_key' = '<sk>'
);
CREATE CATALOG polaris_oauth2_credential_static_gcs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'doris_test',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181/api/catalog',
'iceberg.rest.security.type' = 'oauth2',
'iceberg.rest.oauth2.credential' = 'root:secret123',
'iceberg.rest.oauth2.server-uri' = 'http://127.0.0.1:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:ALL',
'gs.endpoint' = 'https://storage.googleapis.com',
'gs.access_key' = '<ak>',
'gs.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_static_hdfs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'hdfs://127.0.0.1:8020/user/iceberg/warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
'fs.defaultFS' = 'hdfs://127.0.0.1:8020'
);
Версии 2.1 и 3.0
- S3
- OSS
- COS
- OBS
- HDFS
CREATE CATALOG iceberg_static_s3 PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'ap-east-1'
);
CREATE CATALOG iceberg_static_oss PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'https://oss-cn-beijing.aliyuncs.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'cn-beijing'
);
CREATE CATALOG iceberg_static_cos PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'https://cos.ap-beijing.myqcloud.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'ap-beijing'
);
CREATE CATALOG iceberg_static_obs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'cn-north-4'
);
CREATE CATALOG iceberg_static_hdfs PROPERTIES (
'type' = 'iceberg',
'warehouse' = 'hdfs://127.0.0.1:8020/user/iceberg/warehouse',
'iceberg.catalog.type' = 'rest',
'uri' = 'http://127.0.0.1:8181',
'fs.defaultFS' = 'hdfs://127.0.0.1:8020'
);
Iceberg JDBC Catalog
Это экспериментальная возможность, поддерживаемая начиная с версии 4.1.0.
Версия 4.1+
- PostgreSQL
- MySQL
- SQLite
Использование PostgreSQL для хранения метаданных совместно с S3
CREATE CATALOG iceberg_jdbc_postgresql PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'jdbc',
'iceberg.jdbc.catalog_name' = 'iceberg_jdbc_postgresql',
'iceberg.jdbc.uri' = 'jdbc:postgresql://127.0.0.1:5432/iceberg_db',
'iceberg.jdbc.user' = 'iceberg_user',
'iceberg.jdbc.password' = 'password',
'iceberg.jdbc.init-catalog-tables' = 'true',
'iceberg.jdbc.schema-version' = 'V1',
'iceberg.jdbc.driver_class' = 'org.postgresql.Driver',
'iceberg.jdbc.driver_url' = '<jdbc_driver_jar>',
'warehouse' = 's3://bucket/warehouse',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.endpoint' = 'https://s3.us-east-1.amazonaws.com',
's3.region' = 'us-east-1'
);
Использование MySQL для хранения метаданных совместно с S3
CREATE CATALOG iceberg_jdbc_mysql PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'jdbc',
'iceberg.jdbc.catalog_name' = 'iceberg_jdbc_mysql',
'iceberg.jdbc.uri' = 'jdbc:mysql://127.0.0.1:3306/iceberg_db',
'iceberg.jdbc.user' = 'iceberg_user',
'iceberg.jdbc.password' = 'password',
'iceberg.jdbc.init-catalog-tables' = 'true',
'iceberg.jdbc.schema-version' = 'V1',
'iceberg.jdbc.driver_class' = 'com.mysql.cj.jdbc.Driver',
'iceberg.jdbc.driver_url' = '<jdbc_driver_jar>',
'warehouse' = 's3://bucket/warehouse',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.endpoint' = 'https://s3.us-east-1.amazonaws.com',
's3.region' = 'us-east-1'
);
Использование SQLite для хранения метаданных (подходит для тестовых сред)
CREATE CATALOG iceberg_jdbc_sqlite PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'jdbc',
'iceberg.jdbc.catalog_name' = 'iceberg_jdbc_sqlite',
'iceberg.jdbc.uri' = 'jdbc:sqlite:/tmp/iceberg_catalog.db',
'iceberg.jdbc.init-catalog-tables' = 'true',
'iceberg.jdbc.schema-version' = 'V1',
'iceberg.jdbc.driver_class' = 'org.sqlite.JDBC',
'iceberg.jdbc.driver_url' = '<jdbc_driver_jar>',
'warehouse' = 's3://bucket/warehouse',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.endpoint' = 'https://s3.us-east-1.amazonaws.com',
's3.region' = 'us-east-1'
);
FileSystem
Версия 3.1+
- HDFS
- S3
- COS
- OSS
- OBS
- GCS
- MinIO
Доступ к службе HDFS без аутентификации Kerberos
CREATE CATALOG iceberg_fs_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-fs-hdfs-warehouse',
'hadoop.username' = 'doris',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320'
);
Доступ к службе HDFS с включённой аутентификацией Kerberos
CREATE CATALOG iceberg_fs_on_hdfs_kerberos_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-fs-hdfs-warehouse',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal' = 'hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);
CREATE CATALOG iceberg_fs_on_glue_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 's3://selectdb-qa-datalake-test-hk/refactor-test/iceberg-fs-s3-warehouse',
's3.region' = 'ap-east-1',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
Получение учётных данных доступа к S3 с помощью IAM Assumed Role (3.1.2+)
CREATE CATALOG iceberg_fs_on_s3_iamrole PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 's3://bucket/warehouse',
's3.region' = 'us-east-1',
's3.role_arn' = 'arn:aws:iam::543815668950:role/role'
);
CREATE CATALOG iceberg_fs_on_cos_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'cos://doris-build-1308700295/iceberg-fs-cos-warehouse',
'cos.region' = 'ap-beijing',
'cos.endpoint' = 'cos.ap-beijing.myqcloud.com',
'cos.access_key' = '<ak>',
'cos.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_fs_on_oss_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'oss://doris-regression-bj/refactor-test/iceberg-fs-oss-warehouse',
'oss.region' = 'cn-beijing',
'oss.endpoint' = 'oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>'
);
CREATE CATALOG test_fs_on_obs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'obs://bucket/regression/iceberg',
'obs.region' = 'cn-north-4',
'obs.endpoint' = 'obs.cn-north-4.myhuaweicloud.com',
'obs.access_key' = '<ak>',
'obs.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_fs_on_gcs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'gs://bucket/iceberg_warehouse',
'fs.gcs.support' = 'true',
'gs.access_key' = '<ak>',
'gs.secret_key' = '<sk>'
);
CREATE CATALOG test_iceberg_fs_on_minio PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 's3://warehouse/wh',
'fs.minio.support' = 'true',
'minio.endpoint' = 'http://127.0.0.1:19001',
'minio.access_key' = 'admin',
'minio.secret_key' = 'password',
'minio.use_path_style' = 'true'
);
Версии 2.1 и 3.0
- HDFS
- S3
- COS
- OSS
- GCS
- MinIO
Доступ к службе HDFS без аутентификации Kerberos
CREATE CATALOG iceberg_fs_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-fs-hdfs-warehouse',
'hadoop.username' = 'doris',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320'
);
Доступ к службе HDFS с включённой аутентификацией Kerberos
CREATE CATALOG iceberg_fs_on_hdfs_kerberos_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-fs-hdfs-warehouse',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal'='hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);
CREATE CATALOG iceberg_fs_on_s3_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 's3://selectdb-qa-datalake-test-hk/refactor-test/iceberg-fs-s3-warehouse',
's3.region' = 'ap-east-1',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_fs_on_cos_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'cos://doris-build-1308700295/iceberg-fs-cos-warehouse',
'cos.region' = 'ap-beijing',
'cos.endpoint' = 'cos.ap-beijing.myqcloud.com',
'cos.access_key' = '<ak>',
'cos.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_fs_on_oss_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'oss://bucket/refactor-test/iceberg-fs-oss-warehouse',
'oss.region' = 'cn-beijing',
'oss.endpoint' = 'oss-cn-beijing.aliyuncs.com',
'oss.access_key' = '<ak>',
'oss.secret_key' = '<sk>'
);
CREATE CATALOG iceberg_fs_on_gcs_catalog PROPERTIES (
'type'='iceberg',
'iceberg.catalog.type'='hadoop',
'warehouse' = 's3://bucket/iceberg_warehouse',
'gs.endpoint'='storage.googleapis.com',
'gs.access_key' = '<ak>',
'gs.secret_key' = '<sk>'
);
CREATE CATALOG test_iceberg_fs_on_minio PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type'='hadoop',
'warehouse' = 's3://warehouse/wh',
's3.region' = 'ap-east-1',
's3.endpoint' = 'http://minio:9000',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
AWS S3 Tables
Версия 3.1+
- S3 Tables Rest Catalog
- AWS Glue Rest Catalog
- FileSystem Catalog
См. документацию Интеграция с S3 Tables.
CREATE CATALOG aws_s3_tables PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'warehouse' = 'arn:aws:s3tables:us-east-1:<account_id>:bucket/<s3_table_bucket_name>',
'iceberg.rest.uri' = 'https://s3tables.us-east-1.amazonaws.com/iceberg',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 's3tables',
'iceberg.rest.signing-region' = 'us-east-1',
'iceberg.rest.access-key-id' = '<ak>',
'iceberg.rest.secret-access-key' = '<sk>'
);
См. документацию Интеграция с S3 Tables.
CREATE CATALOG glue_s3 PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'https://glue.ap-east-1.amazonaws.com/iceberg',
'warehouse' = '<acount_id>:s3tablescatalog/<s3_table_bucket_name>',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 'glue',
'iceberg.rest.access-key-id' = '<ak>',
'iceberg.rest.secret-access-key' = '<sk>',
'iceberg.rest.signing-region' = 'ap-east-1'
);
См. документацию Интеграция с S3 Tables.
CREATE CATALOG test_s3tables_write_insert PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 's3tables',
'warehouse' = 'arn:aws:s3tables:ap-east-1:12345:bucket/doris-s3-table-bucket',
's3.region' = 'ap-east-1',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
Версия 3.0.6+
- FileSystem Catalog
См. документацию Интеграция с S3 Tables.
CREATE CATALOG test_s3tables_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 's3tables',
'warehouse' = 'arn:aws:s3tables:ap-east-1:9527:bucket/doris-s3-table-bucket',
's3.region' = 'ap-east-1',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
Alibaba Cloud OSS Tables
Версия 4.1.4+
- OSS Tables REST Catalog
Полные инструкции по настройке и использованию см. в разделе Интеграция с Alibaba Cloud OSS Tables.
CREATE CATALOG oss_tables PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'https://<region>.oss-tables.aliyuncs.com/iceberg',
'warehouse' = 'acs:osstables:<region>:<account_id>:bucket/<table_bucket_name>',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 'osstables',
'iceberg.rest.signing-region' = '<region>',
'iceberg.rest.view-enabled' = 'false',
'io-impl' = 'org.apache.iceberg.aws.s3.S3FileIO',
'oss.endpoint' = 'https://oss-<region>.aliyuncs.com',
'oss.region' = '<region>',
'oss.access_key' = '<access_key_id>',
'oss.secret_key' = '<access_key_secret>',
'oss.use_path_style' = 'false',
'test_connection' = 'true'
);
Операции запросов
Базовый запрос
-- 1. switch to catalog, use database and query
SWITCH iceberg;
USE iceberg_db;
SELECT * FROM iceberg_tbl LIMIT 10;
-- 2. use iceberg database directly
USE iceberg.iceberg_db;
SELECT * FROM iceberg_tbl LIMIT 10;
-- 3. use full qualified name to query
SELECT * FROM iceberg.iceberg_db.iceberg_tbl LIMIT 10;
Столбцы метаданных файлов
Поддерживается начиная с версии 4.2.0.
Doris предоставляет два скрытых столбца метаданных для таблиц данных Iceberg. С их помощью можно определить физический файл данных и строку, из которых получен каждый результат запроса.
| Столбец | Тип | Описание |
|---|---|---|
_file | STRING NOT NULL | Исходный путь, записанный для файла данных Iceberg. |
_pos | BIGINT NOT NULL | Физическая позиция строки во всём файле данных, отсчитываемая с нуля. |
Предварительные условия: настройте Iceberg Catalog, как описано в предыдущих примерах, и создайте таблицу данных Iceberg, содержащую столбец id и использующую файлы Parquet или ORC. В следующем запросе предполагается, что iceberg_tbl уже содержит строки со значениями id, равными 1 и 2:
SELECT id, `_file`, `_pos`
FROM iceberg.iceberg_db.iceberg_tbl
ORDER BY `_file`, `_pos`;
Пример результата (путь к файлу зависит от расположения таблицы):
+----+---------------------------------------+------+
| id | _file | _pos |
+----+---------------------------------------+------+
| 1 | s3://bucket/warehouse/db/table/a.orc | 0 |
| 2 | s3://bucket/warehouse/db/table/a.orc | 1 |
+----+---------------------------------------+------+
По умолчанию эти столбцы не отображаются в SELECT * или DESC.
Чтобы включить скрытые столбцы в SELECT * и DESC, включите show_hidden_columns для сеанса:
SET show_hidden_columns = true;
Связанные переменные сеанса:
| Переменная | Тип | По умолчанию | Обязательна | Действие |
|---|---|---|---|---|
show_hidden_columns | BOOLEAN | false | Нет | Включает скрытые столбцы в SELECT * и DESC. Не требуется, если столбцы указаны явно. |
enable_file_scanner_v2 | BOOLEAN | true | Нет | Должна оставаться включённой, если запрос обращается к этим столбцам метаданных. |
force_jni_scanner | BOOLEAN | false | Нет | Должна оставаться отключённой, поскольку модуль чтения JNI не может формировать эти столбцы метаданных. |
Позиция строки определяется относительно всего физического файла. Фильтрация по предикатам, обработка удалений и разбиение сканирования не изменяют нумерацию оставшихся строк. Поэтому сочетание _file и _pos позволяет найти физическую запись в текущем снимке таблицы. Перезапись или компактация файлов данных может изменить оба значения, поэтому их нельзя использовать как стабильный логический идентификатор строки.
Эти столбцы доступны только при чтении таблицы данных Iceberg через нативный модуль чтения Parquet или ORC в FileScannerV2. Запрос, обращающийся к ним, завершается ошибкой, если enable_file_scanner_v2 отключена, force_jni_scanner включена или выбранные файлы данных нельзя прочитать нативным модулем Parquet/ORC.
_file и _pos — зарезервированные имена, сравниваемые без учёта регистра. Не используйте их как имена физических столбцов таблицы Iceberg.
Чтение исторических данных
Можно прочитать определённый снимок таблицы Iceberg.
По умолчанию запросы на чтение обращаются к последней версии снимка.
Получить сведения о снимках таблицы Iceberg можно с помощью системной таблицы $snapshots:
Начиная с версии 4.1.4, табличная функция iceberg_meta() удалена. Для запросов метаданных используйте системные таблицы Iceberg (например, iceberg_tbl$snapshots). См. раздел Системные таблицы ниже.
SELECT * FROM iceberg_ctl.iceberg_db.iceberg_tbl$snapshots\G
*************************** 1. row ***************************
committed_at: 2024-11-28 11:07:29
snapshot_id: 8903826400153112036
parent_id: -1
operation: append
manifest_list: oss://path/to/metadata/snap-8903826400153112036-1-3835e66d-9a18-4cb0-b9b0-9ec80527ad8d.avro
summary: {"added-data-files":"2","added-records":"3","added-files-size":"2742","changed-partition-count":"2","total-records":"3","total-files-size":"2742","total-data-files":"2","total-delete-files":"0","total-position-deletes":"0","total-equality-deletes":"0"}
*************************** 2. row ***************************
committed_at: 2024-11-28 11:10:11
snapshot_id: 6099853805930794326
parent_id: 8903826400153112036
operation: append
manifest_list: oss://path/to/metadata/snap-6099853805930794326-1-dd46a1bd-219b-4fb0-bb46-ac441d8b3105.avro
summary: {"added-data-files":"1","added-records":"1","added-files-size":"1367","changed-partition-count":"1","total-records":"4","total-files-size":"4109","total-data-files":"3","total-delete-files":"0","total-position-deletes":"0","total-equality-deletes":"0"}
Предложения FOR TIME AS OF и FOR VERSION AS OF позволяют читать исторические данные по идентификатору снимка или времени его создания. Примеры:
-- Read data as of a specific timestamp
SELECT * FROM iceberg_table FOR TIME AS OF '2023-01-01 00:00:00';
-- Read data as of a specific snapshot ID
SELECT * FROM iceberg_table FOR VERSION AS OF 123456789;
Начиная с 4.1.5, FOR TIME AS OF принимает от 1 до 9 цифр дробной части секунды после yyyy-MM-dd HH:mm:ss, интерпретирует значение в часовом поясе сеанса и преобразует его в миллисекунды для выбора снимка. Например, используйте FOR TIME AS OF '2024-01-01 12:00:00.123456'. Снимок выбирается с точностью до миллисекунды; поддержка этого синтаксиса не означает сохранения времени снимков с точностью до наносекунды.
Doris 4.1.5 также исправляет чтение исторических снимков после переименования и удаления столбцов, расширения типов и эволюции партиционирования. Каждый файл интерпретируется с использованием спецификации партиционирования, действовавшей при его записи, а не только текущей спецификации. Исторические запросы не должны переписываться для чтения текущих материализованных представлений.
Ветви и теги
Начиная с 3.1.0.
О создании, удалении и управлении ветвями и тегами см. раздел [Управление ветвями и тегами].
Поддерживается чтение определённых ветвей и тегов таблиц Iceberg.
Для совместимости с такими системами, как Spark/Trino, поддерживается несколько вариантов синтаксиса.
-- BRANCH
SELECT * FROM iceberg_tbl@branch(branch1);
SELECT * FROM iceberg_tbl@branch("name" = "branch1");
SELECT * FROM iceberg_tbl FOR VERSION AS OF 'branch1';
-- TAG
SELECT * FROM iceberg_tbl@tag(tag1);
SELECT * FROM iceberg_tbl@tag("name" = "tag1");
SELECT * FROM iceberg_tbl FOR VERSION AS OF 'tag1';
При использовании синтаксиса FOR VERSION AS OF Doris автоматически определяет, является ли параметр временной меткой или именем ветви/тега.
Представления
Начиная с 3.1.0
Поддерживаются запросы к представлениям Iceberg. Запросы к представлениям выполняются так же, как запросы к обычным таблицам. Учитывайте следующее:
- Поддерживается только Iceberg Catalog типа
hms. - SQL определения представления должен быть совместим с диалектом SQL Doris, иначе возникнут ошибки разбора. (Преобразование диалектов будет доступно в будущих версиях).
Скрытые столбцы Iceberg V3 (Row Lineage)
Это экспериментальная возможность, поддерживаемая начиная с версии 4.1.0.
Doris поддерживает запросы к скрытым столбцам Row Lineage таблиц Iceberg V3. Iceberg V3 вводит системные скрытые столбцы с данными о происхождении строк, которые используются для отслеживания изменений данных. Это особенно удобно для инкрементальной синхронизации и аудита данных:
_row_id: числовое значение, однозначно идентифицирующее строку данных (формируется на основе файла и позиции, в которые записаны данные)._last_updated_sequence_number: Sequence Number последнего изменения этой строки. Когда операцияUPDATEилиMERGE INTOобновляет данные, это числовое значение автоматически увеличивается вместе с номером версии.
Как запрашивать скрытые столбцы:
По умолчанию скрытые столбцы не видны при использовании DESC или SELECT *. Их можно запросить явно, указав имена столбцов напрямую:
SELECT id, _row_id, _last_updated_sequence_number FROM iceberg_tbl;
Скрытые столбцы также можно сделать видимыми в стандартном выводе (например, DESC и SELECT *), включив переменную сеанса show_hidden_columns:
SET show_hidden_columns = true;
DESC iceberg_tbl;
Примечания:
- Версия формата таблицы Iceberg (
format-version) должна иметь значение3, чтобы эти параметры уровня строк формировались. Запросы к столбцам происхождения строк в таблицах форматов V1 и V2 могут приводить к ошибкам. - Скрытые столбцы поддерживаются системой. Пользователям запрещено явно указывать столбцы
_row_idили_last_updated_sequence_numberлибо записывать в них данные с помощью операторов записи, таких какINSERT. Начиная с версии 4.1.4, указание столбца происхождения строк в списке столбцов оператораINSERTдля таблицы сformat-version >= 3сразу приводит к ошибке:Cannot specify invisible column '<name>' in INSERT statement.
Значения по умолчанию в Iceberg V3
Поддерживается начиная с версии 4.1.4.
Iceberg V3 определяет два вида значений столбцов по умолчанию, и Doris поддерживает оба:
initial-default: значение по умолчанию, назначаемое существующим историческим данным при добавлении столбца. При чтении старого файла данных, записанного до появления столбца, Doris возвращает это значение вместо NULL. Поддерживается для Parquet и ORC и распространяется на столбцы верхнего уровня, вложенные поля внутриSTRUCTи сложные родительские столбцы, отсутствующие целиком. Оно также применяется при вычислении предикатов.write-default: значение по умолчанию, подставляемое для столбцов, не указанных при записи. При использованииINSERT INTO t (subset of columns) VALUES (...)неуказанные столбцы записываются с текущим значениемwrite-default(в более ранних версиях записывался NULL).
Указание значения по умолчанию через DDL:
ALTER TABLE iceberg_tbl ADD COLUMN c1 INT DEFAULT 10;
Этот оператор задаёт и write-default, и initial-default в Iceberg. Он требует, чтобы format-version таблицы имел значение 3; таблицы V1 и V2 не поддерживают столбцы со значением по умолчанию, отличным от NULL.
Выражение DEFAULT():
Начиная с версии 4.1.4, выражение DEFAULT(<column>) позволяет явно обращаться к значению столбца по умолчанию в DML. Его можно использовать в INSERT, UPDATE ... SET и в каждой ветви MERGE INTO:
INSERT INTO iceberg_tbl VALUES (1, DEFAULT(c1));
UPDATE iceberg_tbl SET c1 = DEFAULT(c1) WHERE id = 1;
MERGE INTO iceberg_tbl t USING src s ON t.id = s.id
WHEN NOT MATCHED THEN INSERT VALUES (s.id, DEFAULT(c1));
Семантика:
- Для целевой таблицы Iceberg выражение
DEFAULT()разрешается по схеме Iceberg, зафиксированной для этой записи. Обращение к столбцу, не входящему в целевую таблицу записи, приводит к ошибкеDEFAULT requires a target column referenceилиCannot find column information for DEFAULT(<col>). - Для столбца, не относящегося к Iceberg, используется его значение по умолчанию. Если у столбца нет значения по умолчанию и он имеет атрибут NOT NULL или является автоинкрементным, возвращается ошибка
Column '<name>' has no default value and does not allow NULL or column is auto-increment. Если столбец допускает NULL и не имеет значения по умолчанию, используется NULL. - Другие ошибки:
DEFAULT requires a column reference, but got: <expr>иDEFAULT cannot be used on generated column '<name>'.
Свойство Iceberg write-default относится к стороне записи коннектора. Оно не отображается через DESCRIBE, SHOW CREATE TABLE или information_schema.columns.COLUMN_DEFAULT.
Системные таблицы
Начиная с 3.1.0
Doris поддерживает запросы к системным таблицам Iceberg для получения метаданных таблиц. Системные таблицы позволяют просматривать историю снимков, файлы манифестов, файлы данных, разделы и другие метаданные.
Для доступа к метаданным таблицы Iceberg добавьте к имени таблицы символ $, а затем имя системной таблицы:
SELECT * FROM iceberg_table$system_table_name;
Например, для просмотра истории таблицы выполните:
SELECT * FROM iceberg_table$history;
Системная таблица
all_manifestsподдерживается начиная с версии 4.0.4.Системная таблица
position_deletesподдерживается начиная с версии 4.1.4.Системная таблица
labelsподдерживается начиная с версии 5.0.0 и доступна только для Iceberg REST Catalog.
Начиная с версии 4.1.4, запросы к системным таблицам Iceberg выполняются по нативному пути выполнения, а табличная функция iceberg_meta() удалена. Вместо неё используйте синтаксис системных таблиц <table>$<system_table_name>. См. ICEBERG_META.
Синтаксис доступа к самим системным таблицам и возвращаемые ими результаты не изменились. Кроме того, системные таблицы теперь поддерживают SHOW CREATE TABLE.
entries
Показывает все записи манифестов для текущего снимка таблицы:
all_entries и entries похожи, но all_entries содержит записи из всех снимков, а entries — только из текущего снимка.
SELECT * FROM iceberg_table$entries;
Результат:
+--------+---------------------+-----------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| status | snapshot_id | sequence_number | file_sequence_number | data_file | readable_metrics |
+--------+---------------------+-----------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 2 | 4890031351138056789 | 1 | 1 | {"content":0, "file_path":"s3://.../iceberg_table/data/id=1/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00001.parquet", "file_format":"PARQUET", "spec_id":0, "partition":{"id":1}, "record_count":1, "file_size_in_bytes":625, "column_sizes":{1:36, 2:41}, "value_counts":{1:1, 2:1}, "null_value_counts":{1:0, 2:0}, "nan_value_counts":{}, "lower_bounds":{1:" ", 2:"Alice"}, "upper_bounds":{1:" ", 2:"Alice"}, "key_metadata":null, "split_offsets":[4], "equality_ids":null, "sort_order_id":0, "first_row_id":null, "referenced_data_file":null, "content_offset":null, "content_size_in_bytes":null} | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":1, "upper_bound":1}, "name":{"column_size":41, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Alice", "upper_bound":"Alice"}} |
| 0 | 1851184769713369003 | 1 | 1 | {"content":0, "file_path":"s3://.../iceberg_table/data/id=2/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00002.parquet", "file_format":"PARQUET", "spec_id":0, "partition":{"id":2}, "record_count":1, "file_size_in_bytes":611, "column_sizes":{1:36, 2:39}, "value_counts":{1:1, 2:1}, "null_value_counts":{1:0, 2:0}, "nan_value_counts":{}, "lower_bounds":{1:" ", 2:"Bob"}, "upper_bounds":{1:" ", 2:"Bob"}, "key_metadata":null, "split_offsets":[4], "equality_ids":null, "sort_order_id":0, "first_row_id":null, "referenced_data_file":null, "content_offset":null, "content_size_in_bytes":null} | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":2, "upper_bound":2}, "name":{"column_size":39, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Bob", "upper_bound":"Bob"}} |
+--------+---------------------+-----------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
files
Показывает список файлов текущего снимка таблицы:
SELECT * FROM iceberg_table$files;
Результат:
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-----------+--------------+--------------------+--------------+--------------+-------------------+------------------+-----------------------+-----------------------+--------------+---------------+--------------+---------------+--------------+----------------------+----------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| content | file_path | file_format | spec_id | partition | record_count | file_size_in_bytes | column_sizes | value_counts | null_value_counts | nan_value_counts | lower_bounds | upper_bounds | key_metadata | split_offsets | equality_ids | sort_order_id | first_row_id | referenced_data_file | content_offset | content_size_in_bytes | readable_metrics |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-----------+--------------+--------------------+--------------+--------------+-------------------+------------------+-----------------------+-----------------------+--------------+---------------+--------------+---------------+--------------+----------------------+----------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 0 | s3://.../iceberg_table/data/id=2/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00002.parquet | PARQUET | 0 | {"id":2} | 1 | 611 | {1:36, 2:39} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Bob"} | {1:" ", 2:"Bob"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":2, "upper_bound":2}, "name":{"column_size":39, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Bob", "upper_bound":"Bob"}} |
| 0 | s3://.../iceberg_table/data/id=4/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00004.parquet | PARQUET | 0 | {"id":4} | 1 | 618 | {1:36, 2:40} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Dave"} | {1:" ", 2:"Dave"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":4, "upper_bound":4}, "name":{"column_size":40, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Dave", "upper_bound":"Dave"}} |
| 0 | s3://.../iceberg_table/data/id=6/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00006.parquet | PARQUET | 0 | {"id":6} | 1 | 625 | {1:36, 2:41} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Frank"} | {1:" ", 2:"Frank"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":6, "upper_bound":6}, "name":{"column_size":41, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Frank", "upper_bound":"Frank"}} |
| 0 | s3://.../iceberg_table/data/id=8/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00008.parquet | PARQUET | 0 | {"id":8} | 1 | 625 | {1:36, 2:41} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Heidi"} | {1:" ", 2:"Heidi"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":8, "upper_bound":8}, "name":{"column_size":41, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Heidi", "upper_bound":"Heidi"}} |
| 0 | s3://.../iceberg_table/data/id=10/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00010.parquet | PARQUET | 0 | {"id":10} | 1 | 618 | {1:36, 2:40} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Judy"} | {1:" ", 2:"Judy"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":10, "upper_bound":10}, "name":{"column_size":40, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Judy", "upper_bound":"Judy"}} |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-----------+--------------+--------------------+--------------+--------------+-------------------+------------------+-----------------------+-----------------------+--------------+---------------+--------------+---------------+--------------+----------------------+----------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Аналогично системной таблице files, сведения об определённых типах файлов можно получить через следующие системные таблицы:
-- Query data files for the current snapshot
SELECT * FROM iceberg_table$data_files;
-- Query delete files for the current snapshot
SELECT * FROM iceberg_table$delete_files;
-- Query all files (including data and delete files) from all snapshots
SELECT * FROM iceberg_table$all_files;
-- Query data files from all snapshots
SELECT * FROM iceberg_table$all_data_files;
-- Query delete files from all snapshots
SELECT * FROM iceberg_table$all_delete_files;
Формат результатов этих таблиц похож на формат системной таблицы files, но каждая из них ориентирована на файлы данных или файлы удалений. Системные таблицы с префиксом all_ содержат файлы из всех снимков, а не только из текущего.
Примечание: если определённые типы файлов в таблице отсутствуют (например, при запросе delete_files, когда в таблице нет файлов удалений), результат запроса может быть пустым.
history
Показывает всю историю таблицы:
SELECT * FROM iceberg_table$history;
Результат:
+----------------------------+---------------------+---------------------+---------------------+
| made_current_at | snapshot_id | parent_id | is_current_ancestor |
+----------------------------+---------------------+---------------------+---------------------+
| 2025-06-12 22:29:16.357000 | 1851184769713369003 | NULL | 1 |
| 2025-06-12 22:29:39.922000 | 4890031351138056789 | 1851184769713369003 | 1 |
+----------------------------+---------------------+---------------------+---------------------+
labels
Эта возможность поддерживается начиная с версии 5.0.0
Показывает метки уровня таблицы (object) и уровня поля (field), которые REST Catalog предоставляет для таблицы Iceberg. Каждой паре ключ-значение метки соответствует отдельная строка. С помощью этой таблицы можно просматривать, например, сведения о владельце таблицы и категории данных в полях.
Эта системная таблица доступна, только если для iceberg.catalog.type задано значение rest. Дополнительная настройка Doris не требуется. Сервис REST Catalog возвращает метки при загрузке таблицы; создавать и изменять их нужно через поставщика сервиса. Эти метки описывают таблицы или поля и отличаются от тегов снимков, показанных в разделе refs.
Поля:
| Поле | Тип | Описание |
|---|---|---|
scope | TEXT | Область действия метки: object для метки уровня таблицы или field для метки уровня поля. |
field_id | INT | Идентификатор поля Iceberg. Для меток уровня таблицы — NULL. |
field_name | TEXT | Имя поля, определяемое по текущей схеме таблицы. Для вложенных полей используется полный путь, например address.city. Для меток уровня таблицы или если идентификатор поля отсутствует в текущей схеме — NULL. |
key | TEXT | Ключ метки. Поскольку key — зарезервированное слово в Doris, при явном обращении к этому столбцу в SQL заключайте его имя в обратные кавычки. |
value | TEXT | Значение метки. |
Примеры запросов:
В следующих примерах предполагается, что Catalog iceberg_ctl настроен, как описано в разделе Iceberg REST Catalog, таблица iceberg_db.iceberg_tbl существует, а у текущего пользователя есть разрешение на выполнение запросов к ней. Сервис REST Catalog настроен на возврат следующих меток:
- Метка уровня таблицы:
owner=team-a. - Метка поля
email(идентификатор поля2):classification=pii. - Метка вложенного поля
address.city(идентификатор поля5):classification=location.
Получить все метки, отсортированные по области действия, идентификатору поля и ключу метки:
SELECT * FROM iceberg_ctl.iceberg_db.iceberg_tbl$labels
ORDER BY scope, field_id, `key`;
Результат:
+--------+----------+--------------+----------------+----------+
| scope | field_id | field_name | key | value |
+--------+----------+--------------+----------------+----------+
| field | 2 | email | classification | pii |
| field | 5 | address.city | classification | location |
| object | NULL | NULL | owner | team-a |
+--------+----------+--------------+----------------+----------+
Найти поля с категорией pii:
SELECT field_name, `key`, value
FROM iceberg_ctl.iceberg_db.iceberg_tbl$labels
WHERE scope = 'field' AND `key` = 'classification' AND value = 'pii';
Результат:
+------------+----------------+-------+
| field_name | key | value |
+------------+----------------+-------+
| email | classification | pii |
+------------+----------------+-------+
Кэширование и обновление:
Метки кэшируются вместе с метаданными таблицы в соответствии с настройкой meta.cache.iceberg.table.ttl-second. После изменения меток в сервисе обновите основную таблицу перед запросом к $labels, чтобы получить актуальные метки:
REFRESH TABLE iceberg_ctl.iceberg_db.iceberg_tbl;
После обновления таблицы следующий запрос к $labels загрузит таблицу заново и получит метки, возвращённые сервисом. Чтобы отключить кэш метаданных таблицы и загружать метки заново при каждом запросе, установите для meta.cache.iceberg.table.ttl-second значение 0. Настройки кэша описаны в разделе Кэш метаданных.
Примечания:
- Если сервис REST Catalog не возвращает метки, результат запроса будет пустым. Таблица без снимков всё же может возвращать метки, если сервис их предоставляет.
COUNT(*)подсчитывает пары ключ-значение меток, а не строки данных основной таблицы. - Метки не версионируются вместе со снимками. Использование
FOR VERSION AS OFдля$labelsне позволяет получить исторические метки: запрос по-прежнему возвращает метки, полученные при текущей загрузке таблицы, а имена полей определяются по текущей схеме. - Метки полей связаны с идентификаторами полей. После переименования поля
field_nameпоказывает его новое имя. Если поле удалено, но сервис по-прежнему возвращает его метки,field_idсохраняется, аfield_nameпринимает значениеNULL. - Каталоги, не использующие REST, не поддерживают
$labels: запрос к этой системной таблице возвращает ошибкуUnknown sys table. REST Catalog, которым требуется планирование сканирования на стороне сервера, также не поддерживают эту системную таблицу.
manifests
Показывает сведения о файлах манифестов таблицы:
SELECT * FROM iceberg_table$manifests;
Результат:
+---------+------------------------------------------------------------------------------------------------------------------------------------------------+--------+-------------------+---------------------+------------------------+---------------------------+--------------------------+--------------------------+-----------------------------+----------------------------+--------------------------------------------------------------------------------+
| content | path | length | partition_spec_id | added_snapshot_id | added_data_files_count | existing_data_files_count | deleted_data_files_count | added_delete_files_count | existing_delete_files_count | deleted_delete_files_count | partition_summaries |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------+--------+-------------------+---------------------+------------------------+---------------------------+--------------------------+--------------------------+-----------------------------+----------------------------+--------------------------------------------------------------------------------+
| 0 | s3://.../iceberg_table/metadata/3194eb8b-5ea4-4cbe-95ba-073229458e7b-m0.avro | 7138 | 0 | 4890031351138056789 | 0 | 5 | 5 | 0 | 0 | 0 | [{"contains_null":0, "contains_nan":0, "lower_bound":"1", "upper_bound":"10"}] |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------+--------+-------------------+---------------------+------------------------+---------------------------+--------------------------+--------------------------+-----------------------------+----------------------------+--------------------------------------------------------------------------------+
all_manifests
Эта возможность поддерживается начиная с версии 4.0.4
Показывает сведения о файлах манифестов всех действительных снимков таблицы:
all_manifests и manifests имеют одинаковую структуру. Различие в том, что all_manifests включает файлы манифестов всех действительных снимков, а manifests — только текущего снимка.
SELECT * FROM iceberg_table$all_manifests;
Формат результата совпадает с форматом системной таблицы manifests.
metadata_log_entries
Показывает журналы метаданных таблицы:
SELECT * FROM iceberg_table$metadata_log_entries;
Результат:
+----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+------------------+------------------------+
| timestamp | file | latest_snapshot_id | latest_schema_id | latest_sequence_number |
+----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+------------------+------------------------+
| 2025-06-12 22:29:06.948000 | s3://.../iceberg_table/metadata/00000-e373aa16-15f1-4e69-ae7d-5ed64199cf9a.metadata.json | NULL | NULL | NULL |
| 2025-06-12 22:29:16.357000 | s3://.../iceberg_table/metadata/00001-bbc8e244-e41c-4958-92f4-63b8c3ee1196.metadata.json | 1851184769713369003 | 0 | 1 |
| 2025-06-12 22:29:39.922000 | s3://.../iceberg_table/metadata/00002-7dc00d6a-6269-4200-9d28-5f8c1c6b9f99.metadata.json | 4890031351138056789 | 0 | 2 |
+----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+------------------+------------------------+
partitions
Показывает разделы таблицы:
SELECT * FROM iceberg_table$partitions;
Результат:
+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+----------------------------+--------------------------+
| partition | spec_id | record_count | file_count | total_data_file_size_in_bytes | position_delete_record_count | position_delete_file_count | equality_delete_record_count | equality_delete_file_count | last_updated_at | last_updated_snapshot_id |
+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+----------------------------+--------------------------+
| {"id":8} | 0 | 1 | 1 | 625 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":6} | 0 | 1 | 1 | 625 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":10} | 0 | 1 | 1 | 618 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":4} | 0 | 1 | 1 | 618 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":2} | 0 | 1 | 1 | 611 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+----------------------------+--------------------------+
Примечания:
- Для непартиционированных таблиц таблица
partitionsне содержит полейpartitionиspec_id. - Таблица
partitionsпоказывает разделы, содержащие файлы данных или файлы удалений в текущем снимке. Однако файлы удалений не применяются, поэтому в некоторых случаях раздел может отображаться, даже если все строки данных в нём помечены как удалённые файлами удалений.
refs
Показывает все известные ссылки на снимки (ветви и теги) таблицы:
SELECT * FROM iceberg_table$refs;
Результат:
+------+--------+---------------------+-------------------------+-----------------------+------------------------+
| name | type | snapshot_id | max_reference_age_in_ms | min_snapshots_to_keep | max_snapshot_age_in_ms |
+------+--------+---------------------+-------------------------+-----------------------+------------------------+
| main | BRANCH | 4890031351138056789 | NULL | NULL | NULL |
+------+--------+---------------------+-------------------------+-----------------------+------------------------+
snapshots
Показывает все снимки таблицы:
SELECT * FROM iceberg_table$snapshots;
Результат:
+----------------------------+---------------------+---------------------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| committed_at | snapshot_id | parent_id | operation | manifest_list | summary |
+----------------------------+---------------------+---------------------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 2025-06-12 22:29:16.357000 | 1851184769713369003 | NULL | append | s3://.../iceberg_table/metadata/snap-1851184769713369003-1-82059f57-821a-4983-b083-002cc2cde313.avro | {"spark.app.id":"application_1738810850199_0472", "added-data-files":"10", "added-records":"10", "added-files-size":"6200", "changed-partition-count":"10", "total-records":"10", "total-files-size":"6200", "total-data-files":"10", "total-delete-files":"0", "total-position-deletes":"0", "total-equality-deletes":"0"} |
| 2025-06-12 22:29:39.922000 | 4890031351138056789 | 1851184769713369003 | overwrite | s3://.../iceberg_table/metadata/snap-4890031351138056789-1-3194eb8b-5ea4-4cbe-95ba-073229458e7b.avro | {"spark.app.id":"application_1738810850199_0472", "deleted-data-files":"5", "deleted-records":"5", "removed-files-size":"3103", "changed-partition-count":"5", "total-records":"5", "total-files-size":"3097", "total-data-files":"5", "total-delete-files":"0", "total-position-deletes":"0", "total-equality-deletes":"0"} |
+----------------------------+---------------------+---------------------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Операции записи
INSERT INTO
Операция INSERT добавляет данные в целевую таблицу.
Например:
INSERT INTO iceberg_tbl VALUES (val1, val2, val3, val4);
INSERT INTO iceberg.iceberg_db.iceberg_tbl SELECT col1, col2 FROM internal.db1.tbl1;
INSERT INTO iceberg_tbl(col1, col2) VALUES (val1, val2);
INSERT INTO iceberg_tbl(col1, col2, partition_col1, partition_col2) VALUES (1, 2, 'beijing', '2023-12-12');
Начиная с версии 3.1.0, поддерживается запись данных в указанные ветви:
INSERT INTO iceberg_tbl@branch(b1) values (val1, val2, val3, val4);
INSERT INTO iceberg_tbl@branch(b1) (col3, col4) values (val3, val4);
INSERT OVERWRITE
Операция INSERT OVERWRITE полностью заменяет существующие данные таблицы новыми.
INSERT OVERWRITE TABLE iceberg_tbl VALUES (val1, val2, val3, val4);
INSERT OVERWRITE TABLE iceberg.iceberg_db.iceberg_tbl(col1, col2) SELECT col1, col2 FROM internal.db1.tbl1;
Начиная с версии 3.1.0, поддерживается запись данных в указанные ветви:
INSERT OVERWRITE TABLE iceberg_tbl@branch(b1) values (val1, val2, val3, val4);
INSERT OVERWRITE TABLE iceberg_tbl@branch(b1) (col3, col4) values (val3, val4);
Начиная с версии 4.1.0, поддерживается запись данных в статические разделы (или в гибридном режиме):
-- Full Static Partition
INSERT OVERWRITE TABLE iceberg_tbl PARTITION (dt='2025-01-25', region='bj')
SELECT id, name FROM source_table;
-- Hybrid Partition Mode: "dt" is static, "region" comes from SELECT dynamically
INSERT OVERWRITE TABLE iceberg_tbl PARTITION (dt='2025-01-25')
SELECT id, name, region FROM source_table;
CTAS
Создать таблицу Iceberg и записать в неё данные можно с помощью оператора CTAS (Create Table As Select):
CREATE TABLE iceberg_ctas AS SELECT * FROM other_table;
CTAS поддерживает указание форматов файлов, партиционирования и других свойств:
CREATE TABLE iceberg_ctas
PARTITION BY LIST (pt1, pt2) ()
AS SELECT col1, pt1, pt2 FROM part_ctas_src WHERE col1 > 0;
CREATE TABLE iceberg.iceberg_db.iceberg_ctas (col1, col2, pt1)
PARTITION BY LIST (pt1) ()
PROPERTIES (
'write-format'='parquet',
'compression-codec'='zstd'
)
AS SELECT col1, pt1 AS col2, pt2 AS pt1 FROM test_ctas.part_ctas_src WHERE col1 > 0;
INSERT INTO BRANCH
Начиная с 3.1.0
INSERT INTO iceberg_table@branch(b1) SELECT * FROM other_table;
INSERT OVERWRITE TABLE iceberg_table@branch(b1) SELECT * FROM other_table;
DELETE
Это экспериментальная возможность, поддерживаемая начиная с версии 4.1.0.
Операция DELETE удаляет из таблицы Iceberg строки данных, соответствующие заданным условиям. В её основе лежат следующие механизмы: для таблиц формата V2 система записывает файлы Position Delete; для таблиц формата V3 система записывает файлы Deletion Vectors в формате Puffin.
Предварительные условия:
- Версия формата таблицы Iceberg (
format-version) должна быть 2 или выше. Таблицы формата V1 не поддерживают операциюDELETE.
Синтаксис:
DELETE FROM iceberg_tbl WHERE <condition>;
Примеры:
-- Delete a single row
DELETE FROM iceberg_tbl WHERE id = 1;
-- Delete using multiple conditions
DELETE FROM iceberg_tbl WHERE age > 30 AND name = 'Bob';
-- Delete using a subquery
DELETE FROM iceberg_tbl WHERE id IN (SELECT id FROM other_table WHERE status = 'inactive');
Для партиционированных таблиц используется тот же синтаксис:
DELETE FROM iceberg_partition_tbl WHERE id = 10;
UPDATE
Это экспериментальная возможность, поддерживаемая начиная с версии 4.1.0.
Операция UPDATE изменяет строки данных таблицы Iceberg, соответствующие заданным условиям. Сначала система записывает сведения для отслеживания удалений (с помощью файлов Position Delete для V2 и Deletion Vectors в формате Puffin для V3), чтобы пометить старые строки данных как недействительные, а затем добавляет новые файлы с обновлёнными данными (если включён формат V3, значение отслеживания _last_updated_sequence_number вновь вставленной строки автоматически увеличивается).
Предварительные условия:
- Версия формата таблицы Iceberg (
format-version) должна быть 2 или выше. Таблицы формата V1 не поддерживают операциюUPDATE.
Синтаксис:
UPDATE iceberg_tbl SET <column1> = <value1> [, <column2> = <value2>, ...] WHERE <condition>;
Примеры:
-- Update a single column
UPDATE iceberg_tbl SET name = 'Alice_new' WHERE id = 1;
-- Update multiple columns
UPDATE iceberg_tbl SET name = 'Updated', age = 28 WHERE id = 2;
-- Update using expressions
UPDATE iceberg_tbl SET age = age * 2 + 1, name = concat(name, '-modified') WHERE id = 3;
-- Update using a subquery as condition
UPDATE iceberg_tbl SET name = 'UpdatedViaSubquery' WHERE id IN (SELECT id FROM other_table);
Для партиционированных таблиц используется тот же синтаксис:
UPDATE iceberg_partition_tbl SET name = 'Updated' WHERE id = 10;
MERGE INTO
Это экспериментальная возможность, поддерживаемая начиная с версии 4.1.0.
Операция MERGE INTO сопоставляет исходные данные с целевой таблицей Iceberg и выполняет вставку, обновление или удаление в зависимости от результатов сопоставления. Она подходит для таких сценариев, как синхронизация данных и инкрементальные обновления.
Предварительные условия:
- Версия формата таблицы Iceberg (
format-version) должна быть 2 или выше. Таблицы формата V1 не поддерживают операциюMERGE INTO.
Синтаксис:
MERGE INTO target_table t
USING <source> s
ON <merge_condition>
[WHEN MATCHED [AND <condition>] THEN DELETE]
[WHEN MATCHED [AND <condition>] THEN UPDATE SET <column1> = <value1> [, ...]]
[WHEN NOT MATCHED [AND <condition>] THEN INSERT (<columns>) VALUES (<values>)]
Здесь <source> может быть подзапросом или другой таблицей.
Примеры:
-
Полная операция сопоставления (включает обновление, удаление и вставку):
MERGE INTO iceberg_tbl t
USING (
SELECT 1 AS id, 'Alice_new' AS name, 26 AS age, 'U' AS flag
UNION ALL
SELECT 2, 'Bob', 30, 'D'
UNION ALL
SELECT 4, 'Dora', 28, 'I'
) s
ON t.id = s.id
WHEN MATCHED AND s.flag = 'D' THEN DELETE
WHEN MATCHED THEN UPDATE SET
name = s.name,
age = s.age
WHEN NOT MATCHED THEN INSERT (id, name, age)
VALUES (s.id, s.name, s.age);В приведённом выше примере:
- Строка с
id = 2удаляется, посколькуflag = 'D'. - Строка с
id = 1обновляется новыми значениямиnameиage. - Строка с
id = 4вставляется, поскольку её нет в целевой таблице.
- Строка с
-
Только обновление совпавших строк:
MERGE INTO iceberg_tbl t
USING (SELECT 1 AS id, 'Alice_matched' AS name, 26 AS age) s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET name = s.name, age = s.age; -
Только вставка строк без совпадений:
MERGE INTO iceberg_tbl t
USING (SELECT 4 AS id, 'Dora' AS name, 40 AS age) s
ON t.id = s.id
WHEN NOT MATCHED THEN INSERT (id, name, age) VALUES (s.id, s.name, s.age); -
Использование подзапроса в качестве источника данных:
MERGE INTO iceberg_tbl t
USING (SELECT id FROM other_table WHERE id = 2) s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET name = 'UpdatedViaSubquery'; -
Операция
MERGE INTOдля партиционированных таблиц:MERGE INTO iceberg_partition_tbl t
USING (
SELECT 1 AS id, 'Alice_new' AS name, 26 AS age, DATE '2024-01-01' AS dt, 'U' AS flag
UNION ALL
SELECT 2, 'Bob', 30, DATE '2024-01-02', 'D'
UNION ALL
SELECT 4, 'Dora', 28, DATE '2024-01-04', 'I'
) s
ON t.id = s.id
WHEN MATCHED AND s.flag = 'D' THEN DELETE
WHEN MATCHED THEN UPDATE SET
name = s.name,
age = s.age
WHEN NOT MATCHED THEN INSERT (id, name, age, dt)
VALUES (s.id, s.name, s.age, s.dt);
Примечания:
- Все три описанные выше операции (
DELETE,UPDATE,MERGE INTO) требуют, чтобы версия формата таблицы Iceberg (format-version) была 2 или выше. Попытка выполнить их для таблицы формата V1 приводит к ошибке:must have format version 2 or higher for position deletes. Для таблицы формата V3 система не только использует Deletion Vectors в формате Puffin вместо исходных данных Position Delete, но и автоматически корректирует атрибуты жизненного цикла происхождения (_last_updated_sequence_number) записываемых записей, если изменяется их содержимое. - Эти операции поддерживают форматы файлов Parquet и ORC.
- При конкурентной записи Iceberg использует механизм оптимистического управления конкурентным доступом. При конфликтах записи операция может выбросить исключение конфликта транзакций.
- Операция
UPDATE, как самостоятельная, так и в составеMERGE INTO, поддерживает выражения и функции, напримерage = age * 2 + 1илиname = concat(name, '-modified'). - Эти операции применимы как к партиционированным, так и к непартиционированным таблицам.
- Начиная с версии 4.1.4,
MERGE INTOпроверяет соответствие между источником и целевой таблицей: если одной целевой строке соответствуют несколько исходных строк, оператор завершается ошибкойmultiple source rows matched the same target rowвместо получения недетерминированного результата. Если ожидается соответствие «один ко многим», сначала устраните дубликаты на стороне источника.
Связанные параметры
-
BE (Backend)
Имя параметра Значение по умолчанию Описание iceberg_sink_max_file_size1GB Максимальный размер файла данных. Когда объём записанных данных превышает этот размер, текущий файл закрывается и создаётся новый для продолжения записи. table_sink_partition_write_max_partition_nums_per_writer128 Максимальное количество разделов, в которые каждый экземпляр может записывать данные на узле BE. table_sink_non_partition_write_scaling_data_processed_threshold25MB Порог объёма данных для запуска масштабирования записи в непартиционированных таблицах. Для каждого дополнительного объёма данных, равного table_sink_non_partition_write_scaling_data_processed_threshold, используется новый модуль записи (экземпляр). Этот механизм регулирует число модулей записи в зависимости от объёма данных, повышая пропускную способность, экономя ресурсы и сводя к минимуму число файлов при небольших объёмах данных.table_sink_partition_write_min_data_processed_rebalance_threshold25MB Минимальный порог объёма данных для запуска перебалансировки партиционированных таблиц. Перебалансировка начинается, если current accumulated data volume-data volume since last rebalancing>=table_sink_partition_write_min_data_processed_rebalance_threshold. Снижение этого порога может улучшить баланс при значительных различиях размеров файлов, но может увеличить затраты на перебалансировку и повлиять на производительность.table_sink_partition_write_min_partition_data_processed_rebalance_thresholdМинимальный порог объёма данных раздела для запуска перебалансировки. Перебалансировка начинается, если current partition data volume>=threshold*number of tasks already allocated to the partition. Снижение этого порога может улучшить баланс при значительных различиях размеров файлов, но может увеличить затраты на перебалансировку и повлиять на производительность.
Управление базами данных и таблицами
Создание и удаление баз данных
Можно переключиться на нужный Catalog с помощью оператора SWITCH и выполнить команду CREATE DATABASE:
SWITCH iceberg;
CREATE DATABASE [IF NOT EXISTS] iceberg_db;
Также можно создать базу данных с помощью полного имени или указать расположение (сейчас указание расположения поддерживают только Catalog типа HMS), например:
CREATE DATABASE [IF NOT EXISTS] iceberg.iceberg_db;
CREATE DATABASE [IF NOT EXISTS] iceberg.iceberg_db
PROPERTIES ('location'='hdfs://172.21.16.47:4007/path/to/db/');
Просмотреть сведения о расположении базы данных можно с помощью команды SHOW CREATE DATABASE:
mysql> SHOW CREATE DATABASE iceberg_db;
+-------------+-------------------------------------------------------------------------------------------------+
| Database | Create Database |
+-------------+-------------------------------------------------------------------------------------------------+
| iceberg_db | CREATE DATABASE iceberg_db LOCATION 'hdfs://172.21.16.47:4007/usr/hive/warehouse/iceberg_db.db' |
+-------------+-------------------------------------------------------------------------------------------------+
Чтобы удалить базу данных:
DROP DATABASE [IF EXISTS] iceberg.iceberg_db;
Перед удалением базы данных Iceberg необходимо удалить все её таблицы; в противном случае возникнет ошибка.
Создание и удаление таблиц
-
Создание таблиц
Doris поддерживает создание как партиционированных, так и непартиционированных таблиц Iceberg.
Например:
-- Create unpartitioned iceberg table
CREATE TABLE unpartitioned_table (
`col1` BOOLEAN COMMENT 'col1',
`col2` INT COMMENT 'col2',
`col3` BIGINT COMMENT 'col3',
`col4` FLOAT COMMENT 'col4',
`col5` DOUBLE COMMENT 'col5',
`col6` DECIMAL(9,4) COMMENT 'col6',
`col7` STRING COMMENT 'col7',
`col8` DATE COMMENT 'col8',
`col9` DATETIME COMMENT 'col9'
)
PROPERTIES (
'write-format'='parquet'
);
-- Create partitioned iceberg table
-- The partition columns must be in table's column definition list
CREATE TABLE partition_table (
`ts` DATETIME COMMENT 'ts',
`col1` BOOLEAN COMMENT 'col1',
`col2` INT COMMENT 'col2',
`col3` BIGINT COMMENT 'col3',
`col4` FLOAT COMMENT 'col4',
`col5` DOUBLE COMMENT 'col5',
`col6` DECIMAL(9,4) COMMENT 'col6',
`col7` STRING COMMENT 'col7',
`col8` DATE COMMENT 'col8',
`col9` DATETIME COMMENT 'col9',
`pt1` STRING COMMENT 'pt1',
`pt2` STRING COMMENT 'pt2'
)
PARTITION BY LIST (day(ts), pt1, pt2) ()
PROPERTIES (
'write-format'='orc',
'compression-codec'='zlib'
);Начиная с версии 4.1.0, Doris поддерживает указание столбцов сортировки при создании таблицы Iceberg. При записи данные сортируются по указанным столбцам, что повышает производительность запросов.
CREATE TABLE ordered_table (
`id` int NULL,
`name` text NULL,
`score` double NULL,
`create_time` datetimev2(6) NULL
)
ORDER BY (`id` ASC NULLS FIRST, `score` DESC NULLS LAST)
PROPERTIES (
"write-format" = "parquet",
"write.parquet.compression-codec" = "zstd"
);- Если столбцы сортировки не указаны, сортировка при записи не выполняется.
- Порядок сортировки по умолчанию — ASC NULLS FIRST.
После создания можно использовать команду
SHOW CREATE TABLEдля просмотра оператора создания таблицы Iceberg. Подробнее о функциях партиционирования см. в разделе Партиционирование. -
Удаление таблиц
Удалить таблицу Iceberg можно с помощью оператора
DROP TABLE. При удалении таблицы также удаляются её данные, включая данные разделов.Например:
DROP TABLE [IF EXISTS] iceberg_tbl; -
Сопоставление типов столбцов
См. раздел Сопоставление типов столбцов.
-
Партиционирование
Типы разделов Iceberg соответствуют разделам List в Doris. Поэтому при создании партиционированной таблицы Iceberg в Doris следует использовать синтаксис партиционирования List, но явно перечислять каждый раздел не требуется. При вставке данных Doris автоматически создаёт соответствующие разделы Iceberg на основе значений данных.
-
Поддерживается создание таблиц, партиционированных по одному или нескольким столбцам.
-
Поддерживаются функции преобразования разделов для неявного партиционирования и эволюции партиционирования Iceberg. Конкретные функции преобразования разделов Iceberg см. в разделе Преобразования разделов Iceberg:
-
year(ts)илиyears(ts) -
month(ts)илиmonths(ts) -
day(ts)илиdays(ts)илиdate(ts) -
hour(ts)илиhours(ts)илиdate_hour(ts) -
bucket(N, col) -
truncate(L, col)
-
-
-
Форматы файлов
-
Parquet (по умолчанию)
В таблицах Iceberg, созданных Doris, тип Datetime соответствует типу
timestamp_ntz.В версиях после 3.1.0 при записи типа Datetime в файл Parquet используется физический тип INT64 вместо INT96.
Если таблица Iceberg создана другой системой, типы
timestampиtimestamp_ntzоба сопоставляются с типом Datetime в Doris. Однако при записи необходимость обработки часового пояса определяется фактическим типом. -
ORC
-
-
Форматы сжатия
-
Parquet: snappy, zstd (по умолчанию), plain (без сжатия).
-
ORC: snappy, zlib (по умолчанию), zstd, plain (без сжатия).
-
-
Среда хранения
-
HDFS
-
Объектное хранилище
-
Изменение схемы
Начиная с 3.1.0, Doris поддерживает изменение схемы таблиц Iceberg с помощью оператора ALTER TABLE.
Поддерживаются следующие операции изменения схемы:
-
Переименование столбца
Используйте предложение
RENAME COLUMNдля переименования столбцов. Начиная с версии 4.1.4, поддерживается переименование столбцов внутри вложенных типов, а ключевое словоTOнеобязательно.ALTER TABLE iceberg_table RENAME COLUMN old_col_name TO new_col_name;
-- Supported since 4.1.4: TO can be omitted
ALTER TABLE iceberg_table RENAME COLUMN old_col_name new_col_name;
-- Supported since 4.1.4: rename a nested field
ALTER TABLE iceberg_table RENAME COLUMN s.old_field TO new_field; -
Добавление столбца
Используйте
ADD COLUMNдля добавления нового столбца. Начиная с версии 4.1.4, поддерживается добавление нового столбца во вложенный тип (STRUCT) через путь с точками (например,s.new_field); новое вложенное поле должно допускать NULL.При добавлении нового столбца можно указать допустимость NULL, значение по умолчанию, комментарий и позицию столбца.
ALTER TABLE iceberg_table ADD COLUMN col_name col_type [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment', [FIRST|AFTER col_name]]]];Пример:
ALTER TABLE iceberg_table ADD COLUMN new_col STRING NOT NULL DEFAULT 'default_value' COMMENT 'This is a new col' AFTER old_col; -
Добавление нескольких столбцов
С помощью
ADD COLUMNтакже можно добавить несколько столбцов. Новые столбцы добавляются в конец таблицы. Указание позиции для нескольких столбцов не поддерживается. Добавление новых столбцов во вложенные типы не поддерживается.Синтаксис для каждого столбца такой же, как при добавлении одного столбца.
ALTER TABLE iceberg_table ADD COLUMN (col_name1 col_type1 [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment']]], col_name2 col_type2 [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment']]] ...); -
Удаление столбца
Используйте
DROP COLUMNдля удаления столбцов. Начиная с версии 4.1.4, поддерживается удаление столбца внутри вложенного типа через путь с точками.ALTER TABLE iceberg_table DROP COLUMN col_name;
-- Supported since 4.1.4: drop a nested field
ALTER TABLE iceberg_table DROP COLUMN s.field_name; -
Изменение столбца
Используйте оператор
MODIFY COLUMNдля изменения атрибутов столбца, включая тип, допустимость NULL, значение по умолчанию, комментарий и позицию столбца.Начиная с версии 4.0.4, Doris поддерживает изменение сложных типов (STRUCT, ARRAY, MAP), включая безопасное расширение типов и добавление полей структуры в конец.
Безопасные расширения типов, поддерживаемые во вложенных типах:
- INT -> BIGINT, LARGEINT
- TINYINT -> SMALLINT, INT, BIGINT, LARGEINT
- SMALLINT -> INT, BIGINT, LARGEINT
- BIGINT -> LARGEINT
- FLOAT -> DOUBLE
- VARCHAR(n) -> VARCHAR(m), где m > n
Ограничения для сложных типов:
- Все новые вложенные поля должны допускать NULL.
- Нельзя сделать необязательное поле обязательным.
- В качестве значения по умолчанию для сложных типов поддерживается только NULL.
Примечание: при изменении атрибутов столбца все неизменяемые атрибуты также следует явно указать с их исходными значениями.
ALTER TABLE iceberg_table MODIFY COLUMN col_name col_type [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment', [FIRST|AFTER col_name]]]];Пример:
CREATE TABLE iceberg_table (
id INT,
name STRING
);
-- Modify the id column type to BIGINT, set as NOT NULL, default value to 0, and add comment
ALTER TABLE iceberg_table MODIFY COLUMN id BIGINT NOT NULL DEFAULT 0 COMMENT 'This is a modified id column';Пример изменения сложных типов:
-- Create Iceberg table with complex types
CREATE TABLE iceberg_tbl (
id BIGINT,
user_info STRUCT<name:STRING, scores:ARRAY<INT>, age:INT>,
dt STRING
);
-- Append a new field (email) to the STRUCT column
ALTER TABLE iceberg_tbl MODIFY COLUMN user_info STRUCT<name:STRING, scores:ARRAY<INT>, age:INT, email:STRING>;
-- Promote the nested ARRAY element type from INT to BIGINT
ALTER TABLE iceberg_tbl MODIFY COLUMN user_info STRUCT<name:STRING, scores:ARRAY<BIGINT>, age:INT, email:STRING>; -
Изменение порядка столбцов
Используйте
ORDER BY, чтобы изменить порядок столбцов, указав новую последовательность.ALTER TABLE iceberg_table ORDER BY (col_name1, col_name2, ...);
Изменение схемы вложенных столбцов (4.1.4+)
Начиная с версии 4.1.4, ADD COLUMN, DROP COLUMN, MODIFY COLUMN и RENAME COLUMN принимают путь с точками (например, a.b.c) для непосредственной работы с вложенным полем. Эта возможность применима только к таблицам Iceberg; её использование с таблицей любого другого типа приводит к ошибке: Nested column path is only supported for Iceberg tables: ....
Основные ограничения и ошибки:
| Сообщение об ошибке | Описание |
|---|---|
New nested field '<path>' must be nullable | Новое вложенное поле должно допускать NULL |
Rollup is not supported for Iceberg column operations | Предложение Rollup не поддерживается |
PROPERTIES are not supported for Iceberg column operations | Предложение PROPERTIES не поддерживается |
KEY is not supported for Iceberg ADD/MODIFY COLUMN | Ключевое слово KEY не поддерживается |
Generated columns are not supported for Iceberg ADD/MODIFY COLUMN | Генерируемые столбцы не поддерживаются |
Modifying default values is not supported for Iceberg columns | Изменение значения по умолчанию существующего столбца не поддерживается |
ON UPDATE is not supported for Iceberg ADD COLUMN | Предложение ON UPDATE не поддерживается |
Modify column type from complex to primitive is not supported | Изменение сложного типа на примитивный не поддерживается |
Cannot change MAP key type from ... / Cannot <op> MAP key nested column | Изменение типа ключа MAP или выполнение операции с вложенным столбцом ключа MAP не поддерживается |
Iceberg does not support comments on collection element or value fields | Комментарии для полей элементов коллекции или значений MAP не поддерживаются |
Multiple Iceberg ALTER clauses are not supported when a statement ... | При работе с вложенными столбцами оператор может содержать только одно предложение ALTER |
Эволюция партиционирования
Начиная с версии 4.0.2, Doris поддерживает эволюцию партиционирования таблиц Iceberg с помощью операторов ALTER.
Поддерживаются следующие преобразования разделов:
| Преобразование | Синтаксис | Пример |
|---|---|---|
| bucket | bucket(N, column) | bucket(16, id) |
| truncate | truncate(N, column) | truncate(10, name) |
| year | year(column) | year(ts) |
| month | month(column) | month(ts) |
| day | day(column) | day(ts) |
| hour | hour(column) | hour(ts) |
| identity | column | category |
Поддерживаются следующие операции:
-
Добавление ключа партиционирования
-- use optional AS keyword to specify a custom name for the partition field
ALTER TABLE table_name ADD PARTITION KEY partition_transform [AS key_name];
-- example
ALTER TABLE prod.db.sample ADD PARTITION KEY bucket(16, id);
ALTER TABLE prod.db.sample ADD PARTITION KEY truncate(4, data);
ALTER TABLE prod.db.sample ADD PARTITION KEY year(ts);
-- use optional AS keyword to specify a custom name for the partition field
ALTER TABLE prod.db.sample ADD PARTITION KEY bucket(16, id) AS shard; -
Удаление ключа партиционирования
ALTER TABLE table_name DROP PARTITION KEY partition_transform|key_name;
-- example
ALTER TABLE prod.db.sample DROP PARTITION KEY catalog;
ALTER TABLE prod.db.sample DROP PARTITION KEY bucket(16, id);
ALTER TABLE prod.db.sample DROP PARTITION KEY truncate(4, data);
ALTER TABLE prod.db.sample DROP PARTITION KEY year(ts);
ALTER TABLE prod.db.sample DROP PARTITION KEY shard; -
Замена ключа партиционирования
-- use optional AS keyword to specify a custom name for the partition field
ALTER TABLE table_name REPLACE PARTITION KEY key_name WITH partition_transform [AS key_name];
-- example
ALTER TABLE prod.db.sample REPLACE PARTITION KEY ts_day WITH day(ts);
-- use optional AS keyword to specify a custom name for the new partition field
ALTER TABLE prod.db.sample REPLACE PARTITION KEY ts_day WITH day(ts) AS day_of_ts;
Управление ветвями и тегами
Начиная с 3.1.0
-
Создание ветви
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
CREATE [OR REPLACE] BRANCH [IF NOT EXISTS] <branch_name>
[AS OF VERSION <snapshot_id>]
[RETAIN <num> { DAYS | HOURS | MINUTES }]
[WITH SNAPSHOT RETENTION { snapshotKeep | timeKeep }]
snapshotKeep:
<num> SNAPSHOTS [<num> { DAYS | HOURS | MINUTES }]
timeKeep:
<num> { DAYS | HOURS | MINUTES }Примеры:
-- Create branch "b1".
ALTER TABLE tbl CREATE BRANCH b1;
ALTER TABLE tb1 CREATE BRANCH IF NOT EXISTS b1;
-- Create or replace branch "b1".
ALTER TABLE tb1 CREATE OR REPLACE BRANCH b1;
-- Create or replace branch "b1" based on snapshot "123456".
ALTER TABLE tb1 CREATE OR REPLACE BRANCH b1 AS OF VERSION 123456;
-- Create or replace branch "b1" based on snapshot "123456", branch retained for 1 day.
ALTER TABLE tb1 CREATE OR REPLACE BRANCH b1 AS OF VERSION 123456 RETAIN 1 DAYS;
-- Create branch "b1" based on snapshot "123456", branch retained for 30 days. Keep the latest 3 snapshots in the branch.
ALTER TABLE tb1 CREATE BRANCH b1 AS OF VERSION 123456 RETAIN 30 DAYS WITH SNAPSHOT RETENTION 3 SNAPSHOTS;
-- Create branch "b1" based on snapshot "123456", branch retained for 30 days. Snapshots in the branch are retained for at most 2 days.
ALTER TABLE tb1 CREATE BRANCH b1 AS OF VERSION 123456 RETAIN 30 DAYS WITH SNAPSHOT RETENTION 2 DAYS;
-- Create branch "b1" based on snapshot "123456", branch retained for 30 days. Keep the latest 3 snapshots in the branch, and snapshots in the branch are retained for at most 2 days.
ALTER TABLE tb1 CREATE BRANCH b1 AS OF VERSION 123456 RETAIN 30 DAYS WITH SNAPSHOT RETENTION 3 SNAPSHOTS 2 DAYS; -
Удаление ветви
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
DROP BRANCH [IF EXISTS] <branch_name>;Пример:
ALTER TABLE tbl DROP BRANCH b1; -
Создание тега
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
CREATE [OR REPLACE] TAG [IF NOT EXISTS] <tag_name>
[AS OF VERSION <snapshot_id>]
[RETAIN <num> { DAYS | HOURS | MINUTES }]Примеры:
-- Create tag "t1".
ALTER TABLE tbl CREATE TAG t1;
ALTER TABLE tb1 CREATE TAG IF NOT EXISTS t1;
-- Create or replace tag "t1".
ALTER TABLE tb1 CREATE OR REPLACE TAG t1;
-- Create or replace tag "t1" based on snapshot "123456".
ALTER TABLE tb1 CREATE OR REPLACE TAG b1 AS OF VERSION 123456;
-- Create or replace tag "b1" based on snapshot "123456", tag retained for 1 day.
ALTER TABLE tb1 CREATE OR REPLACE TAG b1 AS OF VERSION 123456 RETAIN 1 DAYS; -
Удаление тега
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
DROP TAG [IF EXISTS] <tag_name>;Пример:
ALTER TABLE tbl DROP TAG t1;
Действия с таблицами Iceberg
Эта возможность поддерживается начиная с версии 4.0.2. Требования к версии для каждой операции приведены в её описании.
Это экспериментальная возможность.
Doris поддерживает выполнение специальных действий с таблицами Iceberg с помощью синтаксиса ALTER TABLE EXECUTE. Этот синтаксис предоставляет единый интерфейс для различных операций, таких как оптимизация таблиц и управление снимками.
ALTER TABLE [catalog.][database.]table_name
EXECUTE <action_name> ("key1" = "value1", "key2" = "value2", ...)
[WHERE <condition>]
action_name: имя выполняемой операции("key1" = "value1", ...): параметры операции в виде пар «ключ — значение». Имена параметров должны быть заключены в двойные кавычки[WHERE <condition>]: необязательное условие WHERE для указания раздела или диапазона данных для операции (поддерживается только некоторыми операциями)
cherrypick_snapshot
Операция cherrypick_snapshot объединяет изменения из указанного снимка с текущим состоянием таблицы, создавая новый снимок без изменения или удаления исходного.
Поддерживаемая версия: 4.0.2+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE cherrypick_snapshot ("snapshot_id" = "<snapshot_id>")
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
snapshot_id | Long | Да | Идентификатор снимка, изменения которого нужно объединить |
Возвращаемое значение:
Выполнение операции cherrypick_snapshot возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
source_snapshot_id | BIGINT | Идентификатор объединённого снимка |
current_snapshot_id | BIGINT | Идентификатор снимка, созданного и установленного как текущий после объединения |
Пример:
-- Merge changes from snapshot 123456789 into the current table state
ALTER TABLE iceberg_db.iceberg_table
EXECUTE cherrypick_snapshot ("snapshot_id" = "123456789");
Примечания:
- Эта операция не поддерживает условия WHERE
- Если указанный снимок не существует, операция завершается ошибкой
- Объединение создаёт новый снимок и не удаляет исходный
expire_snapshots
Операция expire_snapshots удаляет старые снимки из таблиц Iceberg, освобождая место в хранилище и ускоряя работу с метаданными. Эта операция соответствует спецификации процедуры Apache Iceberg Spark.
Поддерживаемая версия: 4.1.0+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE expire_snapshots ("key1" = "value1", "key2" = "value2", ...)
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
older_than | String | Нет | Временной порог удаления снимков. Снимки старше него будут удалены. Поддерживается формат даты и времени ISO (например, 2024-01-01T00:00:00) или временная метка в миллисекундах |
retain_last | Integer | Нет | Количество сохраняемых снимков-предков. Если указан отдельно, автоматически задаёт для older_than текущее время |
snapshot_ids | String | Нет | Список конкретных идентификаторов снимков для удаления, разделённых запятыми |
max_concurrent_deletes | Integer | Нет | Размер пула потоков для операций удаления |
clean_expired_metadata | Boolean | Нет | Если задано значение true, удаляет неиспользуемые спецификации партиционирования и схемы |
Возвращаемое значение:
Выполнение операции expire_snapshots возвращает набор результатов со следующими 6 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
deleted_data_files_count | BIGINT | Количество удалённых файлов данных |
deleted_position_delete_files_count | BIGINT | Количество удалённых файлов Position Delete |
deleted_equality_delete_files_count | BIGINT | Количество удалённых файлов Equality Delete |
deleted_manifest_files_count | BIGINT | Количество удалённых файлов манифестов |
deleted_manifest_lists_count | BIGINT | Количество удалённых файлов списков манифестов |
deleted_statistics_files_count | BIGINT | Количество удалённых файлов статистики |
Пример:
-- Expire snapshots, keeping only the last 2
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("retain_last" = "2");
-- Expire snapshots older than a specific timestamp
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("older_than" = "2024-01-01T00:00:00");
-- Expire specific snapshots by ID
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("snapshot_ids" = "123456789,987654321");
-- Combine parameters: expire snapshots older than 2024-06-01 but keep at least the last 5
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("older_than" = "2024-06-01T00:00:00", "retain_last" = "5");
Примечания:
- Эта операция не поддерживает условия WHERE.
- Если указаны и
older_than, иretain_last, применяются оба условия: удаляются только снимки старшеolder_than, которые при этом НЕ входят в число последнихretain_lastснимков. snapshot_idsможно использовать отдельно для удаления конкретных снимков.- Эта операция безвозвратно удаляет снимки и связанные с ними файлы данных. Используйте её с осторожностью.
- Перед выполнением рекомендуется запросить системную таблицу
$snapshots, чтобы изучить сведения о снимках таблицы.
fast_forward
Операция fast_forward быстро перемещает текущий снимок одной ветви к последнему снимку другой ветви.
Поддерживаемая версия: 4.0.2+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE fast_forward ("branch" = "<branch_name>", "to" = "<target_branch>")
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
branch | String | Да | Имя перемещаемой ветви |
to | String | Да | Имя целевой ветви; branch будет перемещена к последнему снимку этой ветви |
Возвращаемое значение:
Выполнение операции fast_forward возвращает набор результатов со следующими 3 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
branch_updated | STRING | Имя перемещённой ветви |
previous_ref | BIGINT | Идентификатор снимка, на который ветвь указывала до перемещения (может быть NULL) |
updated_ref | BIGINT | Идентификатор снимка, на который ветвь указывает после перемещения |
Пример:
-- Advance the feature branch to the latest snapshot of the main branch
ALTER TABLE iceberg_db.iceberg_table
EXECUTE fast_forward ("branch" = "feature", "to" = "main");
Примечания:
- Эта операция не поддерживает условия WHERE
- Если указанная ветвь не существует, операция завершается ошибкой
- Перемещать можно только ветви, теги не поддерживаются
publish_changes
Операция publish_changes выполняет шаг публикации в подходе Write-Audit-Publish (WAP). Она находит снимки с определённым атрибутом wap.id и добавляет их в текущее состояние таблицы. Это позволяет атомарно сделать подготовленные данные видимыми после проверки.
Поддерживаемая версия: 4.1.0+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE publish_changes ("wap_id" = "<wap-id>")
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
wap_id | String | Да | Значение wap.id публикуемого снимка |
Возвращаемое значение:
Выполнение операции publish_changes возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
previous_snapshot_id | BIGINT | Идентификатор снимка до публикации |
current_snapshot_id | BIGINT | Идентификатор нового снимка после публикации |
Пример:
ALTER TABLE iceberg_db.iceberg_table
EXECUTE publish_changes ("wap_id" = "branch-123")
Примечания:
- Эта операция не поддерживает условия WHERE
- Если указанное значение
wap.idне существует, операция завершается ошибкой
rewrite_data_files
Операция rewrite_data_files перезаписывает файлы данных таблицы Iceberg для компактации мелких файлов, повышая производительность запросов и эффективность хранения. Это синхронная операция.
Поддерживаемая версия: 4.0.2+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE rewrite_data_files ("key1" = "value1", "key2" = "value2", ...) [WHERE <condition>]
Параметры:
| Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
target-file-size-bytes | Long | 536870912 (512MB) | Целевой размер файла в байтах. Желаемый размер выходных файлов |
min-file-size-bytes | Long | target-file-size-bytes * 0.75 | Минимальный размер файла в байтах. Файлы меньшего размера будут перезаписаны. Если не указан, по умолчанию равен 75% целевого размера файла |
max-file-size-bytes | Long | target-file-size-bytes * 1.8 | Максимальный размер файла в байтах. Файлы большего размера будут разделены. Если не указан, по умолчанию равен 180% целевого размера файла |
min-input-files | Integer | 5 | Минимальное количество входных файлов для запуска перезаписи. Перезапись выполняется, только когда количество файлов для перезаписи достигает этого порога |
rewrite-all | Boolean | false | Определяет, нужно ли перезаписывать все файлы независимо от их размера |
max-file-group-size-bytes | Long | 107374182400 (100GB) | Максимальный размер одной группы файлов в байтах. Ограничивает объём данных, обрабатываемых одной задачей перезаписи |
delete-file-threshold | Integer | Integer.MAX_VALUE | Минимальное количество файлов удалений для запуска перезаписи |
delete-ratio-threshold | Double | 0.3 | Минимальная доля удалённых записей для запуска перезаписи (удалённые записи / общее количество записей). Диапазон: 0.0 - 1.0 |
output-spec-id | Long | 2 | Идентификатор спецификации партиционирования для выходных файлов |
Возвращаемое значение:
Выполнение операции rewrite_data_files возвращает набор результатов со следующими 4 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
rewritten_data_files_count | INT | Количество перезаписанных файлов данных |
added_data_files_count | INT | Количество добавленных новых файлов данных |
rewritten_bytes_count | INT | Количество перезаписанных байтов |
removed_delete_files_count | BIGINT | Количество удалённых файлов удалений |
Примеры:
-- Rewrite data files with default parameters
ALTER TABLE iceberg_db.iceberg_table EXECUTE rewrite_data_files();
-- Specify target file size and minimum input files
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_data_files (
"target-file-size-bytes" = "134217728",
"min-input-files" = "10"
);
-- Rewrite data in specific partitions using WHERE condition
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_data_files (
"target-file-size-bytes" = "268435456"
)
WHERE date_col = '2024-01-01';
-- Rewrite all files
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_data_files (
"rewrite-all" = "true",
"target-file-size-bytes" = "536870912"
);
Примечания:
- Операция
rewrite_data_filesчитает и перезаписывает файлы данных, что создаёт дополнительную нагрузку на ввод-вывод и вычислительные ресурсы. Распределяйте ресурсы кластера соответствующим образом. - Перед выполнением можно использовать SQL из раздела Просмотр распределения файлов данных, чтобы оценить необходимость перезаписи
- Условия WHERE позволяют ограничить разделы или диапазон данных для перезаписи. Такое условие исключает файлы, не содержащие данных, соответствующих WHERE, сокращая количество файлов и объём данных для перезаписи
- Перед выполнением можно использовать SQL из раздела Логика выбора файлов для перезаписи, чтобы определить, какие файлы будут перезаписаны
rewrite_manifests
Операция rewrite_manifests позволяет оптимизировать метаданные таблицы Iceberg путём перезаписи файлов манифестов, повышая производительность запросов и сокращая затраты на обработку метаданных.
Она решает задачи оптимизации файлов манифестов в больших таблицах Iceberg, поскольку большое количество мелких файлов манифестов может замедлять планирование запросов.
Поддерживаемая версия: 4.1.0+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE rewrite_manifests();
Параметры:
Параметров нет
Возвращаемое значение:
Выполнение операции rewrite_manifests возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
rewritten_manifests_count | BIGINT | Количество перезаписанных файлов |
total_data_manifests_count | BIGINT | Количество перезаписанных файлов манифестов данных |
Пример:
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_manifests();
rollback_to_snapshot
Операция rollback_to_snapshot откатывает таблицу Iceberg к указанному снимку.
Поддерживаемая версия: 4.0.2+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE rollback_to_snapshot ("snapshot_id" = "<snapshot_id>")
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
snapshot_id | Long | Да | Идентификатор снимка, к которому нужно откатиться |
Возвращаемое значение:
Выполнение операции rollback_to_snapshot возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
previous_snapshot_id | BIGINT | Идентификатор текущего снимка до отката |
current_snapshot_id | BIGINT | Идентификатор снимка, установленного как текущий после отката |
Пример:
-- Roll back to snapshot 987654321
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rollback_to_snapshot ("snapshot_id" = "987654321");
Примечания:
- Эта операция не поддерживает условия WHERE
- Если указанный снимок не существует, операция завершается ошибкой
- Если текущий снимок уже является целевым, операция сразу завершается без создания нового снимка
rollback_to_timestamp
Операция rollback_to_timestamp откатывает таблицу Iceberg к снимку на указанный момент времени.
Поддерживаемая версия: 4.0.2+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE rollback_to_timestamp ("timestamp" = "<timestamp>")
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
timestamp | String | Да | Момент времени, к которому нужно откатиться. Поддерживаются два формата: 1. Формат даты и времени ISO: yyyy-MM-dd HH:mm:ss.SSS (например, 2024-01-01 10:30:00.000)2. Временная метка в миллисекундах (например, 1704067200000) |
Возвращаемое значение:
Выполнение операции rollback_to_timestamp возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
previous_snapshot_id | BIGINT | Идентификатор текущего снимка до отката |
current_snapshot_id | BIGINT | Идентификатор снимка на указанный момент времени, установленного как текущий |
Примеры:
-- Roll back to specified point in time (ISO format)
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rollback_to_timestamp ("timestamp" = "2024-01-01 10:30:00.000");
-- Roll back to specified point in time (timestamp format)
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rollback_to_timestamp ("timestamp" = "1704067200000");
Примечания:
- Эта операция не поддерживает условия WHERE
- Параметр
timestampподдерживает формат даты и времени ISO (yyyy-MM-dd HH:mm:ss.SSS) или формат временной метки в миллисекундах - Если на указанный момент времени нет соответствующего снимка, операция завершается ошибкой
set_current_snapshot
Операция set_current_snapshot устанавливает текущий снимок таблицы Iceberg по указанному идентификатору снимка или ссылке (ветви либо тегу).
Поддерживаемая версия: 4.0.2+
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE set_current_snapshot ("snapshot_id" = "<snapshot_id>" | "ref" = "<ref_name>")
Параметры:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
snapshot_id | Long | Один из двух | Идентификатор снимка, который нужно установить как текущий |
ref | String | Один из двух | Имя ссылки (ветви или тега), снимок которой нужно установить как текущий |
Возвращаемое значение:
Выполнение операции set_current_snapshot возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
previous_snapshot_id | BIGINT | Идентификатор текущего снимка до операции |
current_snapshot_id | BIGINT | Идентификатор снимка после операции (из параметра snapshot_id или определённый по параметру ref) |
Примеры:
-- Set current snapshot by snapshot ID
ALTER TABLE iceberg_db.iceberg_table
EXECUTE set_current_snapshot ("snapshot_id" = "123456789");
-- Set current snapshot by branch name
ALTER TABLE iceberg_db.iceberg_table
EXECUTE set_current_snapshot ("ref" = "feature_branch");
-- Set current snapshot by tag name
ALTER TABLE iceberg_db.iceberg_table
EXECUTE set_current_snapshot ("ref" = "v1.0");
Примечания:
- Эта операция не поддерживает условия WHERE
- Параметры
snapshot_idиrefвзаимоисключающие; можно указать только один из них - Если указанный идентификатор снимка или ссылка не существует, операция завершается ошибкой
- Если текущий снимок уже является целевым, операция сразу завершается без создания нового снимка
publish_changes
Операция publish_changes используется в режиме WAP (Write-Audit-Publish) для публикации снимка с указанным wap.id в качестве текущего состояния таблицы.
Она находит снимок, у которого wap.id совпадает с заданным wap_id, и применяет его изменения к текущей таблице, делая подготовленные данные видимыми для всех операций чтения.
Синтаксис:
ALTER TABLE [catalog.][database.]table_name
EXECUTE publish_changes("wap_id" = "<wap_id>")
Параметры:
Параметры:
| Имя параметра | Тип | Обязателен | Описание |
|---|---|---|---|
wap_id | STRING | Да | Идентификатор WAP публикуемого снимка |
Возвращаемое значение:
Выполнение publish_changes возвращает набор результатов со следующими 2 столбцами:
| Имя столбца | Тип | Описание |
|---|---|---|
previous_snapshot_id | STRING | Идентификатор текущего снимка до публикации (NULL, если его нет) |
current_snapshot_id | STRING | Идентификатор нового снимка, созданного и установленного как текущий после публикации |
Примеры:
-- Publish the snapshot whose WAP ID is test_wap_001
ALTER TABLE iceberg_db.iceberg_table
EXECUTE publish_changes("wap_id" = "test_wap_001");
Примечания:
- Эта операция не поддерживает предложение WHERE, а также предложения PARTITION/PARTITIONS
- Она имеет смысл только для таблиц Iceberg с write.wap.enabled = true и снимками WAP, созданными через wap.id
- Если снимок с указанным wap_id не найден, операция завершается ошибкой
- После публикации новый снимок становится текущим
- Если до публикации снимка не было, previous_snapshot_id может иметь значение NULL
Оптимизация таблиц Iceberg
Просмотр распределения файлов данных
Следующий SQL позволяет проанализировать распределение данных и количество файлов удалений в таблицах Iceberg, чтобы определить необходимость оптимизации, например rewrite_data_files.
-
Вывод распределения файлов данных по размеру. Позволяет определить, не слишком ли много мелких файлов:
SELECT
CASE
WHEN file_size_in_bytes BETWEEN 0 AND 8 * 1024 * 1024 THEN '0-8M'
WHEN file_size_in_bytes BETWEEN 8 * 1024 * 1024 + 1 AND 32 * 1024 * 1024 THEN '8-32M'
WHEN file_size_in_bytes BETWEEN 32 * 1024 * 1024 + 1 AND 128 * 1024 * 1024 THEN '32-128M'
WHEN file_size_in_bytes BETWEEN 128 * 1024 * 1024 + 1 AND 512 * 1024 * 1024 THEN '128-512M'
WHEN file_size_in_bytes > 512 * 1024 * 1024 THEN '> 512M'
ELSE 'Unknown'
END AS SizeRange,
COUNT(*) AS FileNum
FROM store_sales$data_files
GROUP BY
SizeRange;
+-----------+---------+
| SizeRange | FileNum |
+-----------+---------+
| 0-8M | 8 |
| 8-32M | 6 |
+-----------+---------+ -
Вывод количества файлов данных и файлов удалений:
SELECT
CASE
WHEN content = 0 THEN 'DataFile'
WHEN content = 1 THEN 'PositionDeleteFile'
WHEN content = 2 THEN 'EqualityDeleteFile'
ELSE 'Unknown'
END AS ContentType,
COUNT(*) AS FileNum,
SUM(file_size_in_bytes) AS SizeInBytes,
SUM(record_count) AS Records
FROM
iceberg_table$files
GROUP BY
ContentType;
+--------------------+---------+-------------+---------+
| ContentType | FileNum | SizeInBytes | Records |
+--------------------+---------+-------------+---------+
| EqualityDeleteFile | 2787 | 1432518 | 27870 |
| DataFile | 2787 | 4062416 | 38760 |
| PositionDeleteFile | 11 | 36608 | 10890 |
+--------------------+---------+-------------+---------+
Оставшиеся ссылки на удаления (Dangling Delete)
В некоторых случаях после выполнения действия rewrite_data_files ссылки на определённые Position Delete могут остаться в метаданных снимка (Dangling Delete). Если в такой ситуации напрямую использовать сведения о количестве строк из метаданных, результат может быть неверным.
Поэтому по умолчанию для запросов COUNT(*) при обнаружении файла Position Delete оптимизация проталкивания COUNT не включается; вместо этого файл читается напрямую для получения фактического результата COUNT(*). Однако этот способ требует времени.
Если пользователь может гарантировать отсутствие проблемы Dangling Delete, эту проверку можно пропустить с помощью переменной сеанса Doris ignore_iceberg_dangling_delete. Её значение по умолчанию — false. При значении true система возвращает результат COUNT(*) напрямую на основе сведений о количестве строк из метаданных, повышая эффективность запросов.
Эта возможность поддерживается начиная с версий 3.1.4 и 4.0.3.
Приложение
Стратегия выбора файлов для rewrite_data_files
В этом разделе описана логика выбора файлов для перезаписи. Следующие SQL-запросы также позволяют проанализировать по сведениям системных таблиц, какие файлы будут перезаписаны. Это помогает отладить и понять поведение перезаписи до выполнения реальных операций.
Операция перезаписи использует двухэтапную стратегию фильтрации и группировки:
-
Этап 1: фильтрация на уровне файлов
Сначала файлы фильтруются по условиям уровня файлов. Для перезаписи рассматриваются только файлы, удовлетворяющие хотя бы одному из следующих условий:
- Размер файла вне диапазона: файл меньше
min-file-size-bytesили большеmax-file-size-bytes - Слишком много файлов удалений: количество связанных файлов удалений >=
delete-file-threshold - Высокая доля удалений: доля удалённых записей >=
delete-ratio-threshold
Примечание об условиях для файлов удалений: условия, связанные с файлами удалений (
delete-file-thresholdиdelete-ratio-threshold), влияют на выбор файлов для перезаписи, но не могут быть точно рассчитаны с помощью SQL-запросов к системным таблицам. Текущих сведений системных таблиц недостаточно, чтобы точно определить, какие файлы данных затрагиваются файлами удалений. Файлы удалений могут затрагивать только определённые файлы данных (особенно файлы Position Delete), а для установления связи между файлами удалений и файлами данных нужны более подробные метаданные, недоступные в текущих системных таблицах. Реальные операции перезаписи оценивают эти условия на основе более подробных метаданных, не представленных в системных таблицах. - Размер файла вне диапазона: файл меньше
-
Этап 2: группировка BinPack и фильтрация на уровне групп
После фильтрации на уровне файлов файлы группируются по разделам, а затем внутри каждого раздела — с помощью алгоритма BinPack на основе размера файлов и
max-file-group-size-bytes. Алгоритм BinPack подбирает распределение файлов по группам для оптимизации операций перезаписи.После группировки группы файлов фильтруются по условиям уровня групп. Группы перезаписываются, если удовлетворяют хотя бы одному из следующих условий:
- Достаточно входных файлов: количество файлов в группе > 1 и количество файлов >=
min-input-files - Достаточный объём содержимого: количество файлов в группе > 1 и общий размер >
target-file-size-bytes - Слишком большой объём содержимого: общий размер группы >
max-file-group-size-bytes - Есть файлы с проблемами удалений: хотя бы у одного файла в группе слишком много файлов удалений или высокая доля удалений.
Примечание о группировке BinPack: алгоритм BinPack, используемый для группировки файлов внутри каждого раздела, — сложный алгоритм оптимизации, который невозможно точно воспроизвести с помощью SQL-запросов к системным таблицам. Он учитывает размер файлов и
max-file-group-size-bytes, подбирая распределение файлов по группам, поэтому результат может отличаться от простой группировки по разделам. Приведённые ниже SQL-запросы позволяют выявить только файлы, соответствующие условиям уровня файлов, но не позволяют точно рассчитать итоговые группы файлов для перезаписи. - Достаточно входных файлов: количество файлов в группе > 1 и количество файлов >=
Примеры стратегий запросов:
-
Запрос 1: определение файлов, соответствующих условиям уровня файлов
Этот запрос определяет файлы, соответствующие условиям уровня файлов (по размеру), которые будут рассматриваться для перезаписи:
-- Set parameters (adjust according to your rewrite parameters)
SET @min_file_size_bytes = 16 * 1024 * 1024; -- 16 MB (default: target-file-size-bytes * 0.75)
SET @max_file_size_bytes = 768 * 1024 * 1024; -- 768 MB (default: target-file-size-bytes * 1.8)
SELECT
file_path,
`partition`,
file_size_in_bytes / 1024.0 / 1024.0 AS file_size_mb,
record_count,
CASE
WHEN file_size_in_bytes < @min_file_size_bytes THEN 'Too small'
WHEN file_size_in_bytes > @max_file_size_bytes THEN 'Too large'
END AS size_issue
FROM iceberg_table$data_files
WHERE file_size_in_bytes < @min_file_size_bytes
OR file_size_in_bytes > @max_file_size_bytes
ORDER BY `partition`, file_size_in_bytes DESC;Пример вывода:
+----------------------------------------------------------------------------------------+---------------------------+-------------+--------------+------------+
| file_path | partition | file_size_mb | record_count | size_issue |
+----------------------------------------------------------------------------------------+---------------------------+-------------+--------------+------------+
| s3a://bucket/path/to/table/data/date_col=2024-01-01/00000-0-00000-00000-0.parquet | {"date_col":"2024-01-01"} | 0.00215 | 5 | Too small |
| s3a://bucket/path/to/table/data/date_col=2024-01-01/00001-0-00001-00001-0.parquet | {"date_col":"2024-01-01"} | 0.00198 | 5 | Too small |
| s3a://bucket/path/to/table/data/date_col=2024-01-02/00002-0-00002-00002-0.parquet | {"date_col":"2024-01-02"} | 0.00231 | 5 | Too small |
| s3a://bucket/path/to/table/data/date_col=2024-01-02/00003-0-00003-00003-0.parquet | {"date_col":"2024-01-02"} | 850.23456 | 1250000 | Too large |
| s3a://bucket/path/to/table/data/date_col=2024-01-03/00004-0-00004-00004-0.parquet | {"date_col":"2024-01-03"} | 0.00245 | 5 | Too small |
+----------------------------------------------------------------------------------------+---------------------------+-------------+--------------+------------+
5 rows in setПримечание: этот запрос позволяет определить только файлы, соответствующие условиям уровня файлов (по размеру). Фактические группы файлов для перезаписи зависят от алгоритма группировки BinPack, который нельзя точно воспроизвести с помощью SQL-запросов. Файлы, найденные этим запросом, могут быть сгруппированы алгоритмом BinPack иначе, а некоторые группы могут быть исключены по условиям уровня групп.
-
Запрос 2: общая сводная статистика
Этот запрос предоставляет общую статистику по файлам, соответствующим условиям уровня файлов:
-- Set parameters (adjust according to your rewrite parameters)
SET @min_file_size_bytes = 16 * 1024 * 1024;
SET @max_file_size_bytes = 768 * 1024 * 1024;
WITH file_analysis AS (
SELECT
`partition`,
file_path,
file_size_in_bytes,
record_count,
(file_size_in_bytes < @min_file_size_bytes OR file_size_in_bytes > @max_file_size_bytes) AS meets_file_level_conditions
FROM iceberg_table$data_files
)
SELECT
'Total files' AS metric,
COUNT(*) AS value
FROM file_analysis
UNION ALL
SELECT
'Files meeting file-level conditions',
SUM(CASE WHEN meets_file_level_conditions THEN 1 ELSE 0 END)
FROM file_analysis
UNION ALL
SELECT
'Total size (GB)',
ROUND(SUM(file_size_in_bytes) / 1024.0 / 1024.0 / 1024.0, 2)
FROM file_analysis
UNION ALL
SELECT
'Size meeting file-level conditions (GB)',
ROUND(SUM(CASE WHEN meets_file_level_conditions THEN file_size_in_bytes ELSE 0 END) / 1024.0 / 1024.0 / 1024.0, 2)
FROM file_analysis
UNION ALL
SELECT
'Percentage meeting file-level conditions (%)',
ROUND(SUM(CASE WHEN meets_file_level_conditions THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2)
FROM file_analysis;Пример вывода:
+----------------------------------------------+--------+
| metric | value |
+----------------------------------------------+--------+
| Total files | 15.00 |
| Total size (GB) | 2.45 |
| Files meeting file-level conditions | 12.00 |
| Size meeting file-level conditions (GB) | 1.85 |
| Percentage meeting file-level conditions (%) | 80.00 |
+----------------------------------------------+--------+
5 rows in setПримечания:
- Замените
iceberg_tableв примере фактическим именем таблицы - Скорректируйте значения параметров (
@min_file_size_bytes,@max_file_size_bytes) в соответствии с фактическими параметрами перезаписи - Приведённые выше значения по умолчанию соответствуют стандартным параметрам перезаписи (min-file-size-bytes = target-file-size-bytes * 0.75, max-file-size-bytes = target-file-size-bytes * 1.8)
- Замените
-
Просмотр связей между снимками и ветвями:
SELECT
refs_data.snapshot_id,
snapshots.committed_at,
snapshots.operation,
ARRAY_SORT(refs_data.refs)
FROM (
SELECT
snapshot_id,
ARRAY_AGG(CONCAT(type, ':', name)) AS refs
FROM
iceberg_table$refs
GROUP BY
snapshot_id
) AS refs_data
JOIN (
SELECT
snapshot_id,
committed_at,
operation
FROM
iceberg_table$snapshots
) AS snapshots
ON refs_data.snapshot_id = snapshots.snapshot_id
ORDER BY
snapshots.committed_at;
+---------------------+----------------------------+-----------+-------------------------------------+
| snapshot_id | committed_at | operation | ARRAY_SORT(refs_data.refs) |
+---------------------+----------------------------+-----------+-------------------------------------+
| 8272911997874079853 | 2025-07-10 15:27:07.177000 | append | ["BRANCH:b1", "TAG:t1"] |
| 1325777059626757917 | 2025-07-10 15:27:07.530000 | append | ["BRANCH:b2", "TAG:t2"] |
| 76492482642020578 | 2025-07-10 15:27:07.865000 | append | ["BRANCH:b3", "TAG:t3"] |
| 1788715857849070138 | 2025-07-12 04:15:19.626000 | append | ["BRANCH:main", "TAG:t4", "TAG:t5"] |
+---------------------+----------------------------+-----------+-------------------------------------+