MSCK REPAIR TABLE - Amazon Athena

MSCK REPAIR TABLE

在添加与 Hive 兼容的分区后,使用 MSCK REPAIR TABLE 命令可更新目录中的元数据。

MSCK REPAIR TABLE 命令将扫描在创建表后被添加到文件系统且兼容 Hive 的分区文件系统(例如 Amazon S3)。MSCK REPAIR TABLE 将比较表元数据中的分区和 S3 中的分区。如果您在创建表时指定的 S3 位置中存在新分区,则表会将这些分区添加到元数据和 Athena 表中。

在添加物理分区时,目录中的元数据将变得与文件系统中的数据布局不一致,需要将有关新分区的信息添加到目录中。要更新元数据,请运行 MSCK REPAIR TABLE 以便从 Athena 查询新分区中的数据。

注意

MSCK REPAIR TABLE 仅向元数据添加分区;它不会删除它们。要在 Amazon S3 中手动删除分区后从元数据中删除分区,请运行命令 ALTER TABLE table-name DROP PARTITION。有关更多信息,请参阅 ALTER TABLE DROP PARTITION

注意事项和限制

在使用 MSCK REPAIR TABLE 时,请记住以下几点:

  • 添加所有分区可能需要一些时间。如果此操作超时,它将处于不完整的状态,其中只有少数分区会被添加到目录中。应在同一个表上运行 MSCK REPAIR TABLE 语句,直到添加所有分区。有关更多信息,请参阅 在 Athena 中对数据进行分区

  • 对于不兼容 Hive 的分区,请使用ALTER TABLE ADD PARTITION加载分区,以便您可以查询数据。

  • 要与 Athena 结合使用的分区位置必须使用 s3 协议(例如,s3://DOC-EXAMPLE-BUCKET/folder/)。在 Athena 中,当对包含的表运行 MSCK REPAIR TABLE 查询时,使用其他协议的位置(例如,s3a://bucket/folder/)将导致查询失败。

  • 由于 MSCK REPAIR TABLE 同时扫描文件夹及其子文件夹以查找匹配的分区方案,请确保在单独的文件夹层次结构中保留单独表的数据。例如,假设您在 s3://DOC-EXAMPLE-BUCKET1 中拥有表 1 的数据,在 s3://DOC-EXAMPLE-BUCKET1/table-2-data 中拥有表 2 的数据。如果两个表都是按字符串分区的,则 MSCK REPAIR TABLE 会将表 2 的分区添加到表 1 中。为了避免这种情况,请使用单独的文件夹结构,如 s3://DOC-EXAMPLE-BUCKET1s3://DOC-EXAMPLE-BUCKET2。请注意,此行为与 Amazon EMR 和 Apache Hive 一致。

  • 由于已知问题,当分区值包含冒号(:)字符时(例如,当分区值为一个时间戳时)MSCK REPAIR TABLE 会静默失败。一个解决方法是使用 ALTER TABLE ADD PARTITION

  • MSCK REPAIR TABLE 不会添加开头为下划线(_)的分区列名称。要绕过此限制,使用 ALTER TABLE ADD PARTITION

摘要

MSCK REPAIR TABLE table_name

示例

MSCK REPAIR TABLE orders;

故障排除

运行 MSCK REPAIR TABLE 后,如果 Athena 未将分区添加到 AWS Glue Data Catalog 中的表,请检查以下内容:

  • AWS Glue 访问权限 - 确保 AWS Identity and Access Management(IAM)角色具有允许执行 glue:BatchCreatePartition 操作的策略。有关更多信息,请参阅本文后面的在 IAM policy 中允许 glue:BatchCreatePartition

  • Amazon S3 访问权限 – 确保角色具有的策略的权限足以访问 Amazon S3,包括 s3:DescribeJob 操作。有关允许哪些 Amazon S3 操作的示例,请参阅 Athena 中对 Amazon S3 存储桶的跨账户访问 中的示例存储桶策略。

  • Amazon S3 对象键大小写 - 确保 Amazon S3 路径为小写而不是驼峰式大小写(例如,userid 而不是 userId),或者使用 ALTER TABLE ADD PARTITION 指定对象键名称。有关更多信息,请参阅本文后面的更改或重新定义 Amazon S3 路径

  • 查询超时MSCK REPAIR TABLE 最适用于首次创建表或在数据和分区元数据之间存在奇偶校验不确定性的情况。如果您使用 MSCK REPAIR TABLE 以频繁添加新分区(例如,每天添加)并遇到查询超时,请考虑使用 ALTER TABLE ADD PARTITION

  • 文件系统中缺少分区 - 如果您在 Amazon S3 中手动删除分区,然后运行 MSCK REPAIR TABLE,您可能会收到错误消息文件系统中缺少分区。这是因为 MSCK REPAIR TABLE 不会从表元数据中删除过时的分区。要从表元数据中移除已删除的分区,请运行 ALTER TABLE DROP PARTITION。请注意,SHOW PARTITIONS 将类似地仅列出元数据中的分区,而不是文件系统中的分区。

  • “NullPointerException name is null(NullPointerException 名称为空)”错误

    如果您将 AWS Glue CreateTable API 操作或 AWS CloudFormation AWS::Glue::Table 模板创建用于 Athena 的表,而不指定 TableType 属性,然后运行 DDL 查询,如 SHOW CREATE TABLE 或者 MSCK REPAIR TABLE,则您将收到错误消息 FAILED: NullPointerException Name is null(失败:NullPointerException 名称为空)。

    要纠正该错误,请为 TableInput TableType 属性指定值,使其作为 AWS Glue CreateTable API 调用或 AWS CloudFormation 模板的一部分。TableType 可能的值包括 EXTERNAL_TABLEVIRTUAL_VIEW

    此要求仅适用于使用 AWS Glue CreateTable API 操作或 AWS::Glue::Table 模板创建表的情形。如果您适用 DDL 语句或 AWS Glue 爬网程序为 Athena 创建表,则 TableType 属性将自动定义。

以下各节提供了一些详细信息。

在 IAM policy 中允许 glue:BatchCreatePartition

审核附加到您用于执行 MSCK REPAIR TABLE 的角色的 IAM policy。当您将 AWS Glue Data Catalog 与 Athena 一起使用时,IAM policy 必须允许 glue:BatchCreatePartition 操作。有关允许 glue:BatchCreatePartition 操作的 IAM policy 的示例,请参阅 AWS 托管策略:AmazonAthenaFullAccess

更改或重新定义 Amazon S3 路径

如果 Amazon S3 路径中的一个或多个对象键采用驼峰式大小写而不是小写,MSCK REPAIR TABLE 可能不会将分区添加到 AWS Glue Data Catalog。例如,如果您的 Amazon S3 路径包含对象键名称 userId,则可能不会将以下分区添加到 AWS Glue Data Catalog:

s3://DOC-EXAMPLE-BUCKET/path/userId=1/ s3://DOC-EXAMPLE-BUCKET/path/userId=2/ s3://DOC-EXAMPLE-BUCKET/path/userId=3/

要解决该问题,可以执行下列操作之一:

  • 创建 Amazon S3 对象键时,请使用小写字母而不是驼峰式大小写:

    s3://DOC-EXAMPLE-BUCKET/path/userid=1/ s3://DOC-EXAMPLE-BUCKET/path/userid=2/ s3://DOC-EXAMPLE-BUCKET/path/userid=3/
  • 使用 ALTER TABLE ADD PARTITION 重新定义位置,如以下示例所示:

    ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION (userId=1) LOCATION 's3://DOC-EXAMPLE-BUCKET/path/userId=1/' PARTITION (userId=2) LOCATION 's3://DOC-EXAMPLE-BUCKET/path/userId=2/' PARTITION (userId=3) LOCATION 's3://DOC-EXAMPLE-BUCKET/path/userId=3/'

请注意,尽管 Amazon S3 对象键名称可以使用大写字母,但 Amazon S3 存储桶名称本身一定要使用小写字母。有关更多信息,请参阅《Amazon S3 用户指南》中的对象键命名指南存储桶命名规则