跳至内容

如何排查 Amazon RDS 代理中的连接固定问题?

3 分钟阅读
0

我想排查使用 Amazon Relational Database Services (Amazon RDS) 代理访问目标数据库时的连接固定问题。

解决方法

查看 CloudWatch 指标

完成以下步骤:

  1. 打开 Amazon CloudWatch 控制台
  2. 在导航窗格中,选择 Metrics(指标),然后选择 All Metrics(所有指标)。
  3. Browse(浏览)选项卡中,选择 RDS,然后选择 Per-Proxy Metrics(每个代理的指标)。
  4. 搜索 DatabaseConnectionsCurrentlySessionPinned 指标。

DatabaseConnectionsCurrentlySessionPinned 指标显示 RDS 代理每 60 秒固定的数据库连接数量。当客户端请求中的操作更改了会话状态时,RDS 代理会固定这些连接。

**注意:**DatabaseConnectionsCurrentlySessionPinned 指标在 RDS 代理检测到第一个固定连接时开始记录,并在固定连接的值为 NULL 时停止记录。

查看 RDS 代理日志事件

要获取有关 SQL 语句和 RDS 代理内部操作的详细信息,请修改代理以启用增强的日志记录。

**注意:**增强的日志记录会在 24 小时后自动关闭。

要对连接固定问题进行故障排除,请查看 RDS 代理日志事件。

完成以下步骤:

  1. 打开 CloudWatch 控制台
  2. 在导航窗格中,选择 Logs(日志),然后选择 Log groups(日志组)。
  3. 选择代理的日志组,例如 /aws/rds/proxy/name of your proxy
  4. Log Streams(日志流)选项卡中,选择日志流以查看日志事件。

运行 CloudWatch Log Insights 查询以检测异常

要访问 CloudWatch Logs Insights 中的查询编辑器,请完成以下步骤:

  1. 打开 CloudWatch 控制台
  2. 在导航窗格中,选择 Logs(日志),然后选择 Log Insights

使用查询编辑器运行以下查询。在每个查询中,将 proxy-name 替换为您的代理名称。

要确定单个连接被固定的原因,请运行以下查询:

fields @message  
| sort @timestamp asc  
| filter @logStream like '{proxy-name}'  
| filter @message like /The client session was pinned to the database connection/

要按数量获取固定次数最多的连接,请运行以下查询:

fields @message  
| sort @timestamp asc  
| filter @logStream like '{proxy-name}'  
| filter @message like /The client session was pinned to the database connection/  
| parse 'Reason: \\\*' as reason  
| stats count() as reasonCount by reason  
| sort by reasonCount desc  
| limit 20

解决会话设置更改问题

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

当客户端连接更改会话级变量设置时,RDS 代理会固定连接,因为它无法重用该连接。

然后,您会收到以下错误消息:

"The client session was pinned to the database connection [dbConnection=xxxx] for the remainder of the session.The proxy can't reuse this connection until the session ends.Reason: SQL changed session settings that the proxy doesn't track.Consider moving session configuration to the proxy's initialization query."

所有数据库连接必须具有相同的设置。要解决此问题,请在创建代理时添加初始化查询设置。指定代理在打开每个新数据库连接时要运行的 SQL 语句。要修改现有代理,您可以使用 Amazon RDS 控制台或运行 modify-db-proxy-target-group AWS CLI 命令。

**重要事项:**不要在初始化查询中添加敏感数据,例如密码或长期有效的加密密钥。身份验证或加密方法无法保护这些数据,因为任何有权访问您的代理目标组配置的人员都可以查看初始化查询。

通常,您可以将初始化查询设置与 SET 语句结合使用,以便每个连接都具有相同的设置。要在单个 SET 语句中包含多个变量,请使用逗号分隔符。

例如,您可以运行以下命令在初始化查询中设置时区变量:

aws rds modify-db-proxy-target-group --target-group-name default --db-proxy-name proxy --connection-pool-config '{ > "InitQuery": "SET time_zone = \"+00:00\";" > }'

**注意:**将 proxy 替换为您的代理名称。

解决解析消息和协议级预处理语句错误

当特定库(例如 asyncpg/mysql.connector)在内部使用协议级预处理语句时,您会收到以下错误消息之一:

  • "The client session was pinned to the database connection [dbConnection=xxxx] for the remainder of the session.The proxy can't reuse this connection until the session ends.Reason: A parse message was detected."
  • "The client session was pinned to the database connection [dbConnection=xxxx] for the remainder of the session.The proxy can't reuse this connection until the session ends.Reason: A protocol-level prepared statement was detected."

如果客户端使用预处理语句,则 RDS 代理会固定连接

要解决此问题,请在代理显式使用连接后,关闭所有使用预处理语句的连接。

解决大型 SQL 查询问题

您可能会收到以下错误消息:

"The client session was pinned to the database connection [dbConnection=xxxx] for the remainder of the session.The proxy can't reuse this connection until the session ends.Reason: The connection ran a SQL query which exceeded the 16384 byte limit."

对于 RDS 代理支持的所有数据库引擎,当遇到大于 16KB 的 SQL 语句时,RDS 代理会固定会话。最佳做法是缩减 SQL 语句的大小。例如,您可以移除注释或限制别名的使用。

减少连接固定

为避免不必要的数据库请求导致代理固定连接,请执行以下操作:

  • 移除引发连接固定的数据库操作。
  • 使用批量操作将相关请求合并为单个查询。

为标准化连接设置,请执行以下操作:

  • 保持连接之间的变量和配置设置一致,以支持事务级重用。
  • 对于 Amazon RDS for PostgreSQL,在数据库端设置变量。当您在客户端设置变量时,RDS 代理会固定数据库连接。
  • 对于 Amazon RDS for MySQL 数据库,使用会话绑定筛选条件来指定可以安全避免会话绑定要求的数据库操作。

最佳做法是将常见的 SET 语句移至代理的初始化查询中,以便实现所有连接的统一初始化,并保持事务级重用。

相关信息

RDS 代理的概念和术语

使用 Amazon CloudWatch 监控 RDS 代理指标