Supavisor FAQ
拼车的人能解决什么问题? #
🌐 What problems do poolers solve?
Postgres 与其他数据库不同,它为每个直接连接选择创建新进程,而不是新线程。虽然这个设计带来了很多好处,但它也会增加新连接的启动开销。此外,连接占用更多内存,还可能给 Postgres 的内部调度器带来压力,限制可建立的连接数量。因此,开发者在分配资源时需要谨慎。
🌐 Postgres stands out from other databases by opting to create a new process, not a new thread, for each direct connection. While this design choice brings numerous benefits, it introduces a startup penalty for new connections. Moreover, connections are more memory-intensive and can strain Postgres's internal schedulers, limiting the sustainable number that can be formed. Resultingly, developers must be mindful of how they allocate the resource.
当客户端(后端服务器)连接到 Postgres 时,连接是有状态且持久的,这让客户端可以贪心地占用连接而没有义务释放它们。通常,应用不会持续向数据库发送查询,所以这种模式会低效地使用有限的连接,而这些连接本可以服务其他客户端。
🌐 When a client (backend server) connects to Postgres, the connection is stateful and enduring, allowing clients to greedily hold onto connections without any obligation to give them up. Typically, applications do not continuously send queries to a database, so this pattern underutilizes finite connections that could have serviced other clients.
Postgres 的缺点在处理临时服务器时尤其明显,比如边缘函数。它不仅会为短暂的查询占用连接,还会频繁地打开和关闭连接,给数据库带来压力。
🌐 Postgres's shortcomings are particularly evident when handling transient servers, like edge functions. They not only hoard connections for brief queries but also aggressively open and close connections, straining the database.
拼车的人怎么解决这个问题? #
🌐 How do poolers solve the problem?
连接池最终是数据库连接的负载均衡器。它维护了几个活跃连接,并将它们分配给客户端。这可以减少在 Postgres 上创建新进程的启动成本。连接池还可以更高效地管理数据库有限的连接,只在客户端需要执行查询时才允许访问它们(也就是事务模式)。
🌐 A pooler is ultimately a load balancer for database connections. It maintains several hot connections that it triages to clients. This reduces the startup cost of creating a new process on Postgres. The pooler can also more efficiently manage a database's finite connections by only allowing clients to access them when they need to execute a query (A.K.A. transaction mode).
共享池真的有必要吗? #
🌐 Are poolers necessary?
所有数据库连接库,比如 Prisma、SQLAlchemy 和 Postgres.js,都自带连接池。这些被称为应用端连接池,对于可持续的连接管理来说非常重要。大多数库都有默认的池大小,但对于特定的工作负载可能需要调整。例如,大多数边缘/无服务器函数都是为了处理单个用户的请求。它们通常需要的连接数远少于专用应用服务器(通常 1 个连接就够了)。
🌐 All database connection libraries, such as Prisma, SQLAlchemy, and Postgres.js have built-in poolers. These are known as application-side poolers and they are fundamental for sustainable connection management. Most libraries have default pool sizes that may need to be changed for specific workloads. As an example, most edge/serverless functions are called to service a single user's request. They usually require significantly fewer connections (often 1 is optimal) than a dedicated application server.
注意,像数据库一样,服务器自己也只能维护一定数量的连接。如果你大幅增加连接数,服务器可能无法优雅地管理它们。例如,Prisma 的 默认连接池大小 会自动设置为服务器 CPU 数量的两倍再加一(1 + 2 * CPU 数量)。Prisma 团队之所以选择这个值,是因为它通常在 ORM 的内部架构下性能表现不错。
🌐 Note, that like databases, servers can only maintain a certain amount of connections themselves. If you were to increase the number aggressively, the server may not be able gracefully orchestrate them. For instance, Prisma's default pool size is automatically set to one more than twice the server's CPU count (1 + 2 * num_of_CPUs). The Prisma Team chose this value because it is generally performant with ORM's internal architecture.
在部署到静态架构时,例如长期运行的容器或虚拟机,应用端的连接池本身就足够用了。
🌐 When deploying to static architecture, such as long-standing containers or VMs, application-side poolers are satisfactory on their own.
当你从无服务器/边缘函数、水平自动扩展的服务器连接到你的应用,或者在需要的连接数超过数据库可管理的情况时,最好在应用端的连接池之外,再加一个服务器端的连接池。Supabase 提供了 Supavisor 作为一个选项,但你也可以使用其他替代方案,比如 Prisma 的 Accelerate 或 Cloudflare 的 Hyperdrive。
🌐 When connecting to your application from serverless/edge functions, horizontally auto-scaling servers, or in cases where you need more connections than what the database can manage, it's best to complement application-side poolers with a serverside one. Supabase provides Supavisor as an option, but you could use alternatives, such as Prisma's Accelerate or Cloudflare's Hyperdrive.
它们位于数据库和你的客户端服务器之间。它们专门优化用于维持大量的客户端连接,以及将查询排队和分发到数据库。虽然它们增加了网络复杂性,但在管理能够假设无限数量连接的自动扩展服务器时,它们是必要的。
🌐 They sit between the database and your client servers. They are solely optimized for sustaining high numbers of client connections and queuing and triaging queries to the database. Although they add network complexity, they are necessary when managing auto-scaling servers that can hypothetically form an infinite amount of connections.
连接字符串在哪里 #
🌐 Where are the connection strings
Supabase 提供 3 个数据库连接字符串,如果需要可以同时使用。你可以在仪表板上点击 Connect 找到它们。
🌐 Supabase provides 3 database connection strings that can be used simultaneously if necessary. You can find them on the dashboard by clicking Connect.
直接连接: #
🌐 Direct connections:
“注意默认使用 IPv6 地址。点击这里查看你的网络是否支持 IPv6”
1# Example connection string2postgresql://postgres:[YOUR-PASSWORD]@db.ajrbwkcuthywfihaarmflo.supabase.co:5432/postgres交易模式下的Supavisor(端口6543) #
🌐 Supavisor in transaction mode (port 6543)
1# Example transaction string2postgresql://postgres.ajrbwkcuthywddfihrmflo:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:6543/postgresSupavisor 正在会话模式(端口 5432) #
🌐 Supavisor in session mode (port 5432)
1# Example session string2postgresql://postgres.ajrbwkcuthywfddihrmflo:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgresSupavisor:事务模式 vs 会话模式? #
🌐 Supavisor: Transaction mode vs. Session mode?
当客户端与 Postgres 建立直接连接时,通常会执行几次查询,但可能不会一直使用这个连接。在事务模式下,客户端被允许执行一次查询,然后会被送回比喻中的“等候室”。这样可以防止贪心或长时间闲置的客户端占用连接。在大多数情况下,这会增加查询吞吐量,并且是最优的做法。
🌐 When a client forms a direct connection with Postgres, it usually makes a few queries but may not use the connection the entire time. In transaction mode, a client is allowed to make a single query before being sent back to the figurative "waiting room". This prevents greedy or sedentary clients from hoarding connections. In most cases, this increases query throughput and is optimal.
在会话模式下,一旦池分配器指定了直接连接,它会一直保留给那个客户端,直到客户端主动放弃。
🌐 In session mode, once the pooler assigns a direct connection, it stays with that client until voluntarily surrendered.
这种行为类似于直接连接,让贪心的客户端可以独占连接池。这就引出了一个问题:会话模式的目的是什么?
🌐 This behavior mirrors a direct connection, allowing greedy clients to monopolize the pool. This raises a question: what is the purpose of session mode?
根据你应用的配置,让连接池管理一个等待客户端的队列,比起不断轮询数据库以检查是否有可用连接要更好。会话模式可以让客户端等待最长一分种。如果这对你的应用设计不是特别重要,那么主要好处是它是IPv4 兼容。另外,和事务模式不同,它支持预处理语句。
🌐 Depending on your application's configurations, having the pooler manage a queue of patient clients is preferable to the alternative of constantly polling the database to check for an available connection. Session mode can queue clients for up to a minute. If this isn't particularly relevant to your application design, then the primary benefit is that it is IPv4 compatible. Also, unlike transaction mode, it supports prepared statements.
当像 Prisma 这样的客户端库通过 Supavisor 连接时会发生什么? #
🌐 What happens when a client library, such as Prisma, connects through Supavisor?
当客户端连接到 Postgres 或 Supavisor 时,它们是通过 Postgres Wire 协议进行的。因此,客户端会把与连接池的连接当作直接连接到 Postgres 一样。然后,连接池就像一个信使一样,在数据库和客户端之间顺畅地传递信息。
🌐 When clients connect to either Postgres or Supavisor, they do so with the Postgres Wire Protocol. Because of this, clients treat connections with pooler as if they were directly connected to Postgres. The pooler then smoothly acts as a messenger between the database and the client.
什么是“客户端连接”? #
🌐 What are "client connections"?
总的来说,它们和前端客户端没有关系。它们是可以连接到服务器端连接池的后端服务器连接数量。想象一下有 60 个棋盘的国际象棋比赛。每个棋盘代表数据库中的一个连接。当玩家坐在棋盘旁时,就像客户端连接到数据库一样。他们可以慢慢思考自己的走法,也可以坐在那里不下任何棋子。
🌐 In summary, they have nothing to do with front-end clients. They are the amount of backend-server connections that can connect to a serverside pooler. Imagine a chess tournament with 60 boards. Each board represents a connection in a database. When a player sits down at a board, it's like a client connecting to the database. They can take their time with their moves or sit there, not making any.
但是当比赛名额满了,所有棋盘都被占满时,新玩家就会被拒之门外,被告知稍后再回来看看是否有空桌。
🌐 But when the tournament fills up and all the boards are taken, new players are turned away, and told to check back at a later time to see if a table becomes available.
现在,想象一下,如果比赛组织者决定扩展场地容纳200人,但不增加更多的棋盘。即使所有棋盘都被占满,玩家也不必离开。他们可以在旁等待,一旦棋盘空出来,等待区的人就可以上去替补。同样,如果有人结束了比赛,但想再玩一次,他们可以回到等待区。等待区就代表了“最大客户端连接数”。最终,池的额外容量确保了更少的人会被“比赛”拒之门外。
🌐 Now, imagine the tournament organizers decide to expand the venue to house 200 people without adding more tables. Even when all boards are occupied, players don't have to leave. They can wait in the wings, and the moment a board opens up, someone from the waiting area can take their place. Likewise, if someone ends their game, but wants to play again, they can go back to the waiting area. The waiting area represents the "Max Client Connections". Ultimately, the additional capacity provided by the pooler ensures fewer people are turned away from the "tournament".
在Supavisor的上下文中,“池大小”是什么意思? #
🌐 In the context of Supavisor, what does "pool size" mean?
“连接池大小”指的是连接池在每个唯一用户、数据库和模式组合下可以维持的最大直接连接数。你可以在项目连接页面调整它,以在高效利用资源和应对高峰流量之间取得平衡。
“user+db+mode” 组合是什么意思? #
🌐 What is the "user+db+mode" combination?
Postgres 不是一个数据库。它是一个关系型数据库管理系统(RDMS)。在它里面,你可以创建 Postgres 数据库。在 Supabase 中,一个常见的模式是使用默认的数据库,叫做 postgres,但你也可以创建更多:
🌐 Postgres is not a database. It is a Relational Database Management System (RDMS). Within it, you can spawn Postgres databases. In Supabase, it is a common pattern to use the default database called postgres, but you could create more:
1CREATE DATABASE postgres;2CREATE DATABASE another_database;同样,一个数据库可以有很多数据库用户,但大多数人依赖默认用户 postgres。
🌐 Similarly, a database can have many database users, but most people rely on the default user postgres.
1CREATE USER postgres WITH PASSWORD 'super-secret-password';2CREATE USER some_new_user WITH PASSWORD 'password';模式有交易模式(端口 6543)和会话模式(端口 5432)。
🌐 The modes are transaction (port 6543) and session (port 5432) mode.
“用户+数据库+模式”的组合是由上述变量形成的,并在连接字符串中使用:
🌐 The "user+database+mode" combinations are formed from the above variables and are used within the connection string:
1postgres://[USER].shfmmplnqscentnakbkl:[password]@aws-0-ca-central-1.pooler.supabase.com:[MODE]/[DATABASE]当一个不同的组合连接到你的数据库时,会创建一个新的直接连接池。这意味着如果你有两个组合在连接,而“连接池大小”设置为120,每个组合将有权限建立120个连接。如果它们合起来用完了所有可用的直接连接,这可能会造成问题。
🌐 When a distinct combination connects to your database, a new direct connection pool will be created. That means if you have two combinations connecting and the "Pool Size" is set to 120, each combination will have permission to form 120 connections. This can become problematic if collectively they exhaust all available direct connections.
Supavisor 会立即设定最大连接池大小吗?#
🌐 Does Supavisor immediately establish the max pool size?
不,不是这样的。看看为什么:
🌐 No, it doesn't. See why:
- 在事务模式下,连接池只有在没有足够的连接同时处理所有待处理查询时才会新增连接。如果有10个客户端连接,但单个直接连接就足够应付它们,连接池是不会再创建更多连接的。
- 如果有必要,它可以创建尽可能多的连接,以防查询积压,最多达到“连接池大小”指定的上限。
- 在会话模式下,它会立即为新客户端创建一个新的直接连接,除非已达到“连接池大小”。
- 在事务模式下,一旦建立了直接连接,连接池会将其保持可用,以供其他客户端再次使用。不过,如果连接在5分钟内没有被使用,连接池会关闭它以释放数据库资源。在会话模式下,连接会立即关闭。
- 如果有客户端连接到连接池,那么至少会维持一条活跃连接,即使没有客户端需要它。
如何更改池大小#
🌐 How to change pool size
在仪表板的数据库设置中,你可以配置 Supavisor 的“连接池大小”:
🌐 In the Dashboard's Database Settings, you can configure Supavisor's "Pool Size":
你也可以在应用设置底部更改 PostgREST(数据库 API)内部连接池的大小。
🌐 You can also change the pool size for PostgREST's (DB API) internal pooler at the bottom of the application settings.
Supabase 上的所有服务都使用 Supavisor 吗? #
🌐 Do all services on Supabase use Supavisor?
Supabase Storage 内部使用 Supavisor。其他与 Postgres 通信的服务器(PostgREST、Realtime 和 Auth)都依赖内部应用池。
🌐 Supabase Storage uses Supavisor internally. The other servers that communicate with Postgres (PostgREST, Realtime, and Auth) all rely on internal application poolers.
Supavisor 主要面向那些不想依赖 Supabase 客户端库,而更喜欢使用外部 ORM(如 Prisma、Drizzle 和 Psycopg)的用户。
🌐 Supavisor is primarily intended for users who do not want to rely on the Supabase Client libraries and instead prefer to work with external ORMs, such as Prisma, Drizzle, and Psycopg.
是否要更改Supavisor的池大小?#
🌐 Whether to change Supavisor's pool size?
在理想情况下,Postgres 会支持无限数量的直接连接,但它能处理的连接数是有限的。如果 Supavisor 占用了大部分可用连接,你就有可能让其他服务器,比如 Auth,无法访问你的数据库。不过,尽可能地,你还是希望让连接池能够根据需求自由扩展它的池子来应对访问量。
🌐 In an ideal scenario, Postgres would support an unlimited number of direct connections, but there's a limit to how many it can handle. If Supavisor uses most of the available connections, you risk depriving other servers, such as Auth, from accessing your database. Still, as much as possible, you want to give your pooler freedom to grow its pool as needed to service demand.
需要注意的是,存储服务器也使用 Supavisor 作为一个独特的“用户+数据库+模式”组合,所以你为一般应用设置的池大小同样也适用于它。
🌐 It's important to note that the Storage server also uses Supavisor as a unique "user+db+mode" combination, so the pool size you set for your general application will apply to it, too.
一般来说,如果你在使用数据库 REST API 或多个基于应用的“用户+数据库+模式”组合,尽量保持连接池的使用率在可用连接的 40% 以下。否则,你可以谨慎地将使用率提高到大约 80%。这些百分比是灵活的,具体取决于你的应用使用情况和设置。监控连接使用情况,以确定最佳分配方式,同时不要剥夺其他服务器必要的连接。
🌐 As a rule of thumb, if you're using the DB REST API or multiple app-based "user+db+mode" combinations, try to keep the pooler's usage under 40% of available connections. Otherwise, you can cautiously increase usage to around 80%. These percentages are flexible and depend on your application's usage and setup. Monitor connection usage to determine the optimal allocation without depriving other servers of necessary connections.
如何监控连接#
🌐 How to monitor connections
编辑:发布了一个更深入的连接监控故障排除指南
可以通过 Supabase Grafana 仪表板监控连接使用情况。它可以实时查看超过 200 个数据库指标,比如 CPU、EBS 以及活跃的直接/连接池连接的图表。这对于监控和调试实例非常有用。
🌐 Connection usage can be monitored with a Supabase Grafana Dashboard. It provides realtime visibility of over 200 database metrics, such as graphs of CPU, EBS, and active direct/pooler connections. It can be extremely useful for monitoring and debugging instances.
你可以查看我们的 GitHub 仓库 获取本地部署或在 Fly.io 免费云部署的设置说明。参阅 Supabase 文档 了解更多关于指标端点的信息。
🌐 You can check our GitHub repo for setup instructions for local deployments or free cloud deployments on Fly.io. Refer to Supabase documentation to learn more about the metrics endpoint.
Supavisor 真能支持一百万个连接吗?#
🌐 Can Supavisor really support a million connections?
看情况。
🌐 It depends.
在文章《Supavisor:将 Postgres 扩展到 100 万连接》(/blog/supavisor-1-million) 中,我们让 Supavisor 能够同时连接到一百万个客户端。连接池将客户端的查询分配到 400 个数据库连接上。
🌐 In the article "Supavisor: Scaling Postgres to 1 Million Connections" we gave Supavisor the capacity to connect to a million clients simultaneously. The pooler triaged the clients' queries to 400 database connections.
重要的是,处理这些查询的数据库有64个虚拟CPU和256GB内存。它可以足够快地处理查询,确保从来没有明显的瓶颈。客户端从未等待过长而导致超时。如果客户端要求运行低效查询,比如下面的这个,会形成严重的待处理客户端查询积压:
🌐 What is important is that the database processing these queries had 64vCPUs and 256GB of memory. It could process the queries fast enough to ensure that there was never a noticeable bottleneck. The clients never waited long enough to timeout. If the clients were asking to run inefficient queries, like the one below, a severe backlog of pending client queries would have formed:
1-- do nothing for 60 seconds2select pg_sleep(60);如果没有足够的直接连接,也可能会出现积压。在我们的设置中,400 个连接足以处理一百万个客户端,确保请求顺畅流动。但如果我们只有一个直接连接,队列移动就会太慢,客户端的请求会超时。
🌐 A backlog could also happen if there are not enough direct connections available. In our setup, 400 connections were enough to handle a million clients, ensuring a smooth flow of requests. But if we had only 1 direct connection, the queue would've moved too slowly and clients would expire their requests.
只有在连接池以事务模式运行时,才能扩展到这个级别。在会话模式下,假设最初访问直连的400个客户端可以保留它们,即使它们不再执行查询。剩下的999,600个等待轮次的客户端就会被直接连接饿死。
🌐 Scaling to this level only works when the pooler is operating in transaction mode. In Session mode, hypothetically, the 400 clients that first accessed the direct connections could keep them, even if they are no longer executing queries. The pending 999,600 clients waiting for a turn would then be starved of direct connections.