集成

Apache Hive

师成师成· 更新于 2026-09-28· 阅读 40 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Hive

Iceberg 支持通过 StorageHandler 借助 Hive 读写 Iceberg 表。

功能支持

Hive 4.0.0 及以上版本支持以下功能:

  • 创建 Iceberg 表。
  • 创建 Iceberg 恒等分区表。
  • 创建具有任意分区规范的 Iceberg 表,包括 Iceberg 支持的各种转换(transform)。
  • 基于已有表创建表(CTAS 表)。
  • 删除表。
  • 修改表同时保持 Iceberg 与 Hive 架构(schema)同步。
  • 修改分区架构(更新列)。
  • 通过指定分区转换修改分区架构。
  • 截断表/分区、删除分区。
  • 将 Avro、Parquet 或 ORC(非 ACID)格式的表迁移为 Iceberg 表。
  • 读取 Iceberg 表。
  • 读取表的架构(schema)。
  • 查询 Iceberg 元数据表。
  • 时间旅行应用。
  • 向表/分区插入数据(INSERT INTO)。
  • 向表/分区插入数据并覆盖已有数据(INSERT OVERWRITE)。
  • 针对删除、更新和合并查询的写时复制(copy-on-write)支持,以及 Iceberg V1 表的 CRUD 支持。
  • 修改表以使快照过期(expiring snapshots)。
  • 基于已有表创建表(CTLT 表)。
  • 支持通过表属性添加 Parquet 压缩类型 压缩类型。
  • 修改表元数据位置。
  • 支持表回滚。
  • 写入表时遵循已有表上的排序规则 排序规则规范。
  • 创建、写入和删除 Iceberg 分支(branch)/标签(tag)。
  • 支持通过快照 ID、时间范围、保留最近 N 个快照以及使用表属性来使快照过期。
  • 为 Iceberg 表通过快照 ID 设置当前快照。
  • 支持重命名 Iceberg 表。
  • 修改表以转换为 Iceberg 表。
  • 将提交(commit)快进(fast forwarding)、挑选(cherry-picking)到 Iceberg 分支。
  • 基于 Iceberg 标签创建分支。
  • 为 Iceberg 表通过分支/标签设置当前快照。
  • 删除 Iceberg 表的孤立文件(orphan files)。
  • 允许对 Iceberg 表进行全表合并(compaction)。
  • 支持显示 Iceberg 表的分区信息(SHOW PARTITIONS)。

警告

DML 操作仅在 Tez 执行引擎下可用。

在 Hive 中启用 Iceberg 支持

从 1.8.0 开始,Iceberg 不再发布 Hive 运行时连接器。若要集成 Hive 查询引擎(特别是 Hive 2.x 和 3.x),请使用 Iceberg 1.6.1 附带的 Hive 运行时连接器,或者使用 Hive 4.0.0 及以上版本(其已内嵌 Iceberg 集成)。

Hive 4.1.x、4.2.x

Hive 4.1.x 和 4.2.x 内置了 Iceberg 1.9.1。

Hive 4.0.x

Hive 4.0.x 内置了 Iceberg 1.4.3。

启用支持

如果 Iceberg 存储处理器不在 Hive 的类路径中,那么当为表设置了存储处理器时,Hive 将无法加载或更新 Iceberg 表的元数据。为避免在 Hive 中出现看似损坏的表,除非启用了 Hive 支持,否则 Iceberg 不会为表添加存储处理器。每当表的 Hive 引擎支持被更新(即在表属性中开启或关闭)时,存储处理器都会随之同步(添加或移除)。启用 Hive 支持有两种方式:在 Hadoop 配置中全局启用,或使用表属性按表启用。

Hadoop 配置

要为某个应用全局启用 Hive 支持,可在该应用的 Hadoop 配置中设置 iceberg.engine.hive.enabled=true。例如,在 Spark 加载的 hive-site.xml 中设置该值,将为 Spark 创建的所有表启用存储处理器。

表属性配置

另一种方式是在创建 Iceberg 表时,将属性 engine.hive.enabled 设置为 true 并添加到表属性中。以下是通过编程方式实现的示例:

Catalog catalog=...;
    Map<String, String> tableProperties=Maps.newHashMap();
    tableProperties.put(TableProperties.ENGINE_HIVE_ENABLED,"true"); // engine.hive.enabled=true
    catalog.createTable(tableId,schema,spec,tableProperties);

表级配置会覆盖全局 Hadoop 配置。

目录管理

全局 Hive 目录

HiveCatalog 集成支持 Hive 2.3.10 或 3.1.3 及更高版本。

从 Hive 引擎的角度来看,运行时环境中只存在一个全局数据目录,它在 Hadoop 配置中定义。相比之下,Iceberg 支持多种不同的数据目录类型,例如 Hive、Hadoop、AWS Glue 或自定义目录实现。Iceberg 还允许直接根据文件系统中的路径加载表,这类表不属于任何目录。用户可能希望通过 Hive 引擎读取这些跨目录和基于路径的表,以用于 join 等场景。

为支持这一需求,Hive 元存储中的表可以根据其 iceberg.catalog 属性,代表三种不同的 Iceberg 表加载方式:

  1. 如果未设置 iceberg.catalog,则使用与 Hive 环境中所配置元存储相对应的 HiveCatalog 加载该表
  2. 如果 iceberg.catalog 设置为某个目录名称(见下文),则使用自定义目录加载该表
  3. 如果 iceberg.catalog 设置为 location_based_table,则可以根据表的根位置直接加载该表

对于上述第 2 和第 3 种情况,用户可以在 Hive 元存储中创建 Iceberg 表的叠加层,从而使不同类型的表能够在同一 Hive 环境中协同工作。更多详情请参阅 CREATE EXTERNAL TABLE 和 CREATE TABLE。

自定义 Iceberg 目录

要全局注册不同的目录,请设置以下 Hadoop 配置:

配置键说明
iceberg.catalog.<catalog_name>.type目录类型:hive、hadoop,如果使用自定义目录则可不设置
iceberg.catalog.<catalog_name>.catalog-impl目录实现,当 type 为空时必须设置,不能为 null
iceberg.catalog.<catalog_name>.<key>该目录的任意配置键值对

以下是一些使用 Hive CLI 的示例:

注册一个名为 another_hive 的 HiveCatalog:

SET iceberg.catalog.another_hive.type=hive;
SET iceberg.catalog.another_hive.uri=thrift://example.com:9083;
SET iceberg.catalog.another_hive.clients=10;
SET iceberg.catalog.another_hive.warehouse=hdfs://example.com:8020/warehouse;

注册一个名为 hadoop 的 HadoopCatalog:

SET iceberg.catalog.hadoop.type=hadoop;
SET iceberg.catalog.hadoop.warehouse=hdfs://example.com:8020/warehouse;

注册名为 glue 的 AWS GlueCatalog:

SET iceberg.catalog.glue.type=glue;
SET iceberg.catalog.glue.warehouse=s3://my-bucket/my/key/prefix;
SET iceberg.catalog.glue.lock.table=myGlueLockTable;

DDL 命令

CREATE TABLE

非分区表

当你按如下方式指定存储处理程序时,Hive 的 CREATE EXTERNAL TABLE 命令将创建一个 Iceberg 表:

CREATE EXTERNAL TABLE x (i int) STORED BY ICEBERG;

如果你想使用 CREATE TABLE 创建外部表,请在集群上配置 MetaStoreMetadataTransformer,这样 CREATE TABLE 命令就会被转换为创建外部表的命令。例如:

CREATE TABLE x (i int) STORED BY ICEBERG;

你可以在创建表时指定默认文件格式(Avro、Parquet 或 ORC)。默认值为 Parquet:

CREATE TABLE x (i int) STORED BY ICEBERG STORED AS ORC;

分区表

你可以使用一条创建非 Iceberg 表时同样熟悉的命令来创建 Iceberg 分区表:

CREATE TABLE x (i int) PARTITIONED BY (j int) STORED BY ICEBERG;

信息

生成的表不会在 HMS 中创建分区,而是将分区数据转换为 Iceberg 的 identity 分区。

使用 DESCRIBE 命令获取 Iceberg identity 分区的相关信息:

DESCRIBE x;

结果为:

col_namedata_typecomment
iint
jint
NULLNULL
# Partition Transform InformationNULLNULL
# col_nametransform_typeNULL
jIDENTITYNULL

你可以使用以下 Iceberg 分区规范语法创建 Iceberg 分区(仅从 Hive 4.0.0 起支持):

CREATE TABLE x (i int, ts timestamp) PARTITIONED BY SPEC (month(ts), bucket(2, i)) STORED BY ICEBERG;
DESCRIBE x;

结果为:

col_namedata_typecomment
iint
tstimestamp
NULLNULL
# Partition Transform InformationNULLNULL
# col_nametransform_typeNULL
tsMONTHNULL
iBUCKET[2]NULL

Hive 支持的转换与 Spark 相同:

  • years(ts):按年分区

  • months(ts):按月分区

  • days(ts) 或 date(ts):等同于 dateint 分区

  • hours(ts) 或 date_hour(ts):等同于 dateint 和小时分区

  • bucket(N, col):按哈希值对 N 取模后的桶分区

  • truncate(L, col):按截断到 L 的值分区

    • 字符串截断到给定长度
    • 整数和长整数截断到区间:truncate(10, i) 会生成 0、10、20、30 等分区

:::info
最终的表不会在 HMS 中创建分区,而是将分区数据转换为 Iceberg 分区。
:::

CREATE TABLE AS SELECT

CREATE TABLE AS SELECT 操作与 Hive 原生操作类似,但有一个重要的区别:Iceberg 表和对应的 Hive 表在查询执行开始时就会创建,数据则在查询完成时插入 / 提交。因此在短暂的时间内,表虽然已经存在,但其中不含任何数据。

CREATE TABLE target PARTITIONED BY SPEC (year(year_field), identity_field) STORED BY ICEBERG AS
    SELECT * FROM source;

CREATE TABLE LIKE TABLE

CREATE TABLE target LIKE source STORED BY ICEBERG;

在现有 Iceberg 表之上创建外部表

CREATE EXTENAL TABLE 命令用于在现有 Iceberg 表"之上"覆盖一个 Hive 表。Iceberg 表可以通过 Catalog 或 Tables 接口的实现来创建,Hive 需要进行相应配置,以便对这些不同类型的表进行操作。

Hive catalog 表

如前所述,由 HiveCatalog 创建且启用了 Hive 引擎特性的表可被 Hive 引擎直接识别,因此无需创建覆盖表。

自定义 catalog 表

对于已注册 catalog 中的表,请在语句中通过表属性 iceberg.catalog 指定 catalog 名称。例如,下面的 SQL 为一个名为 hadoop_cat、类型为 hadoop 的 catalog 中的表创建覆盖表:

SET
iceberg.catalog.hadoop_cat.type=hadoop;
SET
iceberg.catalog.hadoop_cat.warehouse=hdfs://example.com:8020/hadoop_cat;

CREATE
EXTERNAL TABLE database_a.table_a
STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
TBLPROPERTIES ('iceberg.catalog'='hadoop_cat');

当表属性和全局 Hadoop 配置中都缺少 iceberg.catalog 时,将默认使用 HiveCatalog。

基于路径的 Hadoop 表

使用 HadoopTables 创建的 Iceberg 表完全存储在 HDFS 等文件系统的某个目录中。这类表被视为没有目录(catalog)。为表明这一点,请将 iceberg.catalog 属性设置为 location_based_table。例如:

CREATE
EXTERNAL TABLE table_a
STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
LOCATION 'hdfs://some_bucket/some_path/table_a'
TBLPROPERTIES ('iceberg.catalog'='location_based_table');

在现有 Iceberg 表之上创建表

你也可以创建一个由自定义 catalog 管理的新表。例如,以下代码在一个自定义 Hadoop catalog 中创建表:

SET
iceberg.catalog.hadoop_cat.type=hadoop;
SET
iceberg.catalog.hadoop_cat.warehouse=hdfs://example.com:8020/hadoop_cat;

CREATE TABLE database_a.table_a
(
    id   bigint,
    name string
) PARTITIONED BY (
  dept string
) STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
TBLPROPERTIES ('iceberg.catalog'='hadoop_cat');

危险

如果要创建的表在自定义目录中已存在,这将创建一个受管理的覆盖表(managed overlay table)。这意味着从技术上讲,创建覆盖表时可以省略 EXTERNAL 关键字。然而,不建议这样做,因为创建受管理的覆盖表可能会对共享数据文件造成风险:一旦 Hive 侧意外执行 drop table 命令,就会无意中删除该表中的所有数据。

ALTER TABLE

表属性

对于 HiveCatalog 表,Iceberg 表属性与存储在 HMS 中的 Hive 表属性会保持同步。

信息

重要提示:此功能不适用于其他 Catalog 实现。

ALTER TABLE t SET TBLPROPERTIES('...'='...');

模式演进

Hive 表的模式与 Iceberg 表保持同步。如果外部来源(Impala/Spark/Java API 等)修改了模式,Hive 表会立即反映这些变化。您可以使用 Hive 命令修改表的模式:

  • 重命名表

    ALTER TABLE orders RENAME TO renamed_orders;
  • 添加列

    ALTER TABLE orders ADD COLUMNS (nickname string);
  • 重命名列

    ALTER TABLE orders CHANGE COLUMN item fruit string;
  • 调整列顺序

    ALTER TABLE orders CHANGE COLUMN quantity quantity int AFTER price;
  • 修改列类型——仅当 Iceberg 将该列类型变更定义为安全操作时才允许

    ALTER TABLE orders CHANGE COLUMN price price long;
  • 使用 REPLACE COLUMN 删除旧列以移除该列

    ALTER TABLE orders REPLACE COLUMNS (remaining string);

信息

请注意,删除列是 REPLACE COLUMNS 唯一的用途;也就是说,如果指定的列顺序不正确,将会抛出错误,提示这一限制。

分区演进

使用以下命令更改分区模式:

  • 将分区模式更改为新的标识分区:

    ALTER TABLE default.customers SET PARTITION SPEC (last_name);
  • 或者,提供一个分区规范:

    ALTER TABLE order SET PARTITION SPEC (month(ts));

表迁移

你可以使用以下命令将 Avro / Parquet / ORC 外部表迁移为 Iceberg 表:

ALTER TABLE t SET TBLPROPERTIES ('storage_handler'='org.apache.iceberg.mr.hive.HiveIcebergStorageHandler');

在迁移过程中,数据文件不会被修改,只会创建相应的 Iceberg 元数据文件。迁移完成后,即可将该表作为普通的 Iceberg 表来使用。

删除分区

你可以使用以下命令,根据单个/多个分区规范来删除分区:

ALTER TABLE orders DROP PARTITION (buy_date == '2023-01-01', market_price > 1000), PARTITION (buy_date == '2024-01-01', market_price <= 2000);

分区规范仅支持恒等(identity)分区列,不支持分区规范中的转换(transform)分区列。

分支与标签

ALTER TABLE ... CREATE BRANCH

可以通过 CREATE BRANCH 语句创建分支,并支持以下选项:

  • 使用默认属性创建分支。
  • 在指定的快照 ID 处创建分支。
  • 基于系统时间创建分支。
  • 创建具有指定快照保留数量的分支。
  • 基于指定的标签创建分支。
-- CREATE branch1 with default properties.
ALTER TABLE test CREATE BRANCH branch1;

-- CREATE branch1 at a specific snapshot ID.
ALTER TABLE test CREATE BRANCH branch1 FOR SYSTEM_VERSION AS OF 3369973735913135680;

-- CREATE branch1 using system time.
ALTER TABLE test CREATE BRANCH branch1 FOR SYSTEM_TIME AS OF '2023-09-16 09:46:38.939 Etc/UTC';

-- CREATE branch1 with a specified number of snapshot retentions.
ALTER TABLE test CREATE BRANCH branch1 FOR SYSTEM_VERSION AS OF 3369973735913135680 WITH SNAPSHOT RETENTION 5 SNAPSHOTS;

-- CREATE branch1 using a specific tag.
ALTER TABLE test CREATE BRANCH branch1 FOR TAG AS OF tag1;

ALTER TABLE ... CREATE TAG

可以通过 CREATE TAG 语句创建标签,并支持以下选项:

  • 使用默认属性创建标签。
  • 在指定的快照 ID 处创建标签。
  • 使用系统时间创建标签。
-- CREATE tag1 with default properties.
ALTER TABLE test CREATE TAG tag1;

-- CREATE tag1 at a specific snapshot ID.
ALTER TABLE test CREATE TAG tag1 FOR SYSTEM_VERSION AS OF 3369973735913135680;

-- CREATE tag1 using system time.
ALTER TABLE test CREATE TAG tag1 FOR SYSTEM_TIME AS OF '2023-09-16 09:46:38.939 Etc/UTC';

ALTER TABLE ... DROP BRANCH

可以通过 DROP BRANCH 语句删除分支,支持以下选项:

  • 使用 IF EXISTS,当分支不存在时不报错
-- DROP branch1
ALTER TABLE test DROP BRANCH branch1;

-- DROP branch1 IF EXISTS
ALTER TABLE test DROP BRANCH IF EXISTS branch1;

ALTER TABLE ... DROP TAG

可以通过 DROP TAG 语句删除标签,支持以下选项:

  • 使用 IF EXISTS,当标签不存在时不报错
-- DROP tag1
ALTER TABLE test DROP TAG tag1;

-- DROP tag1 IF EXISTS
ALTER TABLE test DROP TAG IF EXISTS tag1;

ALTER TABLE ... EXECUTE FAST-FORWARD

作为另一分支祖先的 Iceberg 分支,可以快进(fast-forward)到另一个分支的状态。

-- This fast-forwards the branch1 to the state of main branch of the Iceberg table.
ALTER table test EXECUTE FAST-FORWARD 'branch1' 'main';

-- This fast-forwards the branch1 to the state of branch2.
ALTER table test EXECUTE FAST-FORWARD 'branch1' 'branch2';

ALTER TABLE ... EXECUTE CHERRY-PICK

Cherry-pick(拣选)一个快照需要该快照的 ID。目前,仅支持在 Iceberg 表的主分支上对快照进行 cherry-pick 操作。

 ALTER table test EXECUTE CHERRY-PICK 8602659039622823857;

TRUNCATE TABLE

以下命令会清空 Iceberg 表:

TRUNCATE TABLE t;

TRUNCATE TABLE ... PARTITION

以下命令用于截断 Iceberg 表中的分区:

TRUNCATE TABLE orders PARTITION (customer_id = 1, first_name = 'John');

分区规范仅支持恒等(identity)分区列,不支持分区规范中的转换(transform)分区列。

删除表

可以使用 DROP TABLE 命令删除表:

DROP TABLE [IF EXISTS] table_name [PURGE];

METADATA LOCATION

元数据位置(快照位置)只有在新路径包含完全相同的元数据 JSON 时才能被修改。此操作只能在将表迁移到 Iceberg 之后进行,这两个操作无法在同一步骤中完成。

ALTER TABLE t set TBLPROPERTIES ('metadata_location'='<path>/hivemetadata/00003-a1ada2b8-fc86-4b5b-8c91-400b6b46d0f2.metadata.json');

DML 命令

SELECT

在 Hive 中,SELECT 语句对 Iceberg 表的使用方式完全相同。在编译和执行阶段,你可以看到 Iceberg 相比 Hive 的优势:

  • 无需列举文件系统——这一点在 S3 等对象存储上尤为重要
  • 无需从元数据存储中列举分区
  • 高级分区过滤——当分区键可以通过计算得出时,查询中无需显式包含分区键
  • 能够处理比普通 Hive 表更多的分区数量

以下是 Iceberg Hive 读取支持的功能亮点:

  1. 谓词下推:已实现 Hive SQL WHERE 子句的下推,使这些过滤条件既能在 Iceberg 的 TableScan 层面使用,也能被 Parquet 和 ORC 读取器利用。
  2. 列裁剪:Hive SQL SELECT 子句中的列会被下推到 Iceberg 读取器,以减少读取的列数。
  3. Hive 查询引擎:在 Hive 4.x 中,支持 Tez 查询执行引擎。

部分高级/较少使用的优化尚未在 Iceberg 表上实现,因此你需要检查各自的查询。此外,当前元数据存储(MetaStore)中存储的统计信息会被用于查询规划,这是我们计划在未来改进的地方。

Hive 4 支持对分支(branch)执行 select 操作,其行为与表级别的 select 操作类似。不过,分支必须按以下方式提供——

-- Branches should be specified as <database_name>.<table_name>.branch_<branch_name>
SELECT * FROM default.test.branch_branch1;

INSERT INTO

Hive 支持标准的单表 INSERT INTO 操作:

INSERT INTO table_a
VALUES ('a', 1);
INSERT INTO table_a
SELECT...;

多表插入(multi-table insert)同样受支持,但它并非原子操作。提交会逐表进行。在提交过程中可能看到部分变更,失败也可能导致部分变更被提交。单个表内的变更仍然是原子的。

在分支上执行插入操作,其行为与表级别的 select 操作类似。不过,分支必须按如下方式提供——

-- Branches should be specified as <database_name>.<table_name>.branch_<branch_name>
INSERT INTO default.test.branch_branch1
VALUES ('a', 1);
INSERT INTO default.test.branch_branch1
SELECT...;

以下是 Hive SQL 中一次插入多个表示例:

FROM customers
   INSERT INTO target1 SELECT customer_id, first_name
   INSERT INTO target2 SELECT last_name, customer_id;

INSERT INTO ... PARTITION

Hive 4 支持分区级别的 INSERT INTO 操作:

INSERT INTO table_a PARTITION (customer_id = 1, first_name = 'John')
VALUES (1,2);
INSERT INTO table_a PARTITION (customer_id = 1, first_name = 'John')
SELECT...;

分区规范仅支持恒等(identity)分区列,不支持分区规范中的转换(transform)分区列。

INSERT OVERWRITE

INSERT OVERWRITE 可以用查询结果替换表中的数据。对于 Iceberg 表,覆盖是原子操作。对于非分区表,表中的内容总是会被全部清除;对于分区表,则只会替换 SELECT 查询产生行所在的分区。

INSERT OVERWRITE TABLE target SELECT * FROM source;

INSERT OVERWRITE ... PARTITION

Hive 4 支持分区级别的 INSERT OVERWRITE 操作:

INSERT OVERWRITE TABLE target PARTITION (customer_id = 1, first_name = 'John') SELECT * FROM source;

分区规范仅支持恒等(identity)分区列,不支持分区规范中的转换(transform)分区列。

DELETE FROM

Hive 4 支持 DELETE FROM 查询,用于删除表中的数据。

删除查询接受一个过滤条件,用于匹配要删除的行。

DELETE FROM target WHERE id > 1 AND id < 10;

DELETE FROM target WHERE id IN (SELECT id FROM source);

DELETE FROM target WHERE id IN (SELECT min(customer_id) FROM source);

如果删除过滤条件匹配到表的整个分区,Iceberg 将执行仅元数据的删除操作。如果过滤条件匹配的是表中的单个行,Iceberg 则只会重写受影响的数据文件。

UPDATE

Hive 4 支持 UPDATE 查询,可接受一个过滤条件来匹配要更新的行。

UPDATE target SET first_name = 'Raj' WHERE id > 1 AND id < 10;

UPDATE target SET first_name = 'Raj' WHERE id IN (SELECT id FROM source);

UPDATE target SET first_name = 'Raj' WHERE id IN (SELECT min(customer_id) FROM source);

欲了解基于传入数据的更复杂行级更新,请参阅 MERGE INTO 一节。

MERGE INTO

Hive 4 新增了对 MERGE INTO 查询的支持,可用于表达行级更新。

MERGE INTO 使用来自另一个查询(称为源)的一组更新来更新某个表(称为目标表)。目标表中某一行的更新方式通过 ON 子句确定,该子句类似于连接条件。

MERGE INTO target AS t        -- a target table
USING source s                -- the source updates
ON t.id = s.id                -- condition to find updates for target rows
WHEN ...                      -- updates

目标表中行的更新使用 WHEN MATCHED ... THEN ... 列出。可以添加多个 MATCHED 子句,并通过条件确定每个匹配何时生效。系统会使用第一个匹配的表达式。

WHEN MATCHED AND s.op = 'delete' THEN DELETE
WHEN MATCHED AND t.count IS NULL AND s.op = 'increment' THEN UPDATE SET t.count = 0
WHEN MATCHED AND s.op = 'increment' THEN UPDATE SET t.count = t.count + 1

无法匹配的源行(更新)可以被插入:

WHEN NOT MATCHED THEN INSERT VALUES (s.a, s.b, s.c)

源数据中只允许一条记录更新目标表的任意给定行,否则将抛出错误。

查询元数据表

Hive 支持查询 Iceberg 元数据表。这些表可以像普通 Hive 表一样使用,因此可以使用投影 / 连接 / 过滤等操作。要引用元数据表,应使用表的完整名称,例如:...

目前在 Hive 中可用的元数据表如下:

  • all_data_files
  • all_delete_files
  • all_entries
  • all_files
  • all_manifests
  • data_files
  • delete_files
  • entries
  • files
  • history
  • manifests
  • metadata_log_entries
  • partitions
  • refs
  • snapshots
SELECT * FROM default.table_a.files;

时间旅行(TIMETRAVEL)

Hive 支持基于快照 ID 和基于时间的时间旅行查询。对于这些视图,可以使用投影 / 连接 / 过滤等操作。该功能可通过以下语法使用:

SELECT * FROM table_a FOR SYSTEM_TIME AS OF '2021-08-09 10:35:57';
SELECT * FROM table_a FOR SYSTEM_VERSION AS OF 1234567;

你可以使用 Hive 中的 ALTER TABLE 查询来过期 Iceberg 表的快照。应定期过期快照,以删除不再需要的数据文件,并减小表元数据的大小。

每次通过 Hive 对 Iceberg 表进行写入,都会创建该表的一个新快照(即版本)。快照可用于时间旅行查询,也可以将表回滚到任意有效快照。快照会不断累积,直到通过 expire_snapshots 操作过期。输入以下查询,以过期时间戳为 2021-12-09 05:39:18.689000000 的快照:

ALTER TABLE test_table EXECUTE expire_snapshots('2021-12-09 05:39:18.689000000');

DELETE ORPHAN-FILES

用于删除未被 Iceberg 表的任何元数据文件所引用的文件,这些文件因此可以被视为"孤立文件"。该功能可通过以下语法使用:

ALTER TABLE table_a EXECUTE DELETE ORPHAN-FILES;
ALTER TABLE table_a EXECUTE DELETE ORPHAN-FILES OLDER THAN ('2021-12-09 05:39:18.689000000');

类型兼容性

Hive 与 Iceberg 支持的类型集合并不相同。Iceberg 可以自动执行类型转换,但并非支持所有组合,因此在设计表中各列的类型之前,你可能需要先了解 Iceberg 中的类型转换机制。你可以通过 Hadoop 配置启用自动转换(默认未启用):

配置项默认值说明
iceberg.mr.schema.auto.conversionfalseHive 是否应执行类型自动转换

Hive 类型到 Iceberg 类型

下表描述了 Hive 类型如何转换为 Iceberg 类型。该转换同时适用于通过 Hive 创建 Iceberg 表和向 Iceberg 表写入数据这两种场景。

HiveIceberg说明
booleanboolean
shortinteger自动转换
byteinteger自动转换
integerinteger
longlong
floatfloat
doubledouble
datedate
timestamptimestamp without timezone
timestamplocaltztimestamp with timezone仅 Hive 3
interval_year_month不支持
interval_day_time不支持
charstring自动转换
varcharstring自动转换
stringstring
binarybinary
decimaldecimal
structstruct
listlist
mapmap
union不支持

表回滚

将 Iceberg 表的数据回滚到某个较早表快照时的状态。

回滚到特定时间戳之前的最后一个快照

ALTER TABLE ice_t EXECUTE ROLLBACK('2022-05-12 00:00:00')

回滚到指定快照 ID

ALTER TABLE ice_t EXECUTE ROLLBACK(1111);

压缩

Hive 4 支持使用以下命令对 Iceberg 表进行全表压缩:

-- Using the ALTER TABLE ... COMPACT syntax
ALTER TABLE t COMPACT 'major';

-- Using the OPTIMIZE TABLE ... REWRITE DATA syntax
OPTIMIZE TABLE t REWRITE DATA;

这两种语法的效果相同,都会对 Iceberg 表执行完全表压缩。

评论

登录后参与评论

正在加载评论…