升级中
Supabase 推得很快,我们会尽量把所有新功能加到现有项目里。不过有些情况下,想用新功能需要升级或迁移你的 Supabase 项目。建议升级 Postgres 版本,这样就能使用最新的功能和修复。
🌐 Supabase ships fast and we try to add all new features to existing projects wherever possible. In some cases, access to new features require upgrading or migrating your Supabase project. It is recommended to upgrade Postgres version to get access to the latest features and fixes.
要调整你的计算大小,请参考计算和磁盘页面。
🌐 For scaling your compute size, refer to the Compute and Disk page.
我们如何升级 #
🌐 How we upgrade
对于 Postgres 的主版本和次版本升级,流程保持不变,因为其他功能和服务也会同时升级。
🌐 The process remains the same for Postgres major and minor version upgrades, as other features and services are also upgraded at the same time.
免费项目在暂停的项目恢复后会升级到最新的小版本。付费项目不能暂停。
🌐 Free projects will move to the latest minor version when their paused project is restored. Paid projects can't be paused.
升级过程如下:
🌐 The upgrade process is as follows:
- 在你的仪表板的基础设施部分点击“升级项目”按钮。
- 显示了升级所需时间的估算,并且任何在你有资格升级之前需要处理的事项都会以警告形式显示。在执行升级之前,请确保你已经查看了本文件的 注意事项 部分。
- 你的项目已下线,仪表板显示升级状态。
- 在幕后,会创建一个运行最新版本 Supabase 的新实例。
- 你的数据已被复制到新实例,并使用
pg_upgrade升级。 - 如果升级失败,你的原始数据库会重新上线,并且能够处理请求。
- 当升级成功时,会进行一次 pg_basebackup,完成后,你的项目就可以在仪表板上使用了。
Supabase 项目默认使用 GP3 磁盘类型部署,升级时大约会有 ~100Mbps 的速度。更改磁盘类型(或提高 IOPS/吞吐量)可以缩短升级时间。
🌐 A Supabase project is deployed with a GP3 disk type by default, which will give ~100Mbps when upgrading. Changing the disk type (or increasing IOPS/Throughput) will reduce the time to upgrade.
根据你的数据库大小,你可以用这个指标来大致估算升级所需的停机时间。在这个时间段内,你应该计划好数据库及相关服务将无法使用。
🌐 Using the size of your database, you can use this metric to derive an approximation of the downtime window necessary for the upgrade. During this window, you should plan for your database and associated services to be unavailable.
升级前提条件 #
🌐 Upgrade pre-requisites
升级时,会有通知告诉你是什么阻止了升级过程。你需要按照升级的前提条件操作,才能顺利完成升级:
🌐 When upgrading, a notification will inform you about what is blocking the upgrade process. You need to follow the pre-requisites for the upgrade to successfully complete:
- 带有只读副本的项目无法升级。你需要先删除副本,升级完成后再重新创建它们。
pg_upgrade不支持升级包含引用系统 OID 的reg*数据类型的数据库。你需要在升级前修改数据,不使用reg*数据类型。- 逻辑复制槽必须被删除。
- 必须放弃废弃/不受支持的扩展。扩展可能有依赖,确保你备份这些数据,以便在升级后用更新的扩展版本恢复它们。
服务的新版本可能会影响你依赖的功能或改变性能特性。如果你的项目可以升级,你可以在 Supabase 控制面板 中找到你当前的服务版本。
🌐 Newer versions of services can break functionality or change the performance characteristics you rely on. If your project is eligible for an upgrade, you will be able to find your current service versions from within the Supabase dashboard.
重大更改通常只会出现在 Postgres 和 PostgREST 的主要版本升级中。你可以在这里找到它们各自的发行说明:
🌐 Breaking changes are generally only present in major version upgrades of Postgres and PostgREST. You can find their respective release notes at:
如果你是从一个比较旧的版本升级,你还需要考虑中间版本的更新说明。
🌐 If you are upgrading from a significantly older version, you will need to consider the release notes for any intermediary releases as well.
升级前的最佳做法 #
🌐 Pre-upgrade best practices
- 一定要和你的团队讨论一个合适的维护时间,因为升级会导致停机,这对尽量减少影响非常关键。
- 对于较小的数据库,我们建议使用 pg_dump 工具对数据进行逻辑备份。这样可以确保在升级之前有足够的备份。
- 对于较大的数据库,确保最近的备份已经在仪表板的备份页面中。
- 减少数据库中数据的大小和对象的数量。升级所需的时间很大程度上取决于这些因素,并且可能影响停机时间。例如:归档不常用的数据、删除未使用的索引、运行 vacuum 等。有关可以释放的空间的详细报告,请参见 Supabase CLI 中的 Inspect 命令,以及 pg_repack 文档。
升级后的最佳做法 #
🌐 Post-upgrade best practices
- Supabase 会在升级前后进行广泛的验证,以确保数据库已正确升级。不过,你还是应该规划自己的应用级验证,因为可能会有你没有预料到的变化,这在规划停机时间时也应该考虑到。
- 分析日志,看看升级后是否出现了新的慢查询。这可能是因为升级过程中数据结构发生了变化。
- 检查扩展版本,看看哪些扩展需要升级。
注意事项 #
🌐 Caveats
带 md5 密码的自定义角色 #
🌐 Custom roles with md5 passwords
md5 哈希方法有一些已知的弱点,使其不适合用于加密。因此,我们正在弃用 md5,转而使用 scram-sha-256,这是最新 Postgres 版本中默认且最安全的认证方法。
🌐 The md5 hashing method has known weaknesses that make it unsuitable for cryptography. As such, we are deprecating md5 in favor of scram-sha-256, which is the default and most secure authentication method used in the latest Postgres versions.
在升级过程中,我们会自动将 Supabase 管理的角色密码迁移到 scram-sha-256,但你需要手动迁移你创建的任何自定义角色的密码,否则升级后你将无法使用它们进行连接。
🌐 We automatically migrate Supabase-managed roles' passwords to scram-sha-256 during the upgrade process, but you will need to manually migrate the passwords of any custom roles you have created, else you won't be able to connect using them after the upgrade.
要使用 md5 哈希方法识别角色并迁移它们的密码,在升级后你可以使用以下 SQL 语句:
🌐 To identify roles using the md5 hashing method and migrate their passwords, you can use the following SQL statements after the upgrade:
1-- List roles using md5 hashing method2SELECT3 rolname4FROM pg_authid5WHERE rolcanlogin = true6 AND rolpassword LIKE 'md5%';78-- Migrate a role's password to scram-sha-2569ALTER ROLE <role_name> WITH PASSWORD '<password>';数据库容量缩减 #
🌐 Database size reduction
作为升级过程的一部分,也会执行像清理这样的维护操作。这可能会导致报告的数据库大小减少。
🌐 As part of the upgrade process, maintenance operations such as vacuuming are also executed. This can result in a reduction in the reported database size.
磁盘容量 #
🌐 Disk sizing
在升级时,Supabase 平台会根据当前数据库的大小来“适配”磁盘。例如,如果你的数据库大小是 100GB,而你有一个 200GB 的磁盘,升级后磁盘大小会被缩小到 120GB(数据库大小的 1.2 倍)。
🌐 When upgrading, the Supabase platform will "right-size" your disk based on the current size of the database. For example, if your database is 100GB in size, and you have a 200GB disk, the upgrade will reduce the disk size to 120GB (1.2x the size of your database).
时间限制 #
🌐 Time limits
当一个项目被暂停时,用户有一年的时间可以在 Supabase Studio 内从平台上恢复该项目。
🌐 When a project is paused, users have a 1-year window to restore the project on the platform from within Supabase Studio.
恢复窗口的存在是因为备份只会保留有限的时间,而且平台的变化可能与旧备份不兼容。与活跃项目不同,静态备份无法更新以适应这些变化。
🌐 The restore window exists because backups are only retained for a limited period, and platform changes may not be backwards compatible with older backups. Unlike active projects, static backups can't be updated to accommodate such changes.
在恢复窗口期间,暂停的项目可以通过在Studio 的仪表板页面上单击一个按钮来恢复到平台上。
🌐 During the restore window a paused project can be restored to the platform with a single button click from Studio's dashboard page.

在恢复窗口之后,你可以从项目仪表板下载项目的备份文件和存储对象。你可以通过以下方式恢复数据:
🌐 After the restore window, you can download your project's backup file, and Storage objects from the project dashboard. You can restore the data in the following ways:

如果在项目暂停期间升级到付费计划,任何已过期的一键恢复选项将会重新启用。由于备份是在向后兼容窗口之外进行的,恢复可能会失败。如果升级后恢复备份遇到问题,请联系支持。
🌐 If you upgrade to a paid plan while your project is paused, any expired one-click restore options are reenabled. Since the backup was taken outside the backwards compatibility window, it may fail to restore. If you have a problem restoring your backup after upgrading, contact Support.

具体升级说明 #
🌐 Specific upgrade notes
升级到 Postgres 17 #
🌐 Upgrading to Postgres 17
在使用 Postgres 17 的项目中,以下扩展已被弃用:
🌐 In projects using Postgres 17, the following extensions are deprecated:
plcoffeepllsplv8timescaledbpgjwt
计划将项目从 Postgres 15 升级到 Postgres 17 的用户,需要先在 Supabase 控制台 中禁用这些扩展。
🌐 Projects planning to upgrade from Postgres 15 to Postgres 17 need to first disable these extensions in the Supabase Dashboard.
pgjwt 在所有 Supabase 项目中默认都是开启的,直到 Postgres 17。如果你在项目中没有明确使用 pgjwt,很可能可以安全地将其关闭。
使用较低版本 Postgres 的现有项目不会受到影响,并且这些扩展在使用 Postgres 15 的项目上仍会继续支持,直到 Supabase 平台上 Postgres 15 的生命周期结束。
🌐 Existing projects on lower versions of Postgres are not impacted, and the extensions will continue to be supported on projects using Postgres 15, until the end of life of Postgres 15 on the Supabase platform.
pg_cron#
🌐 pg_cron usage
pg_cron 不会自动清理历史记录。如果这些记录不定期清理,cron.job_run_details 表可能会变得非常大;在升级之前,你应该先清理掉这个表中不必要的记录。
在 Supabase 项目升级过程中,pg_cron 扩展会被移除然后重新创建。在这个过程之前,会复制 cron.job_run_details 表以避免丢失历史日志。复制一个极大的明细表会瞬间产生磁盘压力,这最多会导致不必要的性能下降,最坏的情况甚至可能导致升级过程失败。
🌐 During the Supabase project upgrade, the pg_cron extension gets dropped and recreated. Before this process, the cron.job_run_details table is duplicated to avoid losing historical logs. The instantaneous disk pressure created by duplicating an extremely large details table can cause at best unnecessary performance degradation, or at worst, upgrade process failures.
升级到 pg_graphql 1.6.0 #
🌐 Upgrading to pg_graphql 1.6.0
从 pg_graphql 1.6.0 开始,GraphQL 的 introspection 默认是关闭的。升级后,对 __schema 和 __type 的查询会返回错误,除非明确启用了 introspection。完整细节请参考 pg_graphql 配置文档。
🌐 Starting with pg_graphql 1.6.0, GraphQL introspection is disabled by default. After the upgrade, queries to __schema and __type will return an error unless introspection is explicitly enabled. See the pg_graphql configuration docs for full details.
这会影响依赖自省的工具:
🌐 This affects tools that rely on introspection:
- 工作室的 GraphQL 检查器(GraphiQL)
- 外部 GraphiQL 或 GraphQL Playground
- 代码生成器(例如
graphql-codegen) - 中继编译器
- 任何直接调用
__schema或__type的工具
常规数据查询(例如 accountCollection、insertIntoAccountCollection)不受影响。
🌐 Regular data queries (e.g. accountCollection, insertIntoAccountCollection) are not affected.
要重新启用对模式的自省,请在 SQL 编辑器中运行以下 SQL:
🌐 To re-enable introspection on a schema, run the following SQL in the SQL editor:
1comment on schema public is e'@graphql({"introspection": true})';如果你的 schema 已经有包含其他指令(例如 inflect_names)的注释,把这些键合并 — 设置新注释会覆盖旧注释:
🌐 If your schema already has a comment with other directives (e.g. inflect_names), combine the keys — setting a new comment overwrites the old one:
1comment on schema public is e'@graphql({"inflect_names": true, "introspection": true})';要确认自省功能是否启用:
🌐 To verify introspection is enabled:
1select graphql.resolve('{ __schema { queryType { name } } }');除非选择升级,否则现有的 pg_graphql 1.5.x 项目不会受到影响。
🌐 Existing projects on pg_graphql 1.5.x are not impacted unless they choose to upgrade.
升级后 Ltree 索引需要重新建立 #
🌐 Ltree indexes require reindexing after upgrade
适用于升级到 Postgres 15.18 或 17.10 时.
🌐 Applies when upgrading to Postgres 15.18 or 17.10.
只有当你在 ltree 列上有索引,并且你的数据库使用多字节编码或非 libc 排序规则提供程序时,你才会受到影响。
🌐 You are affected only if you have indexes on ltree columns and your database uses a multibyte encoding or a non-libc collation provider.
升级后,之前版本建立的 ltree 列索引在重建索引之前可能会返回不完整的结果。例如,标签搜索可能会悄悄漏掉存在的行。这会影响使用多字节编码(如 UTF-8)或非 libc 排序规则提供程序(如 ICU 或内置)的数据库。
🌐 After upgrading, indexes on ltree columns that were built under the previous version can return incomplete results until the index is rebuilt. For example, label searches silently miss rows that are present. This affects databases using a multibyte encoding, such as UTF-8, or a non-libc collation provider such as ICU or builtin.
为了解决这个问题:
🌐 To mitigate this issue:
-
检查一下你的数据库是否需要重新建立索引:
1select2pg_encoding_to_char(encoding) as encoding,3pg_encoding_max_length(encoding) as max_bytes_per_char, -- 1 = single-byte, >1 = multibyte4datlocprovider as collation_provider, -- 'c' libc, 'i' icu, 'b' builtin5(pg_encoding_max_length(encoding) > 1 or datlocprovider != 'c') as reindex_required6from pg_database7where datname = current_database();如果
reindex_required是false,比如像 LATIN1 这样单字节编码并且使用libc排序规则,则不需要进行任何操作。 -
如果
reindex_required是true,找出受影响的索引:1select schemaname, tablename, indexname2from pg_indexes3where4indexname in (5select c.relname6from7pg_index as i8join pg_class as c on i.indexrelid = c.oid9join pg_attribute as a on a.attrelid = i.indrelid and a.attnum = ANY(i.indkey)10join pg_type as t on a.atttypid = t.oid11where t.typname in ('ltree', '_ltree')12); -
重新索引每个受影响的索引。
REINDEX INDEX CONCURRENTLY在线运行,无需停机:1REINDEX INDEX CONCURRENTLY <index_name>;
自定义操作符选择性估算器 #
🌐 Custom operator selectivity estimators
适用于升级到 Postgres 15.18 或 17.10 时.
🌐 Applies when upgrading to Postgres 15.18 or 17.10.
现在将非内置(扩展或用户提供的)选择性估算器函数附加到操作符上需要超级用户权限。现有操作符仍然可以正常工作——该检查仅在操作符被(重新)创建时触发,最常见的情况是在 pg_dump / pg_restore、逻辑恢复或分支期间。
🌐 Attaching a non-built-in (extension- or user-provided) selectivity estimator function to an operator now requires superuser. Existing operators continue to work — the check only fires when an operator is (re)created, most commonly during pg_dump / pg_restore, a logical restore, or a branch.
因为 Supabase 数据库角色不是超级用户,所以在为你重新创建这样的运算符时(例如在恢复或分支期间)可能会失败,提示如下:
🌐 Because Supabase database roles are not superusers, recreating such an operator on your behalf (for example during a restore or branch) can fail with:
1ERROR: must be superuser to specify a non-built-in restriction estimator function大多数项目不受影响。要检查你的数据库是否有引用非内置估算器的自定义操作符:
🌐 Most projects are not affected. To check whether your database has any user-defined operators that reference a non-built-in estimator:
1SELECT n.nspname AS schema, o.oprname AS operator2FROM pg_operator o3JOIN pg_namespace n ON o.oprnamespace = n.oid4WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')5 AND ((o.oprrest <> 0 AND o.oprrest::oid >= 10000)6 OR (o.oprjoin <> 0 AND o.oprjoin::oid >= 10000))7 AND NOT EXISTS (8 SELECT 1 FROM pg_depend d9 WHERE d.classid = 'pg_operator'::regclass AND d.objid = o.oid AND d.deptype = 'e'10 );如果没有返回任何行,你的项目不受影响。
🌐 If this returns no rows, your project is unaffected.