在专用 Exadata 基础结构上使用 Autonomous Database 查询 Apache Iceberg 表

Autonomous Database 支持查询 Apache Iceberg 表。

注意:

Oracle Database 19c(从版本 19.28 开始)和 Oracle Database 23ai(从版本 23.9 开始)支持查询 Apache Iceberg 表。

支持的配置

支持以下特定配置:

限制

  • 分区的 Iceberg 表

    Oracle 不支持 Iceberg 分区表。

  • Iceberg 表的行级更新

    Oracle 不支持对 Iceberg 表更新进行合并读取。在 Iceberg 元数据中遇到已删除文件的查询将失败。有关读取合并的更多信息,请参见 Enum RowLevelOperationMode

  • 方案进化

    Oracle 外部表的方案是固定的,反映了创建外部表时的 Iceberg 方案版本。如果 Iceberg 元数据与用于创建 Iceberg 表的元数据指向不同的方案版本,则查询将失败。如果创建外部表后 Iceberg 方案发生了更改,则建议重新创建外部表。

与查询 Apache Iceberg 表相关的概念

了解以下概念有助于查询 Apache Iceberg 表。

Iceberg 目录

Iceberg 目录是一项服务,用于管理表元数据,例如表快照、表方案和分区信息。要查询 Iceberg 表的最新快照,查询引擎必须首先访问目录并获取最新的元数据文件的位置。已经有许多可用的目录实施,包括 AWS Glue、Hive、Nessie 和 Hadoop。Autonomous Database 支持 AWS Glue 目录和 Spark 使用的 HadoopCatalog 实施。

有关更多信息,请参见 Optimistic Concurrency

元数据的文件

元数据文件是 JSON 文档,用于跟踪表快照、分区方案和方案信息。元数据文件是清单列表和清单文件的分层结构的入口点。清单跟踪表的数据文件以及包括分区和列统计信息在内的信息。有关更多信息,请参见 Iceberg Table Specification

事务处理

Iceberg 支持使用“写时复制”或“读时合并”对表进行行级更新。写入时复制会生成反映已更新行的新数据文件,而读取时合并会生成新的“删除文件”,这些文件在读取期间必须与数据文件合并。Oracle 支持写时复制。如果遇到删除文件,对冰山表的查询将失败。有关更多信息,请参见 RowLevelOperationMode

方案演化

Iceberg 支持模式进化。方案更改将使用方案 ID 反映在 Iceberg 元数据中。请注意,Oracle 外部表具有固定方案,该方案由创建表时最新的方案版本确定。当查询的元数据指向与创建表时使用的方案版本不同的方案版本时,Iceberg 查询失败。有关更多信息,请参见 Schema Evolution

分区

Iceberg 支持高级分区选项,例如隐藏分区和分区演变,这些选项依赖于处理/更改表的元数据,而无需更改昂贵的数据布局。

示例:查询 Apache Iceberg 表

以下示例说明如何在 Amazon Web Services (AWS) 和 Oracle Cloud Infrastructure (OCI) 上查询 Apache Iceberg 表、使用数据目录并使用根清单文件的直接 URL。

有关为 Apache Iceberg 创建外部表的详细信息,请参见 CREATE_EXTERNAL_TABLE Procedure for Apache Iceberg

使用 Glue 数据目录查询 AWS 上的 Iceberg 表

在此示例中,我们查询 Iceberg 表 iceberg_parquet_time_dim.下面是 example_1_table.png 的说明
插图 example_1_table.png 的说明

该表属于 Glue 数据库 my-iceberg-db,并存储在文件夹 s3://my-iceberg-bucket/iceberg-loc 中。

iceberg_parquet_time_dim 的表详细信息如下所示:

下面是 example_1_details_v1.png 的说明
插图 example_1_details_v1.png 的说明

可以为 iceberg_parquet_time_dim 创建外部表,如下所示:

BEGIN
DBMS_CLOUD.CREATE_EXTERNAL_TABLE (
    table_name       => 'iceberg_parquet_time_dim',
    credential_name  => 'AWS_CRED',
    file_uri_list    => '',
    format           =>
      '{"access_protocol":
        {
         "protocol_type": "iceberg",
         "protocol_config":
          {
           "iceberg_catalog_type": "aws_glue",
           "iceberg_glue_region": "us-west-1",
           "iceberg_table_path": "my-iceberg-db.iceberg_parquet_time_dim"
          }
        }
      }'
  );
END;
/

在 protocol_config 部分中,我们指定表使用 AWS Glue 作为目录类型,并将目录的区域设置为 us-west-1

凭证 AWS_CRED 是使用 dbms_cloud.create_credential 和 AWS API 密钥创建的。胶水数据目录实例由与区域 us-west-1AWS_CRED 关联的账户 ID 确定,因为每个账户都有一个胶水数据目录区域。protocol_config 部分中的 iceberg_table_path 元素使用 $database_name.$table_name 路径来指定 Glue 表名称和数据库名称。最后,column_list field_list 参数保留为空值,因为表的方案自动派生自 Iceberg 元数据。

有关创建身份证明的详细信息,请参见 CREATE_CREDENTIAL Procedure

有关 AWS Glue 资源的信息,请参阅指定 AWS Glue 资源 ARN

使用根元数据文件的位置查询 AWS 上的 Iceberg 表

如果知道某个 Iceberg 表的元数据文件的位置,则可以在不指定目录的情况下创建外部表,如下所示:

BEGIN
DBMS_CLOUD.CREATE_EXTERNAL_TABLE (
    table_name       => 'iceberg_parquet_time_dim',
    credential_name  => 'AWS_CRED',
    file_uri_list    => 'https://my-iceberg-bucket.s3.us-west-1.amazonaws.com/iceberg-loc/metadata/00004-1758ee2d-a204-4fd9-8d52-d17e5371a5ce.metadata.json',
    format           =>'{"access_protocol":{"protocol_type":"iceberg"}}');
END;
/

我们使用 file_uri_list 参数以 AWS S3 虚拟托管式 URL 格式指定元数据文件的位置。有关此格式的信息,请参见 Methods for access an AWS S3 bucket

在此示例中,数据库直接访问元数据文件,因此无需在 format 参数中提供 protocol_config 部分。使用元数据文件位置创建外部表时,数据库将查询元数据文件引用的最新快照。创建新快照和新元数据文件的 Iceberg 表的后续更新对数据库不可见。

查询在 OCI 上使用 Hadoop 目录的 Iceberg 表

在此示例中,我们查询使用 OCI Data Flow 创建的 Iceberg 表 icebergTablePy,其中 Spark 将 HadoopCatalog 实施用于 Iceberg 目录。HadoopCatalog 使用 warehouse 目录并将 Iceberg 元数据放在此目录下的 $database_name/$table_name 子文件夹中。它还使用包含最新元数据文件版本的版本号的 version-hint.text 文件。有关 Github 上的示例,请参阅 Iceberg Support on OCI Data Flow

示例表 db.icebergTablePy 是使用 OCI 存储桶 my-iceberg-bucket 中名为 icebergwarehouse 文件夹创建的。表 icebergTablePy 的 OCI 上的存储布局如下所示:

下面是 example_3_table_v1.png 的说明
插图 example_3_table_v1.png 的说明

为表 db.icebergTablePy 创建外部表,如下所示:

BEGIN
DBMS_CLOUD.CREATE_EXTERNAL_TABLE (
    table_name       => 'iceberg_parquet_time_dim3',
    credential_name  => 'OCI_CRED',
    file_uri_list    => '',
    format           =>'{"access_protocol":{"protocol_type":"iceberg",
        "protocol_config":{"iceberg_catalog_type": "hadoop",
        "iceberg_warehouse":"https://objectstorage.uk-cardiff-1.oraclecloud.com/n/my-tenancy/b/my-iceberg-bucket/o/iceberg",
        "iceberg_table_path": "db.icebergTablePy"}}}');
END;
/

使用根元数据文件的位置查询 OCI 上的 Iceberg 表

我们可以直接使用元数据文件的 URL 来查询上一节中所述的 Iceberg 表,如下所示:

BEGIN
DBMS_CLOUD.CREATE_EXTERNAL_TABLE (
    table_name       => 'iceberg_parquet_time_dim4',
    credential_name  => 'OCI_CRED',
    file_uri_list    => 'https://objectstorage.uk-cardiff-1.oraclecloud.com/n/my-tenancy/b/my-iceberg-bucket/o/iceberg/db/icebergTablePy/metadata/v2.metadata.json',
    format           =>'{"access_protocol":{"protocol_type":"iceberg"}}'
    );
  END;
/

在此示例中,我们使用 file_uri_list 参数使用本机 OCI URI 格式指定元数据文件的 URI。使用元数据文件 URI 时,外部表始终查询存储在特定文件中的最新快照。查询无法访问生成新快照和新元数据文件的后续更新。

有关本机 OCI URI 格式的更多信息,请参阅云对象存储 URI 格式