关于 querying-aws-s3
这项技能通过 Athena 查询 Amazon S3 元数据和 Storage Lens 系统表,面向 AWS 用户,涵盖配置、选表、SQL 查询与访问安全。
主要功能
- 01查询对象清单、日志和注释表
- 02分析 Storage Lens 指标
- 03配置 S3 Metadata 和表导出
- 04指导 Athena SQL 与权限设置
适用场景
- 01统计对象并按标签筛选
- 02审计对象上传、删除及请求来源
- 03搜索注释文本或 JSON 值
- 04查看存储桶容量和活动指标
MCP 相关
建议使用 AWS MCP 服务进行沙盒执行和审计记录;相关命令也可通过 AWS CLI 运行。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aws/ agent-toolkit-for-aws --skill querying-aws-s3安装后在 Claude Code 中输入/querying-aws-s3确认已加载。
详细介绍
查询 AWS S3 系统表
概述
搭配 AWS MCP server 使用效果最佳,可实现沙盒执行和审计日志记录。以下所有命令均使用 AWS CLI,可在配置了 AWS 凭证的任何环境中运行。请使用 IAM 角色或临时凭证,避免使用长期访问密钥。
Amazon S3 Metadata 提供持续更新的 Apache Iceberg 表,用于记录通用存储桶的对象级元数据。S3 Storage Lens 会将汇总的存储和活动指标导出为 Iceberg 表。这两类表均为只读,存储在 AWS 托管的 aws-s3 表存储桶中,并可通过 Amazon Athena 查询。
相比原始 S3 API(list-objects-v2、head-object),系统表更受推荐,原因如下:
list-objects-v2每页最多分页返回 1000 个对象,对于大型存储桶(数百万或数十亿个对象)效率低下。无论规模如何,清单表都能在几秒内返回SELECT COUNT(*)的结果。list-objects-v2无法识别对象的上传者、上传时使用的 IP 地址,也无法确定对象何时被删除。只有日志表包含requester、source_ip_address和删除事件跟踪信息。- 按标签筛选需要对每个对象调用一次
get-object-tagging。清单表提供了可查询的映射列object_tags。
决策树
| 用户意图 | 使用此技能? | 表 | 替代方案 |
|---|---|---|---|
| 查询存储桶中的对象数量 | 是 | 清单 | — |
| 查看最近上传或删除了哪些对象 | 是 | 日志 | — |
| 审计对象的写入者或删除者 | 是 | 日志(requester、source_ip) | — |
| 查看存储类别细分情况 | 是 | 清单 | — |
| 按标签或用户元数据查找对象 | 是 | 清单 | — |
| 搜索注释内容 | 是 | 注释 | 单个对象 → 直接调用 API get-object-annotation |
| 写入或更新注释 | 否 | — | 直接调用 API:put-object-annotation(表为只读) |
| 查询对象内部的数据 | 否 | — | querying-data-lake |
| 查询存储桶级存储指标或趋势 | 是 | Storage Lens 表 | — |
| 启用元数据跟踪 | 是 | 参见“启用”部分 | — |
常见任务
1. 检查是否已配置
查询前,请确认目标存储桶已启用 S3 Metadata。
aws s3api get-bucket-metadata-configuration --bucket <BUCKET> --region <REGION>
解读响应:
- 出现
MetadataConfigurationNotFound错误 → 尚未启用。请参阅下方的“启用”部分。 TableStatus: ACTIVE→ 已可查询。TableStatus: BACKFILLING→ 可查询,但清单可能不完整。TableStatus: FAILED→ 检查错误字段(通常是 IAM 问题)。
对于 Storage Lens:
aws s3control get-storage-lens-configuration --account-id <ACCOUNT> --config-id <CONFIG_ID> --region <REGION>
查看 DataExport.StorageLensTableDestination.IsEnabled: true。
2. 启用(如果尚未配置)
在存储桶上启用 S3 Metadata:
aws s3api create-bucket-metadata-configuration \
--bucket <BUCKET> \
--region <REGION> \
--metadata-configuration '{
"JournalTableConfiguration": {"RecordExpiration": {"Expiration": "DISABLED"}},
"InventoryTableConfiguration": {"ConfigurationState": "ENABLED"}
}'
如需同时启用注释(需要服务角色):
aws s3api create-bucket-metadata-configuration \
--bucket <BUCKET> \
--region <REGION> \
--metadata-configuration '{
"JournalTableConfiguration": {"RecordExpiration": {"Expiration": "ENABLED", "Days": 90}},
"InventoryTableConfiguration": {"ConfigurationState": "ENABLED"},
"AnnotationTableConfiguration": {"ConfigurationState": "ENABLED", "Role": "<ROLE_ARN>"}
}'
启用 Storage Lens S3 Tables 导出:
aws s3control put-storage-lens-configuration \
--account-id <ACCOUNT> \
--config-id <CONFIG_ID> \
--region <REGION> \
--storage-lens-configuration '{
"Id": "<CONFIG_ID>",
"IsEnabled": true,
"AccountLevel": {"BucketLevel": {}},
"DataExport": {
"StorageLensTableDestination": {"IsEnabled": true}
}
}'
在 Glue 中注册 S3 Tables 联合目录(Athena 访问所必需):
aws glue create-catalog --region <REGION> --cli-input-json '{
"Name": "s3tablescatalog",
"CatalogInput": {
"FederatedCatalog": {
"Identifier": "arn:aws:s3tables:<REGION>:<ACCOUNT>:bucket/*",
"ConnectionName": "aws:s3tables"
}
}
}'
有关设置权限和 IAM 角色要求,请参阅下方的安全注意事项。
3. 验证权限
查询需要以下权限:
- Athena 执行权限
- S3 Tables 读取权限(请参阅“安全注意事项”中的最小权限策略)
- 已在 Glue 中注册的 S3 Tables 联合目录(
s3tablescatalog) - Athena 工作组已配置对输出位置进行 SSE-KMS 加密
如果出现 CATALOG_NOT_FOUND 错误,可能是尚未启用 Glue 集成。请参阅:
将 S3 Tables 与 AWS 分析服务集成
4. 确定目标表
S3 Metadata 表 — 命名空间为 b_<bucket-name>:
| 表 | 捕获的数据 |
|---|---|
journal | 事件日志——每次 CREATE、DELETE、UPDATE_METADATA 和注释事件。近乎实时。 |
inventory | 当前状态——每个对象(最新版本)一行。在 1 小时内更新。 |
annotation | 注释负载——text_value 列保存完整内容。近乎实时。 |
Storage Lens 表 — 命名空间为 lens_<config-id>_exp:
| 表 | 捕获的数据 |
|---|---|
default_storage_metrics | 按存储桶/前缀统计:对象数量、大小、存储类别明细。每日更新。 |
default_activity_metrics | 按存储桶/前缀统计:GET/PUT/DELETE 请求数量。每日更新。 |
bucket_property_metrics | 存储桶配置:版本控制、加密、生命周期设置。每日更新。 |
5. 查询
查询语法:
"s3tablescatalog/aws-s3"."<namespace>"."<table>"
限制:
-
执行前,必须确认工作组和输出位置
-
必须确保 Athena 工作组强制使用 SSE-KMS 加密查询结果
-
必须告知用户表为只读——不支持 INSERT/UPDATE/DELETE
-
应使用此技能中记录的键列构建查询。如果需要完整架构(例如 AWS 添加了新列),请在任意单个命名空间上运行一次
get-tables——同一表类型的所有实例架构都相同:aws glue get-tables --catalog-id "<ACCOUNT>:s3tablescatalog/aws-s3" --database-name "<namespace>" --region <REGION>
Journal——审计是谁更改了什么:
SELECT key, record_type, record_timestamp, requester, source_ip_address
FROM "s3tablescatalog/aws-s3"."b_<bucket>"."journal"
WHERE record_type = 'DELETE'
AND record_timestamp > current_timestamp - interval '24' hour
ORDER BY record_timestamp DESC;
Journal——跟踪注释事件:
SELECT key, record_type, annotation.name, record_timestamp
FROM "s3tablescatalog/aws-s3"."b_<bucket>"."journal"
WHERE record_type IN ('CREATE_ANNOTATION', 'DELETE_ANNOTATION', 'UPDATE_ANNOTATION_METADATA')
ORDER BY record_timestamp DESC LIMIT 20;
Inventory——按存储类别查找对象:
SELECT key, size, storage_class, last_modified_date
FROM "s3tablescatalog/aws-s3"."b_<bucket>"."inventory"
WHERE storage_class = 'GLACIER'
ORDER BY size DESC LIMIT 50;
Inventory——按标签查找对象:
SELECT key, size, object_tags
FROM "s3tablescatalog/aws-s3"."b_<bucket>"."inventory"
WHERE object_tags['environment'] = 'staging';
Annotation——跨负载搜索:
SELECT object_key, name, text_value
FROM "s3tablescatalog/aws-s3"."b_<bucket>"."annotation"
WHERE text_value LIKE '%error%';
Annotation——提取 JSON 字段:
SELECT object_key, json_extract_scalar(text_value, '$.status') as status
FROM "s3tablescatalog/aws-s3"."b_<bucket>"."annotation"
WHERE name = 'pipeline_status'
AND json_extract_scalar(text_value, '$.status') = 'FAILED';
Storage Lens——存储分布:
SELECT *
FROM "s3tablescatalog/aws-s3"."lens_<config-id>_exp"."default_storage_metrics"
LIMIT 20;
路由:Athena 还是直接 API
| 场景 | 使用方式 |
|---|---|
| 单个已知对象和注释名称 | 直接 API:get-object-annotation |
| 跨多个对象进行聚合/计数 | 使用 Athena 查询 annotation 或 inventory 表 |
| 跨注释负载进行全文搜索 | 使用 Athena 和 LIKE 或 json_extract_scalar |
| 写入/更新注释 | 直接 API:put-object-annotation(表为只读) |
| 存储桶未配置相应功能 | 直接 API 循环(list-objects-v2 + head-object);建议启用 S3 Metadata |
故障排查
| 错误 | 原因 | 修复方法 |
|---|---|---|
CATALOG_NOT_FOUND | S3 Tables 尚未在 Glue 中注册 | 启用集成:S3 控制台 > 表存储桶 > 启用集成 |
| journal 查询结果为空 | 功能刚启用,尚未记录事件 | 上传或删除一个对象,并等待约 1 分钟 |
| inventory 查询结果为空 | 表仍处于 BACKFILLING 状态 | 检查状态;等待其变为 ACTIVE(根据对象数量,可能需要几分钟到几小时) |
查询表时出现 AccessDenied | 缺少 s3tables:GetTable 或 GetTableMetadataLocation 权限 | 请参阅下文的安全注意事项 |
| 命名空间错误 | 存储桶名称包含句点 | 命名空间中的句点会转换为下划线:my.bucket → b_my_bucket |
| 没有 Storage Lens 数据 | 首次交付最多需要 48 小时 | 请等待;不会回填历史数据 |
安全注意事项
最小权限 IAM 策略
将权限限定到特定表存储桶 ARN,而不是使用通配符:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3tables:GetTable",
"s3tables:GetTableMetadataLocation",
"s3tables:GetTableData",
"s3tables:GetNamespace",
"s3tables:ListTables",
"s3tables:ListNamespaces",
"s3tables:GetTableBucket"
],
"Resource": [
"arn:aws:s3tables:<REGION>:<ACCOUNT>:bucket/aws-s3",
"arn:aws:s3tables:<REGION>:<ACCOUNT>:bucket/aws-s3/*"
]
}
]
}
数据敏感性
Journal 查询结果可能包含敏感字段:
requester— 发出请求的 AWS 账户 ID 或服务主体source_ip_address— 请求者的 IP 地址
包含这些字段的查询结果应存储在加密且受访问控制的位置。避免记录或共享包含 IP 地址或主体标识符的原始查询输出。
查询结果加密
使用 EncryptionConfiguration 配置 Athena 工作组,以便对静态查询结果进行加密:
{
"ResultConfiguration": {
"EncryptionConfiguration": {
"EncryptionOption": "SSE_KMS",
"KmsKey": "arn:aws:kms:<REGION>:<ACCOUNT>:key/<KEY_ID>"
}
}
}
审计跟踪
为 Athena(StartQueryExecution、GetQueryResults)和 S3 Tables(s3tables:GetTableData)API 调用启用 CloudTrail 日志记录,以维护审计跟踪,记录谁查询了哪些元数据。确保 CloudTrail 日志使用 SSE-KMS 加密,并存储在启用了访问日志记录的存储桶中。