我在AWS上有一个RDS数据库实例,目前已将其关闭.然而,每隔几天它就会自行启动.我现在没有任何其他服务在运行.

我的RDS日志(log)中有此事件: "数据库实例正在启动,因为它超过了允许的最长停止时间."

为什么我的RDS实例可以停止的时间有限制?我只想把我的项目搁置几周,但AWS不让我关闭数据库?让它处于闲置状态需要12.50美元/月,所以我不想为此买单,我当然也不想让AWS为我启动一个不被使用的实例.

请帮忙!

推荐答案

这是new feature美元的限制.

一次最多可以停止一个实例7天.7天后,它将自动启动.有关停止和启动数据库实例的更多详细信息,请参阅亚马逊RDS用户指南中的Stopping and Starting a DB Instance.

您可以设置cron作业(job),在7天后再次停止实例.您还可以更改为较小的实例大小以节省资金.

另一种 Select 是即将到来的Aurora Serverless,它会自动停止和启动.在全天候运行时,它可能比专用实例更昂贵.

最后,总是有Heroku,它给你一个free database instance,它会自动启动和停止,但有一些限制.


您还可以try 将以下CloudFortification模板另存为KeepDbStopped.yml,然后使用此命令进行部署:

aws cloudformation deploy --template-file KeepDbStopped.yml --stack-name stop-db --capabilities CAPABILITY_IAM --parameter-overrides DB=arn:aws:rds:us-east-1:XXX:db:XXX

确保将arn:aws:rds:us-east-1:XXX:db:XXX更改为RDS ARN.

Description: Automatically stop RDS instance every time it turns on due to exceeding the maximum allowed time being stopped
Parameters:
  DB:
    Description: ARN of database that needs to be stopped
    Type: String
    AllowedPattern: arn:aws:rds:[a-z0-9\-]+:[0-9]+:db:[^:]*
Resources:
  DatabaseStopperFunction:
    Type: AWS::Lambda::Function
    Properties:
      Role: !GetAtt DatabaseStopperRole.Arn
      Runtime: python3.6
      Handler: index.handler
      Timeout: 20
      Code:
        ZipFile:
          Fn::Sub: |
            import boto3
            import time

            def handler(event, context):
              print("got", event)
              db = event["detail"]["SourceArn"]
              id = event["detail"]["SourceIdentifier"]
              message = event["detail"]["Message"]
              region = event["region"]
              rds = boto3.client("rds", region_name=region)

              if message == "DB instance is being started due to it exceeding the maximum allowed time being stopped.":
                print("database turned on automatically, setting last seen tag...")
                last_seen = int(time.time())
                rds.add_tags_to_resource(ResourceName=db, Tags=[{"Key": "DbStopperLastSeen", "Value": str(last_seen)}])

              elif message == "DB instance started":
                print("database started (and sort of available?)")

                last_seen = 0
                for t in rds.list_tags_for_resource(ResourceName=db)["TagList"]:
                  if t["Key"] == "DbStopperLastSeen":
                    last_seen = int(t["Value"])

                if time.time() < last_seen + (60 * 20):
                  print("database was automatically started in the last 20 minutes, turning off...")
                  time.sleep(10)  # even waiting for the "started" event is not enough, so add some wait
                  rds.stop_db_instance(DBInstanceIdentifier=id)

                  print("success! removing auto-start tag...")
                  rds.add_tags_to_resource(ResourceName=db, Tags=[{"Key": "DbStopperLastSeen", "Value": "0"}])

                else:
                  print("ignoring manual database start")

              else:
                print("error: unknown database event!")
  DatabaseStopperRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: Notify
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                  - rds:StopDBInstance
                Effect: Allow
                Resource: !Ref DB
              - Action:
                  - rds:AddTagsToResource
                  - rds:ListTagsForResource
                  - rds:RemoveTagsFromResource
                Effect: Allow
                Resource: !Ref DB
                Condition:
                  ForAllValues:StringEquals:
                    aws:TagKeys:
                      - DbStopperLastSeen
  DatabaseStopperPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !GetAtt DatabaseStopperFunction.Arn
      Principal: events.amazonaws.com
      SourceArn: !GetAtt DatabaseStopperRule.Arn
  DatabaseStopperRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.rds
        detail-type:
          - "RDS DB Instance Event"
        resources:
          - !Ref DB
        detail:
          Message:
            - "DB instance is being started due to it exceeding the maximum allowed time being stopped."
            - "DB instance started"
      Targets:
        - Arn: !GetAtt DatabaseStopperFunction.Arn
          Id: DatabaseStopperLambda

它至少对一个人有效.如果您有问题,请报告here.

Database相关问答推荐

撤销语句释放类实例中可用的缓冲区

什么时候需要手动重新分析 PostgreSQL 中的表?

在哪里存储 PHP 应用程序的数据库登录凭据

java嵌入式库磁盘键值数据库

即使使用列入白名单的 IP,也无法连接到 Azure SQL 数据库

group by会自动保证order by吗?

如何验证 SQLAlchemy ORM 中的列数据类型?

ORM vs 传统数据库查询,它们的字段是什么?

db:schema:load vs db:migrate with capistrano

nvarchar (50) 与 nvarchar (max) 的含义

我们如何保存在 sqlite3 中创建的数据库

如果数据库已经提供缓存,为什么还要使用应用程序级缓存?

数以百万计的条目排名

mysql 无法从存储引擎读取自增值

日期格式的 Oracle SQL 查询

在 PostgreSQL 中索引空值

最佳用户角色权限数据库设计实践?

数据库与平面文本文件:当性能不是问题时, Select 一个而不是另一个的一些技术原因是什么?

SQL Server Express LocalDB 可以远程连接吗?

在连接表中,Rails 缺少组合键的最佳解决方法是什么?