AWS Athena复制S3表数据后查询无结果问题排查
问题场景
我有一张可正常查询的Athena表 mydb.mySourceTable,建表语句如下:
CREATE EXTERNAL TABLE `mySourceTable`( `column1` bigint, `column2` bigint, ... ) PARTITIONED BY ( `columnA` string, `columnB` string, ...) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/prefix/.../mySourceTable/' TBLPROPERTIES ( 'classification'='parquet')
将该表对应的S3数据从 s3://bucket/prefix/.../mySourceTable/ 复制到 s3://bucket/prefix/.../myNewTable/ 后,创建了结构完全一致的新表 myNewTable,建表语句如下:
CREATE EXTERNAL TABLE `myNewTable`( `column1` bigint, `column2` bigint, ... ) PARTITIONED BY ( `columnA` string, `columnB` string, ...) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://bucket/prefix/.../myNewTable/' TBLPROPERTIES ( 'classification'='parquet')
执行分区修复命令:
msck repair table myNewTable
返回「元存储中无对应分区」及「文件系统中缺少相同分区列表」,执行查询语句 select * from myNewTable limit 10 无结果返回且无报错。
已排除权限问题(同Bucket及前缀),使用Glue爬虫指向新表前缀生成的表可正常查询,但手动执行该爬虫生成的建表语句仍无查询结果,怀疑Glue元数据异常。
问题分析与解决方案
核心原因
Glue爬虫生成表时会自动处理分区格式校验、添加关键元数据属性,手动建表时容易遗漏这些细节,导致Athena无法正确关联S3数据与元存储。
具体解决步骤
- 补充Glue爬虫默认添加的TBLPROPERTIES参数
Glue生成的表会包含额外属性,手动建表时需补充(根据实际数据调整参数值):
TBLPROPERTIES ( 'classification'='parquet', 'parquet.compression'='SNAPPY', -- 匹配源数据的压缩格式 'compressionType'='none', 'typeOfData'='file', 'has_encrypted_data'='false' )
其中parquet.compression是关键,若源数据有压缩但未指定,SerDe会无法解析文件。
校验S3分区路径格式
确保新表S3路径下的分区目录严格遵循Hive格式:columnA=valueA/columnB=valueB/,且分区列名大小写与建表语句完全一致。若源表分区列是小写,复制后的目录为大写,MSCK Repair会无法识别。手动添加分区替代MSCK Repair
如果自动修复无效,尝试手动指定分区:
ALTER TABLE myNewTable ADD PARTITION (columnA='val1', columnB='val2') LOCATION 's3://bucket/prefix/.../myNewTable/columnA=val1/columnB=val2/';
添加后执行查询验证数据是否返回。
- 强制同步Glue元数据
使用增强版MSCK命令刷新元数据缓存:
MSCK REPAIR TABLE myNewTable SYNC PARTITIONS;
该命令会直接同步S3分区与Glue元存储,比普通修复更彻底。
- 替换为新版SerDe类
手动建表使用的旧版SerDe可能存在兼容性问题,替换为Glue爬虫默认使用的新版:
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetSerDe'
内容的提问来源于stack exchange,提问作者Zack

