如何对连接到 Amazon RDS 数据库实例时出现的问题进行故障排除?
我想排查无法连接到 Amazon Relational Database Service (Amazon RDS) 数据库实例的原因。
简短描述
以下是与 Amazon RDS 数据库实例的连接可能失败的原因:
- 连接数据库实例的源在您的安全组、网络访问控制列表 (ACL) 或本地防火墙中没有获得访问权限。
- 路由表中缺少从客户端应用程序到数据库实例的网络路径。
- 连接数据库实例时使用了错误的 DNS 名称或端点。
- 数据库实例不可公开访问,无法通过互联网进行连接。
- 多可用区数据库实例进行了失效转移,而辅助数据库实例使用的子网或路由表不允许入站连接。
- 用户身份验证不正确。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
要对 Amazon RDS 数据库实例连接问题进行故障排除,请完成以下任务:
使用自动诊断
首先使用自动化工具以快速识别连接问题。
完成以下步骤:
- 要运行自动诊断工具,请使用以下 start-automation-execution AWS Systems Manager 命令:
**注意:**将 EC2-INSTANCE-ID 替换为您的 EC2 实例 ID,将 DB-INSTANCE-NAME 替换为您的 RDS 实例标识符。aws ssm start-automation-execution \ --document-name "AWSSupport-TroubleshootConnectivityToRDS" \ --parameters "InstanceId=EC2-INSTANCE-ID,DBInstanceIdentifier=DB-INSTANCE-NAME" - 要检查自动化结果,请运行以下 get-automation-execution 命令:
**注意:**将 EXECUTION-ID 替换为步骤 1 中的执行 ID。aws ssm get-automation-execution \ --automation-execution-id EXECUTION-ID
有关如何运行运行手册的说明及其检查内容的详细信息,请参阅 AWSSupport-TroubleshootConnectivityToRDS。
验证数据库实例状态
确认您的数据库实例可用且已做好连接准备。
完成以下步骤:
- 要检查您的数据库实例状态,请运行以下 describe-db-instances 命令:
**注意:**将 DB-INSTANCE-NAME 替换为您的 Amazon RDS 实例标识符。aws rds describe-db-instances \ --db-instance-identifier DB-INSTANCE-NAME \ --query 'DBInstances[*].DBInstanceStatus' - 等待状态显示为 available(可用),然后再尝试连接。新实例或重启后的实例最多可能需要 20 分钟才能变为可用。
检查安全组规则
安全组控制对 Amazon RDS 实例的网络访问权限。验证安全组是否允许来自源的流量。
完成以下步骤:
- 要识别附加到 Amazon RDS 实例的安全组,请运行以下 describe-db-instances 命令:
**注意:**将 DB-INSTANCE-NAME 替换为您的 RDS 实例标识符。aws rds describe-db-instances \ --db-instance-identifier DB-INSTANCE-NAME \ --query 'DBInstances[*].VpcSecurityGroups[*].VpcSecurityGroupId' - 要检查每个安全组的入站规则,请运行以下 describe-security-groups 命令:
**注意:**将 SECURITY-GROUP-ID 替换为步骤 1 中的各个安全组 ID。aws ec2 describe-security-groups \ --group-ids SECURITY-GROUP-ID \ --query 'SecurityGroups[*].IpPermissions' - 要添加允许您的 IP 地址的规则,请运行以下 authorize-security-group-ingress 命令:
**注意:**将 SECURITY-GROUP-ID 替换为您的安全组 ID。将 DATABASE-PORT 替换为您的数据库端口(MySQL 为 3306,PostgreSQL 为 5432)。将 YOUR-IP-ADDRESS 替换为您的公有 IP 地址。aws ec2 authorize-security-group-ingress \ --group-id SECURITY-GROUP-ID \ --protocol tcp \ --port DATABASE-PORT \ --cidr YOUR-IP-ADDRESS/32
验证网络 ACL 规则
网络访问控制列表 (ACL) 提供子网级安全性。检查其是否允许数据库流量。
完成以下步骤:
- 要识别 Amazon RDS 子网的网络访问控制列表 (ACL),请运行以下 describe-network-acls 命令:
**注意:**将 SUBNET-ID 替换为您的 RDS 子网 ID:aws ec2 describe-network-acls \ --filters "Name=association.subnet-id,Values=SUBNET-ID" \ --query 'NetworkAcls[*].NetworkAclId' - 要检查网络访问控制列表 (ACL) 规则,请运行以下 describe-network-acls 命令:
**注意:**将 NETWORK-ACL-ID 替换为步骤 1 中的网络 ACL ID。aws ec2 describe-network-acls \ --network-acl-ids NETWORK-ACL-ID \ --query 'NetworkAcls[*].Entries' - 验证入站规则是否允许数据库端口上的流量,以及出站规则是否允许通过临时端口 (1024-65535)。
检查路由表配置
路由表负责引导网络流量。验证路由表是否为 Amazon RDS 实例提供了正确的路由。
完成以下步骤:
- 要检查 Amazon RDS 子网的路由表,请运行以下 describe-route-tables 命令:
CMD
**注意:**将 SUBNET-ID 替换为您的 RDS 子网 ID。 - 对于公共访问,请验证是否存在指向互联网网关的路由 ([IP_ADDRESS])。
- 对于私有访问,请根据需要验证指向 NAT 网关、VPC 对等连接或 VPN 网关的路由。
有关更多信息,请参阅如何对我的 Amazon RDS 数据库实例的 IP 地址问题进行故障排除?
检查 DNS 解析失败
验证 Amazon RDS 端点是否解析为正确的 IP 地址。
完成以下步骤:
-
要从客户端测试 DNS 解析,请运行以下命令:
nslookup RDS-ENDPOINT**注意:**将 RDS-ENDPOINT 替换为您的 RDS 实例端点。
-
要使用 dig 命令进行测试,请运行以下命令:
dig RDS-ENDPOINT -
如果 DNS 解析失败,请检查 Amazon VPC DNS 设置或使用其他 DNS 服务器。
测试网络连接
在测试数据库身份验证之前,请先验证与 RDS 实例的网络连接。
完成以下步骤:
-
要测试与 Amazon RDS 实例的连接,请运行以下 telnet 命令:
telnet RDS-ENDPOINT DATABASE-PORT**注意:**将 RDS-ENDPOINT 替换为您的 RDS 端点,将 DATABASE-PORT 替换为您的数据库端口。
-
要使用 netcat 进行测试,请运行以下命令:
nc -zv RDS-ENDPOINT DATABASE-PORT -
如果连接成功,则问题可能与身份验证相关。如果失败,则问题与网络相关。
有关更多信息,请参阅使用 VPC Reachability Analyzer 对与 Amazon RDS 数据库的网络连接进行故障排除。
检查数据库身份验证
验证您的数据库凭据和身份验证方法。
完成以下步骤:
- 要测试 MySQL 的密码身份验证,请运行以下命令:
**注意:**将 RDS-ENDPOINT 替换为您的端节,将 DATABASE-PORT 替换为您的端口,将 USERNAME 替换为您的数据库用户名。mysql -h RDS-ENDPOINT -P DATABASE-PORT -u USERNAME -p - 要测试 PostgreSQL 的密码身份验证,请运行以下命令:
**注意:**将 RDS-ENDPOINT、DATABASE-PORT、USERNAME 和 DATABASE-NAME 替换为您的值。psql -h RDS-ENDPOINT -p DATABASE-PORT -U USERNAME -d DATABASE-NAME - 如果需要重置主密码,请运行以下 modify-db-instance 命令:
**注意:**将 DB-INSTANCE-NAME 替换为您的实例标识符,将 NEW-PASSWORD 替换为您的新密码。aws rds modify-db-instance \ --db-instance-identifier DB-INSTANCE-NAME \ --master-user-password NEW-PASSWORD \ --apply-immediately
检查连接限制
验证 Amazon RDS 实例是否尚未达到连接限制。
完成以下步骤:
-
要检查 MySQL 的当前连接数,请连接到您的数据库并运行以下查询:
SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections'; -
要检查 PostgreSQL 的当前连接数,请运行以下查询:
SELECT count(*) FROM pg_stat_activity; SHOW max_connections; -
要检查 MySQL 中的连接错误,请运行以下查询:
SHOW STATUS LIKE 'Connection_errors%'; SHOW STATUS LIKE 'Max_used_connections';
如果 Amazon RDS 实例已达到连接限制,请完成以下步骤:
-
要识别可以终止的空闲连接,请运行以下 MySQL 查询:
SELECT id, user, host, db, command, time, state, info FROM information_schema.processlist WHERE command = 'Sleep' AND time > 300 ORDER BY time DESC; -
要终止 MySQL 中的空闲连接,请运行以下命令:
CALL mysql.rds_kill(CONNECTION-ID);**注意:**将 CONNECTION-ID 替换为步骤 1 中的连接 ID。
-
要增加 max_connections 参数,请运行以下 modify-db-parameter-group 命令:
aws rds modify-db-parameter-group \ --db-parameter-group-name PARAMETER-GROUP-NAME \ --parameters "ParameterName=max_connections,ParameterValue=NEW-VALUE,ApplyMethod=pending-reboot"**注意:**将 PARAMETER-GROUP-NAME 替换为您的参数组名称,将 NEW-VALUE 替换为您所需的连接限制。更改 max_connections 后需要重启。
-
要应用参数更改,请重启您的 Amazon RDS 实例。运行以下 reboot-db-instance 命令:
aws rds reboot-db-instance \ --db-instance-identifier DB-INSTANCE-NAME**注意:**将 DB-INSTANCE-NAME 替换为您的 Amazon RDS 实例标识符。
-
要使用 RDS 代理实现连接池,请运行以下 create-db-proxy 命令:
aws rds create-db-proxy \ --db-proxy-name PROXY-NAME \ --engine-family mysql \ --target-group-config DBInstanceIdentifiers=DB-INSTANCE-NAME \ --vpc-subnet-ids SUBNET-ID-1,SUBNET-ID-2 \ --auth AuthScheme=SECRETS,SecretArn=SECRET-ARN**注意:**将 PROXY-NAME、DB-INSTANCE-NAME、SUBNET-ID-1、SUBNET-ID-2 和 SECRET-ARN 替换为您的值。
检查用户特定的连接限制
完成以下步骤:
-
要检查当前的 max_user_connections,请运行以下查询:
SHOW VARIABLES LIKE 'max_user_connections'; -
要检查每个用户的当前连接数,请运行以下查询:
SELECT user, COUNT(*) as connection_count FROM information_schema.processlist GROUP BY user ORDER BY connection_count DESC; -
要检查特定用户是否已达到其连接限制,请运行以下查询:
SELECT user, max_user_connections FROM mysql.user WHERE user = 'USERNAME';**注意:**将 USERNAME 替换为遇到连接问题的具体用户名。
即使未达到总连接限制,max_user_connections 参数也可以阻止特定用户进行连接。
如果 Amazon RDS 实例已达到最大用户连接数,请完成以下步骤:
- 要全局增加 max_user_connections 参数,请运行以下 modify-db-parameter-group 命令:
**注意:**将 PARAMETER-GROUP-NAME 替换为您的参数组名称,将 NEW-VALUE 替换为您所需的每个用户的连接限制。aws rds modify-db-parameter-group \ --db-parameter-group-name PARAMETER-GROUP-NAME \ --parameters "ParameterName=max_user_connections,ParameterValue=NEW-VALUE,ApplyMethod=immediate" - 要修改特定用户账户的连接限制,请运行以下查询:
**注意:**将 USERNAME 替换为用户名,将 NEW-LIMIT 替换为该用户所需的连接限制。ALTER USER 'USERNAME'@'%' WITH MAX_USER_CONNECTIONS NEW-LIMIT;
有关更多信息,请参阅 MySQL 网站上的 Setting Account Resource Limits(设置账户资源限制)。
检查连接错误限制
完成以下步骤:
-
要检查 Amazon RDS for MySQL 当前的 max_connect_errors,请运行以下查询:
SHOW VARIABLES LIKE 'max_connect_errors'; -
要检查当前是否有任何主机被屏蔽,请运行以下查询:
SELECT * FROM performance_schema.host_cache WHERE SUM_CONNECT_ERRORS > 0; -
要检查主机的当前连接错误数,请运行以下查询:
SELECT HOST, SUM_CONNECT_ERRORS, COUNT_HANDSHAKE_ERRORS, COUNT_AUTHENTICATION_ERRORS FROM performance_schema.host_cache WHERE HOST = 'YOUR-CLIENT-IP';**注意:**将 YOUR-CLIENT-IP 替换为您实际的客户端 IP 地址。
-
要刷新主机缓存并解除对所有主机的屏蔽,请运行以下查询:
FLUSH HOSTS; -
要增加 max_connect_errors 参数以防止将来受阻,请运行以下 modify-db-parameter-group 命令:
aws rds modify-db-parameter-group \ --db-parameter-group-name PARAMETER-GROUP-NAME \ --parameters "ParameterName=max_connect_errors,ParameterValue=NEW-VALUE,ApplyMethod=immediate"**注意:**将 PARAMETER-GROUP-NAME 替换为您的参数组名称,将 NEW-VALUE 替换为更高的限额,例如 1000000。
-
要验证参数更改是否已应用,请再次运行步骤 1 中的查询并确认新值。
有关更多信息,请参阅如何解决 Amazon RDS for MySQL 中的 "Host is blocked because of many connections errors" 错误?

