调试连接问题

简介

通常,连接问题分为以下三个方面:

  • 正在连接 - 您可以通过网络访问实例吗?
  • 正在授权 - 您有权连接到实例吗?
  • 正在进行身份验证 - 数据库是否接受您的数据库凭据?

每个连接问题都可以进一步细分为不同的调查路径。以下部分包含您可以自己提出的一些问题示例,以帮助进一步缩小问题的范围:

连接问题核对清单

错误消息

如需了解具体的 API 错误消息,请参阅错误消息参考页面。

其他连接问题排查

如有其他问题,请参阅问题排查页面中的连接部分。

常见连接问题

验证您的应用是否正确关闭连接

如果您看到包含“Aborted connection nnnn to db:”的错误,这通常表明您的应用未以正确的方式停止连接。网络问题也可能会导致此错误。此错误并不意味着您的 Cloud SQL 实例存在问题。 此外,我们还建议您运行 tcpdump 来检查数据包以找出问题根源。

如需查看连接管理最佳做法的示例,请参阅管理数据库连接

验证您的证书未过期

如果您的实例配置为使用 SSL,请转到 Cloud Console 中的“Cloud SQL 实例”页面并打开该实例。打开实例的连接页面,并确保您的服务器证书有效。如果证书已过期,您必须添加一个新证书并轮替至该证书。

验证您有权进行连接

如果您的连接失败,请检查您是否有权进行连接:

  • 如果您在使用 IP 地址进行连接时遇到问题,例如您使用 psql 客户端从本地环境进行连接,请确保您用于连接的 IP 地址有权连接到 Cloud SQL 实例。

    使用专用 IP 地址连接到 Cloud SQL 实例时会自动获得授权来使用 RFC 1918 地址范围。因此,所有专用客户端都可以在不经过 Cloud SQL Auth 代理的情况下访问数据库。非 RFC 1918 地址范围必须配置为已获授权的网络

    默认情况下,Cloud SQL 不会从 VPC 中获知非 RFC 1918 子网路由。您需要将网络对等互连更新到 Cloud SQL,以导出所有非 RFC 1918 路由。例如:

    gcloud compute networks peerings update cloudsql-postgres-googleapis-com \
    --network=NETWORK \
    --export-subnet-routes-with-public-ip \
    --project=PROJECT_ID
    
  • 此处为您的当前 IP 地址

  • 尝试使用 gcloud sql connect 命令连接到您的实例。该命令会向您的 IP 地址授予一小段时间的权限。您可以在安装有 Cloud SDK 和 psql 客户端的环境中运行该命令。您还可以在 Cloud Shell 中运行此命令。Cloud Shell 在 Google Cloud Console 中可用,并预安装有 Cloud SDK 和 psql 客户端。Cloud Shell 提供了一个可用于连接到 Cloud SQL 的 Compute Engine 实例。
  • 通过授权 0.0.0.0/0 暂时允许所有 IP 地址连接到实例。

确认连接方式

如果您在连接时收到类似如下的错误消息:

FATAL: database `user` does not exist.

gcloud sql connect --user 命令仅适用于默认用户 (postgres)。解决方法是使用默认用户进行连接,然后使用 "\c" psql 命令以其他用户身份重新连接。

确定发起连接的方式

您可以通过连接到数据库并运行以下命令来查看有关当前连接的信息:

SELECT * from pg_stat_activity ;

显示 IP 地址(如 1.2.3.4)的连接是使用 IP 进行连接的。 带有 cloudsqlproxy~1.2.3.4 的连接使用的是 Cloud SQL Auth 代理,其他的连接则是从 App Engine 发起。某些 Cloud SQL 内部进程可使用来自 localhost 的连接。

了解连接限制

Cloud SQL 实例没有 QPS 限制。但是,这些实例存在连接、大小和 App Engine 特定方面的限制。请参阅配额和限制

数据库连接会消耗服务器和连接应用上的资源。请始终采用最佳连接管理做法,以最大限度减少应用的占用空间,并降低超出 Cloud SQL 连接限制的可能性。 如需了解详情,请参阅管理数据库连接

显示连接和线程

要查看在数据库上运行的进程,请使用 pg_stat_activity 表:

select * from pg_stat_activity;

连接超时(来自 Compute Engine)

与 Compute Engine 实例的连接在处于非活跃状态 10 分钟后会超时,这可能会影响 Compute Engine 实例与 Cloud SQL 实例之间长期未使用的连接。如需了解详情,请参阅 Compute Engine 文档中的网络和防火墙

如需让长期未使用的连接保持活跃状态,您可以设置 TCP keepalive。以下命令将 TCP keepalive 值设置为一分钟,并使该配置即便在实例重新启动后仍保持永久有效。

显示当前的 tcp_keepalive_time 值。

cat /proc/sys/net/ipv4/tcp_keepalive_time

将 tcp_keepalive_time 设置为 60 秒,并在重新启动后使其成为永久状态。

echo 'net.ipv4.tcp_keepalive_time = 60' | sudo tee -a /etc/sysctl.conf

应用更改。

sudo /sbin/sysctl --load=/etc/sysctl.conf

显示 tcp_keepalive_time 值以验证已应用更改。

cat /proc/sys/net/ipv4/tcp_keepalive_time

用于调试连接的工具

最基本的工具包括 pingtraceroute

Ping

Ping 会执行基本测试,以确定目的地(“Cloud SQL 实例”)是否可从来源中获得。Ping 会将 ICMP Echo Request 数据包发送到 Cloud SQL 实例,并预计会返回 ICMP Echo Reply。如果 ping 失败,则表示没有从来源到目的地的路由。但成功并不意味着您的数据包可以到达,通常,只是能访问 Cloud SQL 实例。

虽然 ping 可以确定主机处于活跃状态并做出响应,但不能保证可靠。为安全起见,部分网络提供商会屏蔽 ICMP,这可能会使连接调试更加困难。

Traceroute

Traceroute 测试完整路由网络数据包是否从一个主机传送到另一个主机。它会显示数据包在此过程中执行的所有步骤(“跃点”)以及每个步骤所花费的时间。如果数据包没有一直到达目的地,则 traceroute 不会完成,但会以一系列星号结尾。在这种情况下,请查找在此过程中成功访问的最后一个 IP 地址。这是连接中断的位置。

Traceroute 可能超时。如果未正确配置沿途的网关,无法将数据包传递给下一个跃点,则其会失败。

如果 traceroute 无法完成,您或许可以找出其停止位置。找到 traceroute 输出中列出的最后一个 IP 地址,然后通过浏览器搜索 who owns [IP_ADDRESS]。结果不一定会显示地址所有者,但值得一试。

mtr

mtr 工具是一种 traceroute 形式,可保持活跃并持续更新,这类似于 top 命令在本地进程的工作方式。

tcpdump

tcpdump 是用来捕获数据包的工具。在调试连接问题时,强烈建议运行 tcpdump 来捕获和检查主机和 CloudSQL 实例之间的数据包。

查找本地 IP 地址

如果您不知道主机的本地地址,请运行 ip -br address show 命令。在 Linux 上,系统会显示网络接口、接口状态、本地 IP 地址和 MAC 地址。例如:eth0 UP 10.128.0.7/32 fe80::4001:aff:fe80:7/64

或者,您也可以运行 ipconfigifconfig 来查看网络接口的状态。

使用 Connectivity Test 进行测试

Connectivity Tests 是一种诊断工具,可让您检查网络中端点之间的连接。它会分析您的配置,并且在某些情况下会执行运行时验证。它现在支持 Cloud SQL。请按照这些说明使用 Cloud SQL 实例运行测试。

测试连接

您可以使用 psql 客户端来测试从本地环境建立连接的能力。如需了解详情,请参阅使用 IP 地址连接 psql 客户端使用 Cloud SQL Auth 代理连接 psql 客户端

确定应用的 IP 地址

为确定运行应用的计算机的 IP 地址,以便授权该地址访问 Cloud SQL 实例,您可以使用以下可选方法之一:

  • 如果计算机不在代理或防火墙后面,请登录计算机并使用此链接确定其 IP 地址。
  • 如果计算机在代理或防火墙后面,请登录计算机,并使用 whatismyipaddress.com 等工具或服务来确定其真实的 IP 地址。

打开本地端口

如需验证主机是否正在侦听您所认为的端口,请运行 ss -tunlp4 命令。这会告诉您哪些端口已打开并正在侦听。 例如,如果您正在运行 PostgreSQL 数据库,则应该启动并侦听端口 5432。对于 SSH,您应该会看到端口 22。

所有本地端口活动

使用 netstat 命令可查看所有本地端口活动。例如,netstat -lt 会显示当前所有活跃端口。

使用 telnet 连接到 Cloud SQL 实例

如需验证您是否可以使用 TCP 连接到 Cloud SQL 实例,请运行 telnet 命令。Telnet 会尝试连接到您指定的 IP 地址和端口。

例如,如果您的 Cloud SQL 实例正在运行 PostgreSQL 数据库,则您应该能够使用 telnet 通过端口 5432 连接到该实例:telnet 35.193.198.159 5432

成功后,您会看到以下内容:

Trying 35.193.198.159...

Connected to 35.193.198.159.

失败时,您会看到 telnet 挂起,直至您强行关闭尝试:

Trying 35.193.198.159...

^C.

客户端验证

客户端身份验证由名为 pg_hba.conf 的配置文件控制(HBA 表示基于主机的身份验证)。

确保更新源数据库上 pg_hba.conf 文件的复制连接部分,以接受来自 Cloud SQL VPC 的 IP 地址范围的连接。

Cloud Logging

Cloud SQL 和 Cloud SQL 使用 Cloud Logging。请参阅 Cloud Logging 文档了解完整信息,并查看 Cloud SQL 示例查询

查看日志

您可以查看 Cloud SQL 实例和其他 Google Cloud 项目(如 Cloud VPN 或 Compute Engine 实例)的日志。如需查看 Cloud SQL 实例日志条目的日志,请按如下所述操作:

控制台

  1. 在 Google Cloud Console 中,转到 Cloud Logging 页面。

    转到 Cloud Logging

  2. 在页面顶部选择一个现有 Cloud SQL 项目。
  3. 在查询构建器中,添加以下内容:
    • 资源:选择 Cloud SQL 数据库。在该对话框中,选择一个 Cloud SQL 实例。
    • 日志名称:滚动到 Cloud SQL 部分,并为您的实例选择相应的日志文件。例如:
      • cloudsql.googleapis.com/postgres.log
    • 严重程度:选择一个日志级别。
    • 时间范围:选择预设范围或创建自定义范围。

gcloud

使用 gcloud logging 命令查看日志条目。 在下面的示例中,替换 PROJECT_IDlimit 标志是一个可选参数,用于指示要返回的最大条目数。

gcloud logging read "projects/PROJECT_ID/logs/cloudsql.googleapis.com/postgres.log" \
--limit=10

专用 IP 地址

使用专用 IP 地址连接到 Cloud SQL 实例时会自动获得授权来使用 RFC 1918 地址范围。非 RFC 1918 地址范围必须在 Cloud SQL 中配置为已获授权的网络。您还需要将网络对等互连更新到 Cloud SQL,以导出所有非 RFC 1918 路由。例如:

gcloud compute networks peerings update cloudsql-postgres-googleapis-com 
--network=NETWORK
--export-subnet-routes-with-public-ip
--project=PROJECT_ID

系统会预留 IP 范围 172.17.0.0/16 用于 Docker 桥接网络。您无法访问任何使用该范围内的 IP 地址创建的 Cloud SQL 实例,无法从该范围内的任何 IP 地址连接到使用专用 IP 地址的 Cloud SQL 实例。

VPN 问题排查

请参阅 Cloud VPN 问题排查页面。