

# MSCK REPAIR TABLE
<a name="msck-repair-table"></a>

在添加与 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](alter-table-drop-partition.md)。

## 注意事项和限制
<a name="msck-repair-table-considerations"></a>

在使用 `MSCK REPAIR TABLE` 时，请记住以下几点：
+ 添加所有分区可能需要一些时间。如果此操作超时，它将处于不完整的状态，其中只有少数分区会被添加到目录中。应在同一个表上运行 `MSCK REPAIR TABLE` 语句，直到添加所有分区。有关更多信息，请参阅 [对您的数据进行分区](partitions.md)。
+ 对于不兼容 Hive 的分区，请使用[ALTER TABLE ADD PARTITION](alter-table-add-partition.md)加载分区，以便您可以查询数据。
+ 要与 Athena 结合使用的分区位置必须使用 `s3` 协议（例如，`s3://amzn-s3-demo-bucket/{{folder}}/`）。在 Athena 中，当对包含的表运行 `MSCK REPAIR TABLE` 查询时，使用其他协议的位置（例如，`s3a://{{bucket}}/{{folder}}/`）将导致查询失败。
+ 由于 `MSCK REPAIR TABLE` 同时扫描文件夹及其子文件夹以查找匹配的分区方案，请确保在单独的文件夹层次结构中保留单独表的数据。例如，假设您在 `s3://amzn-s3-demo-bucket1` 中拥有表 1 的数据，在 `s3://amzn-s3-demo-bucket1/table-2-data` 中拥有表 2 的数据。如果两个表都是按字符串分区的，则 `MSCK REPAIR TABLE` 会将表 2 的分区添加到表 1 中。为了避免这种情况，请使用单独的文件夹结构，如 `s3://amzn-s3-demo-bucket1` 和 `s3://amzn-s3-demo-bucket2`。请注意，此行为与 Amazon EMR 和 Apache Hive 一致。
+ 由于已知问题，当分区值包含冒号（`:`）字符时（例如，当分区值为一个时间戳时）`MSCK REPAIR TABLE` 会静默失败。一个解决方法是使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)。
+ `MSCK REPAIR TABLE` 不会添加开头为下划线（\_）的分区列名称。要绕过此限制，使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)。

## 摘要
<a name="synopsis"></a>

```
MSCK REPAIR TABLE table_name
```

## 示例
<a name="examples"></a>

```
MSCK REPAIR TABLE orders;
```

## 问题排查
<a name="msck-repair-table-troubleshooting"></a>

运行 `MSCK REPAIR TABLE` 后，如果 Athena 未将分区添加到 Amazon Glue Data Catalog 中的表，请检查以下内容：
+ **Amazon Glue 访问权限** - 确保 Amazon Identity and Access Management（IAM）角色具有允许执行 `glue:BatchCreatePartition` 操作的策略。有关更多信息，请参阅本文后面的[在 IAM policy 中允许 glue:BatchCreatePartition](#msck-repair-table-troubleshooting-allow-gluebatchcreatepartition-in-the-policy)。
+ **Amazon S3 访问权限** – 确保角色具有的策略的权限足以访问 Amazon S3，包括 [https://docs.amazonaws.cn/AmazonS3/latest/API/API_control_DescribeJob.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_control_DescribeJob.html) 操作。有关允许哪些 Amazon S3 操作的示例，请参阅 [在 Athena 中配置对 Amazon S3 存储桶的跨账户存取](cross-account-permissions.md) 中的示例存储桶策略。
+ **Amazon S3 对象键大小写** - 确保 Amazon S3 路径为小写而不是驼峰式大小写（例如，`userid` 而不是 `userId`），或者使用 `ALTER TABLE ADD PARTITION` 指定对象键名称。有关更多信息，请参阅本文后面的[更改或重新定义 Amazon S3 路径](#msck-repair-table-troubleshooting-change-or-redefine-the-amazon-s3-path)。
+ **查询超时** – `MSCK REPAIR TABLE` 最适用于首次创建表或在数据和分区元数据之间存在奇偶校验不确定性的情况。如果您使用 `MSCK REPAIR TABLE` 以频繁添加新分区(例如，每天添加)并遇到查询超时，请考虑使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)。
+ **文件系统中缺少分区** - 如果您在 Amazon S3 中手动删除分区，然后运行 `MSCK REPAIR TABLE`，您可能会收到错误消息文件系统中缺少分区。这是因为 `MSCK REPAIR TABLE` 不会从表元数据中删除过时的分区。要从表元数据中移除已删除的分区，请运行 [ALTER TABLE DROP PARTITION](alter-table-drop-partition.md)。请注意，[SHOW PARTITIONS](show-partitions.md) 将类似地仅列出元数据中的分区，而不是文件系统中的分区。
+ **“NullPointerException name is null（NullPointerException 名称为空）”错误**

  如果您将 Amazon Glue [CreateTable](https://docs.amazonaws.cn/glue/latest/webapi/API_CreateTable.html) API 操作或 Amazon CloudFormation [https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/aws-resource-glue-table.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/aws-resource-glue-table.html) 模板创建用于 Athena 的表，而不指定 `TableType` 属性，然后运行 DDL 查询，如 `SHOW CREATE TABLE` 或者 `MSCK REPAIR TABLE`，则您将收到错误消息 FAILED: NullPointerException Name is null（失败：NullPointerException 名称为空）。

  要纠正该错误，请为 [TableInput](https://docs.amazonaws.cn/glue/latest/webapi/API_TableInput.html) `TableType` 属性指定值，使其作为 Amazon Glue `CreateTable` API 调用或 [Amazon CloudFormation 模板](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/aws-properties-glue-table-tableinput.html)的一部分。`TableType` 可能的值包括 `EXTERNAL_TABLE` 或 `VIRTUAL_VIEW`。

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

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

### 在 IAM policy 中允许 glue:BatchCreatePartition
<a name="msck-repair-table-troubleshooting-allow-gluebatchcreatepartition-in-the-policy"></a>

审核附加到您用于执行 `MSCK REPAIR TABLE` 的角色的 IAM policy。当您[将 Amazon Glue Data Catalog 与 Athena 一起使用](data-sources-glue.md)时，IAM policy 必须允许 `glue:BatchCreatePartition` 操作。有关允许 `glue:BatchCreatePartition` 操作的 IAM policy 的示例，请参阅 [Amazon 托管策略：AmazonAthenaFullAccess](security-iam-awsmanpol.md#amazonathenafullaccess-managed-policy)。

### 更改或重新定义 Amazon S3 路径
<a name="msck-repair-table-troubleshooting-change-or-redefine-the-amazon-s3-path"></a>

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

```
s3://amzn-s3-demo-bucket/path/userId=1/

s3://amzn-s3-demo-bucket/path/userId=2/

s3://amzn-s3-demo-bucket/path/userId=3/
```

要解决该问题，可以执行下列操作之一：
+ 创建 Amazon S3 对象键时，请使用小写字母而不是驼峰式大小写：

  ```
  s3://amzn-s3-demo-bucket/path/userid=1/
  
  s3://amzn-s3-demo-bucket/path/userid=2/
  
  s3://amzn-s3-demo-bucket/path/userid=3/
  ```
+ 使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 重新定义位置，如以下示例所示：

  ```
  ALTER TABLE table_name ADD [IF NOT EXISTS]
  PARTITION (userId=1)
  LOCATION 's3://amzn-s3-demo-bucket/path/userId=1/'
  PARTITION (userId=2)
  LOCATION 's3://amzn-s3-demo-bucket/path/userId=2/'
  PARTITION (userId=3)
  LOCATION 's3://amzn-s3-demo-bucket/path/userId=3/'
  ```

请注意，尽管 Amazon S3 对象键名称可以使用大写字母，但 Amazon S3 存储桶名称本身一定要使用小写字母。有关更多信息，请参阅《*Amazon S3 用户指南*》中的[对象键命名指南](https://docs.amazonaws.cn/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines)和[存储桶命名规则](https://docs.amazonaws.cn/AmazonS3/latest/userguide/bucketnamingrules.html)。