Consistent reads are not supported on global secondary indexes

TL;DR — 你在一个针对全局二级索引的 QueryScan 上设置了 ConsistentRead: true。GSI 从基础表异步复制,只提供最终一致性读取——这个标志是一个硬性错误,而非偏好设置。去掉该标志,或者如果你确实需要写后读一致性,就读取基础表(或者把该键设计进一个 LSI)。

含义

ValidationException: Consistent reads are not supported on global secondary indexes

一个 GSI 在物理上是它自己的索引结构,有自己的分区和容量;DynamoDB 会把基础表的写入异步地传播进去。因为你刚写入的项目可能还没到达索引,DynamoDB 无法对它兑现一个强一致性读取——因此 ConsistentRead: true 与 GSI 的 IndexName 组合会被直接拒绝。AWS 文档说得很明确:用 ConsistentRead 设为 true 查询一个 GSI,你会收到 ValidationException

本地二级索引则不同:一个 LSI 与基础表共享其分区,因此那里支持 ConsistentRead: true

为什么会发生

  • 该标志被全局设置——一个共享的查询辅助工具或客户端封装为每次读取默认设置 ConsistentRead: true,而某条调用路径添加了一个指向 GSI 的 IndexName
  • 一个 LSI 变成了 GSI——为本地索引(那里该标志合法)编写的代码被指向了一个全局索引。
  • 复制粘贴的基础表查询——一个在表上合法地使用了强一致性的查询,被加上 IndexName 后重用了。

如何修复

  1. 从 GSI 读取中移除 ConsistentRead(或把它设为 false——默认值):

    await client.send(
      new QueryCommand({
        TableName: 'Orders',
        IndexName: 'status-index',
        KeyConditionExpression: '#s = :open',
        // ConsistentRead: true  ← delete this line for a GSI
        ExpressionAttributeNames: {'#s': 'status'},
        ExpressionAttributeValues: {':open': {S: 'OPEN'}}
      })
    );
  2. 需要写后读?ConsistentRead: true 查询基础表——只要你要查找的键是表自己的分区键,就可以做到。

  3. 相同的分区键,不同的排序? 把它建模为一个 LSI(在表创建时创建),它支持一致性读取。

  4. 或者在应用中吸收这个延迟——GSI 传播通常很快;对于 UI 流程,返回你已经拥有的刚写入的数据胜过重新读取索引。

DynoTable 桌面应用会显示每张表的索引并让你直接查询它们——而且因为它知道哪个索引是全局的、哪个是本地的,这类错误压根不会出现。

在 DynoTable 中核对

DynoTable 知道哪些索引是 GSI 与 LSI — GSI 查询从不发送 ConsistentRead: true。使用 ⌘K 打开表,从下拉列表中选择一个索引,然后运行不带标志的查询。当你需要先写后读时,请改为查询基表 - Query Builder 为每个目标生成正确的参数。使用 ⌘P 切换配置文件;参见连接 AWS安装

来源

相关错误

参考资料

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。