【问题标题】:Creating multiple GSIs by updateTable - DynamoDB通过 updateTable 创建多个 GSI - DynamoDB
【发布时间】:2026-02-08 18:50:02
【问题描述】:

我是 DynmaoDB 的 updateTable,根据文档,如果我们要创建多个全局二级索引 (GSI),我们需要在“GlobalSecondaryIndexUpdates”字段中有多个对象,所以我传递了以下参数,但不会更新 GSI;但是,如果我只是创建一个 GSI(在“GlobalSecondaryIndexUpdates”字段中传递一个对象,它可以工作);这是我为创建多个 GSI 传递的参数:

{
    "TableName": "movies",
    "AttributeDefinitions": [{
            "AttributeName": "id",
            "AttributeType": "N"
        }, {
            "AttributeName": "title",
            "AttributeType": "S"
        }, {
            "AttributeName": "subtitle",
            "AttributeType": "S"
        }],
    "GlobalSecondaryIndexUpdates": [{
            "Create": {
                "IndexName": "title",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": "5",
                    "WriteCapacityUnits": "5"
                },
                "KeySchema": [{
                        "AttributeName": "title",
                        "KeyType": "HASH"
                    }],
                "Projection": {
                    "ProjectionType": "ALL"
                }
            }
        }, {
            "Create": {
                "IndexName": "subtitle",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": "5",
                    "WriteCapacityUnits": "5"
                },
                "KeySchema": [{
                        "AttributeName": "subtitle",
                        "KeyType": "HASH"
                    }],
                "Projection": {
                    "ProjectionType": "ALL"
                }
            }
        }]
}

我是否以错误的格式传递参数?

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb amazon nosql


    【解决方案1】:

    来自 DynamoDB documentation

    您只能创建或删除一个全局二级索引 更新表操作。但是,如果您运行多个 UpdateTable 同时操作,您可以一次创建多个索引。 您最多可以在一个表上运行五个这样的 UpdateTable 操作 一次,每个操作只能创建一个索引。

    【讨论】:

    • 当我通过网站(AWS 控制台)执行此操作时,它说:Only 1 online index can be created or deleted simultaneously per table (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: LimitExceededException; Request ID: ... 但是通过代码它一个接一个地创建/删除它并且它起作用了! :-) 谢谢
    • 但是您不能真正同时运行多个 UpdateTable 操作,对吗?我正在尝试通过 java AWS sdk 做类似的事情;我正在尝试创建几个全局二级索引;当我尝试进行第二次更新时,我得到了同样的错误,从上面,关于“只能同时创建或删除 1 个在线索引......”;我发现我必须轮询表的状态,然后还要轮询所有索引的状态;如果其中任何一个处于 ACTIVE 以外的状态,我会收到错误
    • 我在@user26270 得到了同样的结果。而AmazonDynamoDB.updateTable 返回一个UpdateTableResult,但显然它实际上并没有完成并且没有UpdateTableResult.waitForReady() 类型函数。好郁闷!!!
    【解决方案2】:

    所以 SDK 现在提供了一个 Table.createGSI 帮助函数来实现这个目的。请参阅有关该主题的blog post

    此帮助器返回一个Index 对象,您可以调用index.waitForActive(); 等到建立索引后再构建下一个避免此异常的GSI。

    【讨论】:

    • 你如何做 index.waitForActive() 与 aws cli 等效?
    【解决方案3】:

    如果您使用 bash,则可以使用适当的 aws 命令创建索引,然后使用以下 sn-p 在更新之间等待

    waitForIndexUpdate() {
      tableActive=false
      while [ "$tableActive" = false ];
      do
        describeTable=$(aws dynamodb describe-table --endpoint-url "$dynamoHost" --table-name "$tableName")
        if [[ $describeTable == *"\"IndexStatus\": \"CREATING\""* ]];
        then
          echo "waiting for index update to complete..."
          sleep .5
        else
          tableActive=true
        fi
      done
    }
    

    【讨论】: