调试连接问题

简介

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

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

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

连接问题核对清单

错误消息

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

其他连接问题排查

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

常见连接问题

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

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

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

验证您的证书未过期

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

验证您有权进行连接

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

  • 如果您在使用 IP 地址进行连接时遇到问题,例如使用 mysql 客户端从本地环境进行连接,请确保您用于连接的 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-mysql-googleapis-com \
    --network=NETWORK \
    --export-subnet-routes-with-public-ip \
    --project=PROJECT_ID
    
  • 此处为您的当前 IP 地址

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

确认连接方式

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

ERROR 1045 (28000): Access denied for user 'root'@'1.2.3.4' (using password: NO)

请确认您是否提供了密码。

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

ERROR 1045 (28000): Access denied for user 'root'@'1.2.3.4' (using password: YES)

请确保使用正确的密码,并通过 SSL 进行连接(如果实例要求)。

确定发起连接的方式

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

SHOW PROCESSLIST;

显示 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 连接限制的可能性。 如需了解详情,请参阅管理数据库连接

显示连接和线程

如果您收到“连接过多”错误消息,或者想要查看实例上发生的情况,可使用 SHOW PROCESSLIST 显示连接数和线程数。

MySQL 客户端运行以下命令:

mysql> SHOW PROCESSLIST;

您将获得类似如下所示的输出:

+----+-----------+--------------+-----------+---------+------+-------+----------------------+
| Id | User      | Host         | db        | Command | Time | State | Info                 |
+----+-----------+--------------+-----------+---------+------+-------+----------------------+
|  3 | user-name | client-IP    | NULL      | Query   |    0 | NULL  | SHOW processlist     |
|  5 | user-name | client-IP    | guestbook | Sleep   |    1 |       | SELECT * from titles |
| 17 | user-name | client-IP    | employees | Query   |    0 | NULL  | SHOW processlist     |
+----+-----------+--------------+-----------+---------+------+-------+----------------------+
3 rows in set (0.09 sec)

如需了解如何解释从 PROCESSLIST 返回的列,请参阅 MySQL 参考文档

如需获取线程数,您可以使用:

mysql> SHOW STATUS WHERE Variable_name = 'Threads_connected';

您将获得类似如下所示的输出:

+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 7     |
+-------------------+-------+
1 row in set (0.08 sec)

连接超时(来自 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

与 IPv6 连接

如果您在连接时收到以下任一错误消息:

Can't connect to MySQL server on '2001:1234::4321' (10051)
Can't connect to MySQL server on '2001:1234::4321' (101)

这可能是由于您尝试连接到实例的 IPv6 地址,但是您的工作站中无可用的 IPv6 地址。您可以通过转到 ipv6.google.com 来验证 IPv6 地址在您的工作站上是否正常可用。如果未能加载,则表明您没有可用的 IPv6 地址。请改为连接到 IPv4 地址或 Cloud SQL 实例。您可能首先需要将 IPv4 地址添加到实例

用于调试连接的工具

tcpdump

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

查找本地 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 实例运行测试。

测试连接

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

确定应用的 IP 地址

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

  • 如果计算机不在代理或防火墙后面,请登录计算机并使用“我的 IP 是什么?”网站来确定其 IP 地址。
  • 如果计算机在代理或防火墙后面,请登录计算机,并使用 whatismyipaddress.com 等工具或服务来确定其真实的 IP 地址。

打开本地端口

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

所有本地端口活动

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

使用 telnet 连接到 Cloud SQL 实例

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

例如,如果您的 Cloud SQL 实例正在运行 MySQL 数据库,则您应该能够使用 telnet 通过端口 3306 连接到该实例:telnet 35.193.198.159 3306。 例如,如果您的 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 控制台中,转到 Cloud Logging 页面。

    转到 Cloud Logging

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

gcloud

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

gcloud logging read "projects/PROJECT_ID/logs/cloudsql.googleapis.com/mysql-general.log" \
--limit=10
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-mysql-googleapis-com 
--network=NETWORK
--export-subnet-routes-with-public-ip
--project=PROJECT_ID

VPN 问题排查

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