Skip to content
Database

连接管理

Using your connections resourcefully

连接 #

🌐 Connections

每个 Compute Add-On 都有预配置的直接连接数量和 Supavisor 池大小。本指南讨论了如何有效地观察和管理它们。

🌐 Every Compute Add-On has a pre-configured direct connection count and Supavisor pool size. This guide discusses ways to observe and manage them resourcefully.

配置 Supavisor 的池大小 #

🌐 Configuring Supavisor's pool size

你可以通过在 数据库设置 的“连接池”部分更改池大小,来调整 Supavisor 可以管理的数据库连接数量:

🌐 You can change how many database connections Supavisor can manage by altering the pool size in the "Connection pooling" section of the Database Settings:

Connection Info and Certificate.

一般的规则是,如果你大量使用 PostgREST 数据库 API,你应该注意不要将连接池大小提高到超过数据库最大连接数的 40%。否则,你可以将 80% 的连接数分配给连接池。这为认证服务器和其他工具留出了足够的空间。

🌐 The general rule is that if you are heavily using the PostgREST database API, you should be conscientious about raising your pool size past 40% of the Database Max Connections. Otherwise, you can commit 80% to the pool. This leaves adequate room for the Authentication server and other utilities.

这些数字只是概括,而且取决于你使用的其他 Supabase 产品以及使用的程度。实际数值取决于你同时在线的高峰连接数。例如,如果你在一周内只使用了 80 个连接,而你的数据库最大连接数设置为 500,那么实际上你可以把剩下的 420(减去合理的缓冲)分配给更多的需求。

🌐 These numbers are generalizations and depends on other Supabase products that you use and the extent of their usage. The actual values depend on your concurrent peak connection usage. For instance, if you were only using 80 connections in a week period and your database max connections is set to 500, then realistically you could allocate the difference of 420 (minus a reasonable buffer) to service more demand.

监控连接 #

🌐 Monitoring connections

记录历史用法 #

🌐 Capturing historical usage

仪表盘监控图表 #

🌐 Dashboard monitoring charts

Database client connections chart

对于团队和企业计划,Supabase 在仪表板中直接提供高级遥测图表。Database client connections 图表显示按连接类型划分的历史连接数据:

🌐 For Teams and Enterprise plans, Supabase provides Advanced Telemetry charts directly within the Dashboard. The Database client connections chart displays historical connection data broken down by connection type:

  • Postgres:直接从你的应用连接
  • PostgREST:来自 PostgREST API 层的连接
  • 保留:Supabase 服务的管理连接
  • 认证:来自 Supabase 认证服务的连接
  • 存储:来自 Supabase 存储服务的连接
  • 其他角色:各种数据库连接

这个图表帮助你监控连接池的使用情况,发现连接泄漏,并进行容量规划。它还显示了与你的计算规模最大连接数相关的参考线。

🌐 This chart helps you monitor connection pool usage, identify connection leaks, and plan capacity. It also shows a reference line for your compute size's maximum connection limit.

想了解更多关于使用这些监控图表的详情,请查看 报告指南。

🌐 For more details on using these monitoring charts, see the Reports guide.

Grafana 仪表板 #

🌐 Grafana Dashboard

Supabase 提供了一个 Grafana 仪表板,可以记录和可视化超过 200 个项目指标,包括连接情况。有关设置说明,请查看 指标文档。

🌐 Supabase offers a Grafana Dashboard that records and visualizes over 200 project metrics, including connections. For setup instructions, check the metrics docs.

它的“客户端连接”图显示了 Supavisor 和 Postgres 的连接情况 客户端连接图

🌐 Its "Client Connections" graph displays connections for both Supavisor and Postgres client connection graph

观察实时连接 #

🌐 Observing live connections

pg_stat_activity 是一个特殊的视图,它可以跟踪你的数据库正在运行的进程,包括活跃的连接。它特别有用来判断空闲的客户端是否占用了连接插槽。

查询所有活动连接:

🌐 Query to get all live connections:

SELECT
pg_stat_activity.pid as connection_id,
ssl,
datname as database,
usename as connected_role,
application_name,
client_addr as IP,
query,
query_start,
state,
backend_start
FROM pg_stat_ssl
JOIN pg_stat_activity
ON pg_stat_ssl.pid = pg_stat_activity.pid;

解读这个查询:

🌐 Interpreting the query:

列描述
connection_id连接ID
ssl是否使用SSL
database连接的数据库名称(通常是 postgres)
usename连接用户的角色
application_name连接应用的名称
client_addr连接服务器的IP地址
query连接执行的最后一次查询
query_start最后一次查询执行的时间
state查询状态。有关完整的值列表及其含义,请参见 会话状态
backend_start连接建立的时间戳

用户名可以用来识别来源:

🌐 The username can be used to identify the source:

角色API/工具
supabase_adminSupabase 用于监控和 Realtime
authenticator数据 API (PostgREST)
supabase_auth_admin认证
supabase_storage_admin存储
supabase_replication_admin同步只读副本
postgresSupabase 仪表板和外部工具(例如 Prisma、SQLAlchemy、PSQL...)
用户定义的自定义角色外部工具(例如 Prisma、SQLAlchemy、PSQL...)

诊断卡住和阻塞的查询 #

🌐 Diagnosing stuck and blocked queries

如果你的应用运行缓慢或卡住,原因通常现在就能在 pg_stat_activity 中看到——可能是某个查询卡住了、一个会话阻塞了其他会话,或者有事务被错误地保持打开。本节将讲解如何查看会话状态、找出阻塞查询的原因,以及停止负责的会话。

🌐 If your application is slow or hanging, the cause is usually visible right now in pg_stat_activity - a query that's stuck, one session blocking others, or a transaction left open by mistake. This section covers how to read a session's state, find out what's blocking a query, and stop the session responsible.

会话状态 #

🌐 Session states

pg_stat_activity上的state列可以是六个值中的一个:

🌐 The state column on pg_stat_activity can be one of six values:

状态意思
active会话当前正在执行查询。查询执行时间超过预期值得调查,但本身活跃会话数量非零是正常的。
idle会话已连接,正在等待客户端发送新命令。对于连接池或长时间连接来说,这是正常的。
idle in transaction会话存在一个未完成的事务,但当前没有执行查询。这会持有锁并阻止表清理,只要事务保持打开状态,通常意味着应用忘记提交或回滚。
idle in transaction (aborted)事务中的最后一条语句失败了。Postgres 会在中止时释放事务的一般锁——例外是会话级别的咨询锁(pg_advisory_lock,而不是 pg_advisory_xact_lock),这些锁会一直保持,直到显式解锁或会话结束。客户端仍然需要发送 rollback 来关闭事务,这样会话才会接受新的命令。
fastpath function call会话正在通过 Postgres 的低级 fastpath 协议执行一个函数,最常用于大对象的读取或写入。很少见,而且通常很短暂。
disabled本次会话关闭了活动跟踪 (track_activities),所以 Postgres 不会记录其状态或查询。

idle in transaction 是最值得关注的状态。不同于至少在有进展的慢 active 查询,空闲事务会话会一直占着锁,却什么也不做。

查找被屏蔽的查询 #

🌐 Finding blocked queries

Postgres 会跟踪哪些会话在等待被其他会话持有的锁。把查询 pg_stat_activity 和 pg_blocking_pids() 一起运行就可以直接看到这个情况:

🌐 Postgres tracks which sessions are waiting on a lock held by another session. Query pg_stat_activity and pg_blocking_pids() together to see this directly:

select
a.pid,
a.usename as role_name,
a.application_name,
a.state,
a.query,
a.wait_event_type,
a.wait_event,
a.xact_start as transaction_start,
a.query_start,
a.state_change,
pg_blocking_pids(a.pid) as blocked_by
from pg_stat_activity as a
where
a.datname = current_database()
and a.pid != pg_backend_pid()
and a.backend_type = 'client backend'
order by a.query_start asc nulls last;

where 条款会排除查询自身的会话以及 Postgres 的内部后台工作进程(如 autovacuum、WAL 写入程序、像 pg_cron 这样的扩展),所以结果只会显示客户端开启的会话。

🌐 The where clause excludes the query's own session and Postgres's internal background workers (autovacuum, the WAL writer, extensions like pg_cron), so the results only show sessions a client opened.

blocked_by 是一个数组,不是单个值,有两个原因:

  • 如果有几个会话持有的锁与它请求的冲突,一个会话可能同时在等多个会话。
  • 阻塞可以形成链:会话 A 持有一个锁,会话 B 在等 A,会话 C 在等 B。blocked_by 只会列出_直接_阻塞者,所以要追踪一个长队列的根本原因,可能需要通过不止一个会话跟踪这个链。

取消或结束会话 #

🌐 Cancelling or terminating a session

Postgres 给你两种方法来停止会话,它们的行为有所不同:

🌐 Postgres gives you two ways to stop a session, and they behave differently:

  • select pg_cancel_backend(pid); 会取消会话中 当前正在运行的查询,但会保持连接打开。应用会收到一个失败的查询结果,然后可以继续使用这个连接。
  • select pg_terminate_backend(pid); 会完全断开会话连接。

使用哪一个取决于会话的状态:

🌐 Which one to use depends on the session's state:

  • 对于一个因为等待锁或运行时间过长而卡住的 active 会话,先取消它。这是影响最小的做法,而且通常足够让等待解除或停止失控的查询。
  • 对于一个 idle in transaction 的会话,取消操作没用——没有正在运行的查询可以取消,而且打开的事务无论如何都会保持开启。唯一能强制关闭事务并释放其锁的方法是终止该会话。
  • 对于一个 idle in transaction (aborted) 的会话,当事务中止时,它的普通锁已经被释放。正确的做法是让客户端发出 rollback,这样可以干净地关闭事务。将 pg_terminate_backend 保留给无响应的客户端或需要关闭的连接——在这种情况下,它不会释放其他任何东西,除了会话级的建议锁,这个锁会一直存在直到会话结束。

这两个功能都要求你要么是超级用户,要么拥有 pg_signal_backend 角色,或者正在操作你自己的会话——即便是 pg_signal_backend 也不能用来终止属于真正超级用户角色的会话。如果在终止会话时遇到权限错误,可以查看这个故障排除指南。

🌐 Both functions require you to either be a superuser, hold the pg_signal_backend role, or be signalling your own session - and even pg_signal_backend can't be used to stop a session belonging to an actual superuser role. If you hit a permission error while terminating a session, see this troubleshooting guide.


如果你在使用 Supabase,你可以在项目的 数据库连接 页面上看到所有这些——会话状态、阻塞链,以及终止卡住会话的方法——而无需编写任何 SQL。

🌐 If you're on Supabase, you can see all of this - session states, blocking chains, and a way to terminate a stuck session - on your project's Database Connections page in the dashboard, without writing any SQL.