本页介绍如何使用 ALTER TABLE ... SET MANAGED 命令将外部表转换为 Azure Databricks 中的 Unity 目录托管表。
SET MANAGED 概述
使用此功能将 SET MANAGED 外部表转换为 Azure Databricks 中的 Unity 目录托管表。
SET MANAGED 的优势如下:
- 最大程度地减少读取器和写入器的停机时间。
- 在转换期间处理并发写入。
- 保留表历史记录。
- 保留相同的表配置,包括相同的名称、设置、权限和视图。
- 能够将转换后的管理表回滚到外部表。
先决条件
若要使用表转换功能,必须满足以下先决条件:
外部表的所有读取器和编写器都必须使用基于名称的访问。 例如:
SELECT * FROM catalog_name.schema_name.table_name;不支持基于路径的访问,转换表后将失败。 例如:
SELECT * FROM delta.`protocol://path/to/table`;必须使用 Databricks Runtime 17.0 或更高版本才能使用
SET MANAGED或UNSET MANAGED。若要转换已启用 Iceberg 读取的 Unity 目录表(UniForm),必须使用 Databricks Runtime 17.2 或更高版本才能使用
TRUNCATE UNIFORM HISTORY。Azure Databricks 读取器和编写器必须使用 Databricks Runtime 15.4 LTS 或更高版本。 如果读取器或编写器使用 14.3 LTS 或更低版本,请参阅 Databricks Runtime 14.3 LTS 或更高版本上的读取器和编写器的替代选项。
如果表具有
SET MANAGED、DELTA_TRUNCATED_TRANSACTION_LOG和minReaderVersion=2,命令minWriterVersion=7会失败,并出现tableFeatures={..., columnMapping}错误。 可以检查表是否使用这些DESCRIBE DETAIL属性。外部(非 Databricks)客户端必须支持对 Unity 目录托管表的读取。 请参阅 Delta 客户端读取表。
- 使用 Access Insights 仪表板查看访问表的读取程序和写入程序是 Databricks Runtime 还是外部非 Databricks 系统。
重要
若要避免冲突,请取消在表上运行的任何现有 OPTIMIZE 命令作业(液体群集、压缩 ZORDER),并且不要在将外部表转换为托管表时计划任何作业。
从外部转换为管理表
重要
该 SET MANAGED 命令在 Databricks Runtime 17.0 或更高版本中可用。
该 TRUNCATE UNIFORM HISTORY 命令在 Databricks Runtime 17.2 或更高版本中可用。
运行以下命令之一,将 Unity 目录外部表转换为 Unity 目录托管表。
对于未启用 Apache Iceberg 读取(UniForm)的 Unity 目录外部表:
ALTER TABLE catalog.schema.my_external_table SET MANAGED;转换后,可以在托管表上启用 Iceberg 读取,而无需兼容性问题。
对于已启用 Iceberg 读取(UniForm)的 Unity 目录外部表:
ALTER TABLE catalog.schema.my_external_table SET MANAGED TRUNCATE UNIFORM HISTORY;在这种情况下,使用
TRUNCATE UNIFORM HISTORY以保持表格性能和兼容性的最佳状态。TRUNCATE UNIFORM HISTORY仅截断 UniForm Iceberg 历史记录,并且不会删除 Delta 历史记录。 此命令在截断后会导致 Iceberg 出现短时间的读取和写入停机,但这消除了在转换前后需要手动禁用和重新启用 Iceberg 读取的必要性。
如果您的命令在复制数据时中断,您可以重启操作,它将从中断的位置继续。
警告
Databricks 建议不要在同一个表中并发运行多个 SET MANAGED 命令,这可能会导致表状态不一致。
在表转换完成后,您必须:
- 在您的数据表中启用 UniForm(如果之前已禁用)。
- 使用外部表重新启动任何流式处理作业(读取或写入)。
- 确保读者和写作者都使用托管表。
启用预测优化后,Azure Databricks 会在 14 天后自动删除 Unity 目录外部位置中的数据。 如果预测优化已禁用,则可以在新转换的托管表上运行VACUUM(需要 Databricks Runtime 17.0)。 这指示 Azure Databricks 在 14 天后清理原始 Unity 目录外部表位置中的数据:
VACUUM my_converted_table
注释
在某些情况下,即使启用了预测优化,Unity 目录外部位置中的数据在 14 天后也可能不会删除。 例如,如果你的 Unity 目录托管表不经常使用,或者非常小,则可能不会进行自动删除。 在这些情况下,在 14 天后,在新转换的托管表上手动运行 VACUUM(需要 Databricks Runtime 17.0)以删除旧数据。
Azure Databricks 仅删除外部位置中的数据。 将保留 Delta 事务日志以及对 Unity Catalog 中表的引用。
检查转换
您可以确认您的外部表已经转换为托管表:
DESCRIBE EXTENDED catalog_name.schema_name.table_name
如果表已转换,Type在col_name下方时会变成在MANAGED下方的data_type。
替代选项,适用于 Databricks Runtime 14.3 LTS 或更低版本的读取器和编写器
Databricks 建议将所有读取器和编写器升级到 Databricks Runtime 15.4 LTS 或更高版本,以利用 SET MANAGED 该命令,包括保留表历史记录的功能。
如果您具有 Databricks Runtime 14.3 或更低版本的读取器或编写器,仍然可以使用 SET MANAGED 命令。 但是,转换为托管表后,无法按时间戳访问历史提交。 只能按版本进行操作。 如果在 14 天的时间窗口内回滚到外部表,转换之前的历史提交的时间旅行功能将被重新启用。
在所有情况下(无论 DBR 版本是什么),按时间戳回滚到 UC 外部对在转换完成后与尝试回滚之前提交到已转换的 UC 托管表的任何提交都无效。
在使用 Databricks Runtime 15.4 LTS 或更低版本转换后写入表时,需要禁用 inCommitTimestamp 功能。
ALTER TABLE <table_name> DROP FEATURE inCommitTimestamp;
排查转换失败问题
本部分介绍将外部表转换为 Unity 目录托管表以及如何解决这些问题的常见问题。
DBR 版本一致性
避免使用不同的 Databricks Runtime 版本运行或重试同一表的转换。 元数据可以跨版本以不同的方式序列化,这会导致 VERSIONED_CLONE_INTERNAL_ERROR.EXISTING_FILE_VALIDATION_FAILED 失败。 如果转换失败,请始终使用相同的 Databricks Runtime 版本重试。
在转换期间关闭群集
如果在转换期间群集关闭,DELTA_ALTER_TABLE_SET_MANAGED_INTERNAL_ERROR 命令可能会失败。 重试该命令以恢复转换。
损坏的外部表
如果外部表已损坏(例如表状态无效),则转换可能会失败,并出现错误,例如 DELTA_TRUNCATED_TRANSACTION_LOG, DELTA_TXN_LOG_FAILED_INTEGRITY或 DELTA_STATE_RECOVER_ERRORS。 在尝试转换之前,请确保可以在外部表上运行基本操作,例如 DESCRIBE DETAIL。
回滚到外部表
重要
该 UNSET MANAGED 命令在 Databricks Runtime 17.0 或更高版本中可用。
将外部表转换为托管表后,可以在 14 天内回滚。
如果回滚,则在转换和回滚之间在外部位置所做的提交可以按版本进行时间旅行,但不能按时间戳进行。 回滚操作后的七天内,托管位置中的数据将被删除。
若要回滚到外部表,请运行以下命令:
ALTER TABLE catalog.schema.my_managed_table UNSET MANAGED
如果回滚命令中断,可以重新运行以重试,类似于 SET MANAGED 命令。
检查回滚
您可以确认转换已回滚:
DESCRIBE EXTENDED catalog_name.schema_name.table_name
如果表已转换,则 Type 下方 col_name 将显示为 EXTERNAL 下 data_type。
在回滚到外部表后,您也必须重启流式处理作业,如同转换过程一样。
停机时间和数据复制时间
当读取器或编写器在转换期间访问表时,可能会停机。 但是,与“DEEP CLONE”命令相比,该 SET MANAGED 命令可最大程度地减少或消除读取器和编写器的停机时间。 Databricks Runtime 16.1 或更高版本的读者不会停机。 复制表数据和增量日志时,读取器和写入器在第一步期间不受影响。
在第二步中,将阻止对 Unity Catalog 外部位置的写入操作,并且在第一次数据复制期间提交到外部位置的内容将被移过来。 第二个数据复制步骤会导致 Databricks Runtime 15.4 LTS 或更低版本中的编写器和读取器停机。
之后,读者和编写器将转移到 Unity 目录托管位置,并在 Unity 目录中注册新的托管表位置。 使用 Databricks Runtime 16.1 或更高版本的用户将体验到相当于无停机的使用效果。
估计的停机时间为:
| 表大小 | 建议的群集大小 | 数据复制的时间 | 读取器和编写器停机时间 |
|---|---|---|---|
| 100 GB 或更少 | 32 核 / DBSQL 小型 | 约 6 分钟或更少 | ~1-2 分钟或更少 |
| 1 TB(兆字节) | 64核/DBSQL中型 | 约 30 分钟 | ~1-2min |
| 10 兆字节 | 256核/DBSQL x-large | ~1.5 小时 | ~1-5min |
估计假设吞吐量速率为 0.5-2GB/CPU 核心/分钟。
注释
停机时间可能会有所不同。 转换的性能取决于文件大小、文件数和提交次数等因素。
已知的限制
将外部表转换为托管表具有以下限制:
流式处理客户端:转换后必须重启任何流式处理作业。
回滚后的表历史记录约束:对于 Databricks Runtime 15.4 LTS 或更高版本中的读取者/编写器,转换后但在回滚之前提交的表历史记录将可以通过版本进行时间旅行,但无法通过时间戳进行。
多个云区域:如果 Unity 目录元存储、目录或架构的默认托管位置与要转换的外部表的存储位置不同,则可能会产生额外的跨区域数据传输成本。 云提供商将这些费用强加于 Databricks 的控制之外。
若要检查架构、目录和元存储的位置,可以使用以下命令:
DESC SCHEMA EXTENDED <catalog_name>.<schema_name>; DESC CATALOG EXTENDED <catalog_name>; SELECT * FROM system.information_schema.metastores;