将外部表转换为托管的 Unity Catalog 表

重要

此功能以公共预览版提供,目前仅适用于参与客户。 要参与预览,请通过 填写此表单 来申请。 此功能仅支持转换使用 HMS 和 Glue 联邦联合的外部表。

本页介绍如何使用 SET MANAGED 将外部表转换为托管表。

SET MANAGED 概述

使用此功能将 SET MANAGED 外表转换为 Azure Databricks 中的 Unity 目录托管表。 SET MANAGED 的优势如下:

  • 保留表历史记录。
  • 保留相同的表配置,包括相同的名称、设置、权限和视图。
  • 受益于 预测优化。 将表转换为托管时,预测优化设置为 INHERIT,这意味着它将从架构或目录级别继承该设置。 默认情况下,此状态当前处于禁用状态。 可以通过运行 ALTER TABLE <table_name> ENABLE PREDICTIVE OPTIMIZATION来启用已转换表的预测优化,从而将其设置为 ENABLED 而不是 INHERIT

先决条件

  • 数据格式:外表的数据格式必须为 Delta Lake。 若要为 Parquet 执行一次性转换,请参阅 “转换为 Delta Lake”。
  • 表类型:HMS 表类型必须是外部 HMS 表。 如果表是托管 HMS 表,该命令将失败。
  • 运行时:Databricks Runtime 17.3 或更高版本
  • 权限OWNERMANAGE 对表的权限,和 CREATEEXTERNAL LOCATION 的权限

Syntax

若要将 Unity Catalog 外部表转换为 Unity Catalog 托管表,请运行以下命令:

ALTER TABLE source_table SET MANAGED {MOVE | COPY}

参数

  • source_table

    Unity Catalog中的现有外部表。 外部表包含由外部目录管理的数据和元数据。 在转换之前,如果在外部目录中删除源表,则外部表也会在 Unity 目录中删除。 将表转换为托管表后,删除外部目录中的源表不会影响 Unity 目录托管表。

  • MOVE

    将表格转换为托管表,并在外部目录中禁用对该源表的访问。

    • 表转换后,通过外部目录或基于路径的访问尝试将失败。 表的所有读取者和编写器都必须使用 Unity 目录命名空间进行访问。

    • 所有读取器和编写器都必须使用基于名称的访问。 例如:

      SELECT * FROM catalog_name.schema_name.table_name;
      
    • 不支持基于路径的访问,转换表后失败。 例如:

      SELECT * FROM delta.`protocol://path/to/table`;
      
    • 外部(非 Azure Databricks)客户端必须支持读取 Unity Catalog 托管的表。 请参阅 兼容性模式

    • 使用 Access Insights 仪表板查看访问表的读取器和编写器是 Databricks Runtime 还是外部非 Azure Databricks 客户端。

    • Azure Databricks 读取器和编写器必须使用 Databricks Runtime 15.4 LTS 或更高版本。 如果读取器或编写器使用 Databricks Runtime 14.3 LTS 或更低版本,请参阅 Databricks Runtime 14.3 LTS 或更高版本上的读取器和编写器替代选项

    • 当读取器或编写器在转换期间访问表时,可能会停机。 有关详细信息,请参阅 将外部表转换为托管 Unity 目录表

    • 如果命令中断,由于转换到托管状态不完整,表可能会保留为外部表。 若要完成该命令,请再次在外部表上运行 SET MANAGED

    • 除非你手动进行了配置,否则预测优化将设置为INHERIT。 若要检查是否启用了预测优化,请参阅 检查是否启用了预测优化

    • 回滚:若要回滚表迁移并重新获得对外部目录中源表的访问权限,请 UNSET MANAGED 运行以下命令。 运行命令后,该表将成为外部表。 若要将表转换为外部表,请删除该表,并在下一次目录同步时,将其重新联接为外部表。

      ALTER TABLE catalog.schema.my_managed_table UNSET MANAGED
      

      警告

      在删除表之前,您必须运行 UNSET MANAGED 。 删除表而不首先运行 UNSET MANAGED 可能会使系统处于错误状态,并可能导致数据丢失或不一致。

    • 如果回滚, 则在转换与回滚之间提交到外部位置的更改可以根据版本进行历史追溯,但无法通过时间戳来实现。 回滚七天后,托管位置中的数据将被删除。 对于 Databricks Runtime 15.4 LTS 或更高版本中的读写者,转换后但在回滚之前的提交表历史记录可以按版本进行时间旅行,但不能按时间戳进行。

    • 在表转换完成后,您必须:

      • 重启使用外部表的任何流式处理作业(读取或写入)
      • 确保读者和写作者都使用托管表。
  • COPY

    将表转换为托管表,而无需修改或禁用对外部目录中源表的访问。

    • 在转换为托管时,源表中的数据将被复制到为托管表定义的位置,从而创建两个单独的副本:一个是新的托管表,另一个是位于外部目录中的源表。
    • 与读取和写入失败的情况不同 MOVE ,使用 COPY时,你负责正确禁用对外部目录中源表的读取和写入,并确保工作负荷已迁移到新目录。
    • 回滚:若要回滚表迁移,无需运行 UNSET MANAGED 命令,因为源表尚未在外部目录中中断。 删除此表,在下次与目录同步时将其重新联结为外表。

检查转换

您可以确认您的外部表已经转换为托管表:

DESCRIBE EXTENDED catalog_name.schema_name.table_name

如果表已转换,Typecol_name下方时会变成在MANAGED下方的data_type

已知的限制

将外表转换为托管表具有以下限制:

  • 流式处理客户端:转换后必须重启任何流式处理作业。

  • 多个云区域:如果 Unity Catalog 元存储、目录或架构的默认托管位置与要转换的外表的存储位置位于不同的云区域,则可能会产生额外的跨区域数据传输成本。 云提供商将这些费用强加于 Azure Databricks 的控制之外。 若要检查架构、目录和元存储的位置,请使用以下命令:

    -- Check schema location
    DESCRIBE SCHEMA EXTENDED catalog_name.schema_name;
    
    -- Check catalog location
    DESCRIBE CATALOG EXTENDED catalog_name;
    
    -- Check metastore location
    DESCRIBE METASTORE;
    

FAQ

是否可以在外部目录中创建表以及转换表?

是的,可以在外部目录中创建外部表或托管表。 行为取决于架构配置:

  • 对于 Glue 或 eHMS 架构,或者 对于 Unity 目录中设置了托管位置的架构:如果运行 CREATE TABLE foreign_catalog.schema.table,这将创建 Unity 目录托管表或外部表。 该表未推送或同步到外部目录。
  • 对于来自内部 Hive 元存储连接的模式:如果尝试在外部模式中创建表,它仍然会创建一个外表,并在 Hive 内部架构 hive_metastore 创建一个表。
  • 对于旧工作区 Hive 元存储:由于它是读取和写入联合的,因此如果在外部目录中创建表,它还会在内部 Hive 元存储中创建一个表。

如果我的外部表是基于 DBFS,应该怎么处理?

在转换一个由 DBFS 支持的表时,我们将当前的 DBFS 路径映射存储为外部表的云路径位置。

可以在模式或目录级别进行转换吗?

可以逐一浏览架构中的表以进行单独转换,或使用 discoverx labs 项目将整个模式或目录一次性转换。

df = (dx.from_tables("prod.*.*")
.with_sql("ALTER TABLE {full_table_name} SET MANAGED;")
.apply())