Skip to content
Platform

升级中

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.

升级过程如下:

🌐 The upgrade process is as follows:

  1. 在你的控制面板的常规设置页面上使用“升级项目”按钮。
  2. 显示了升级所需时间的估算,并且任何在你有资格升级之前需要处理的事项都会以警告形式显示。在执行升级之前,请确保你已经查看了本文件的 注意事项 部分。
  3. 你的项目已下线,仪表板显示升级状态。
  4. 在幕后,会创建一个运行最新版本 Supabase 的新实例。
  5. 你的数据已被复制到新实例,并使用 pg_upgrade 升级。
  6. 如果升级失败,你的原始数据库会重新上线,并且能够处理请求。
  7. 当升级成功时,会进行一次 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:

  1. 带有只读副本的项目无法升级。你需要先删除副本,升级完成后再重新创建它们。
  2. pg_upgrade 不支持升级包含引用系统 OID 的 reg* 数据类型的数据库。你需要在升级前修改数据,不使用 reg* 数据类型。
  3. 逻辑复制槽必须被删除。
  4. 必须放弃废弃/不受支持的扩展。扩展可能有依赖,确保你备份这些数据,以便在升级后用更新的扩展版本恢复它们。

服务的新版本可能会影响你依赖的功能或改变性能特性。如果你的项目可以升级,你可以在 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

  1. 一定要和你的团队讨论一个合适的维护时间,因为升级会导致停机,这对尽量减少影响非常关键。
  2. 对于较小的数据库,我们建议使用 pg_dump 工具对数据进行逻辑备份。这样可以确保在升级之前有足够的备份。
  3. 对于较大的数据库,确保最近的备份已经在仪表板的备份页面中。
  4. 减少数据库中数据的大小和对象的数量。升级所需的时间很大程度上取决于这些因素,并且可能影响停机时间。例如:归档不常用的数据、删除未使用的索引、运行 vacuum 等。有关可以释放的空间的详细报告,请参见 Supabase CLI 中的 Inspect 命令,以及 pg_repack 文档。

升级后的最佳做法 #

🌐 Post-upgrade best practices

  1. Supabase 会在升级前后进行广泛的验证,以确保数据库已正确升级。不过,你还是应该规划自己的应用级验证,因为可能会有你没有预料到的变化,这在规划停机时间时也应该考虑到。
  2. 分析日志,看看升级后是否出现了新的慢查询。这可能是因为升级过程中数据结构发生了变化。
  3. 检查扩展版本,看看哪些扩展需要升级。

注意事项 #

🌐 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:

-- List roles using md5 hashing method
SELECT
rolname
FROM pg_authid
WHERE rolcanlogin = true
AND rolpassword LIKE 'md5%';
-- Migrate a role's password to scram-sha-256
ALTER 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.

Project Paused: 90 Days Remaining

在恢复窗口之后,你可以从项目仪表板下载项目的备份文件和存储对象。你可以通过以下方式恢复数据:

🌐 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:

Project Paused: Download Backup

如果在项目暂停期间升级到付费计划,任何已过期的一键恢复选项将会重新启用。由于备份是在向后兼容窗口之外进行的,恢复可能会失败。如果升级后恢复备份遇到问题,请联系支持。

🌐 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.

Project Paused: Paid Tier Restore

具体升级说明 #

🌐 Specific upgrade notes

升级到 Postgres 17 #

🌐 Upgrading to Postgres 17

在使用 Postgres 17 的项目中,以下扩展已被弃用:

🌐 In projects using Postgres 17, the following extensions are deprecated:

  • plcoffee
  • plls
  • plv8
  • timescaledb
  • pgjwt

计划将项目从 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.

使用较低版本 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:

comment 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:

comment on schema public is e'@graphql({"inflect_names": true, "introspection": true})';

要确认自省功能是否启用:

🌐 To verify introspection is enabled:

select 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.19 或 17.11 时.

🌐 Applies when upgrading to Postgres 15.19 or 17.11.

升级后,之前版本建立的 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:

  1. 检查一下你的数据库是否需要重新建立索引:

    select
    pg_encoding_to_char(encoding) as encoding,
    pg_encoding_max_length(encoding) as max_bytes_per_char, -- 1 = single-byte, >1 = multibyte
    datlocprovider as collation_provider, -- 'c' libc, 'i' icu, 'b' builtin
    (pg_encoding_max_length(encoding) > 1 or datlocprovider != 'c') as reindex_required
    from pg_database
    where datname = current_database();

    如果 reindex_required 是 false,比如像 LATIN1 这样单字节编码并且使用 libc 排序规则,则不需要进行任何操作。

  2. 如果 reindex_required 是 true,找出受影响的索引:

    select distinct
    n.nspname as schema_name,
    cls.relname as table_name,
    ic.relname as index_name
    from pg_index idx
    join pg_class ic on idx.indexrelid = ic.oid
    join pg_class cls on idx.indrelid = cls.oid
    join pg_namespace n on ic.relnamespace = n.oid
    join lateral unnest(idx.indclass::oid[]) with ordinality as k(opclass, pos) on true
    join pg_opclass oc on oc.oid = k.opclass
    join pg_type ty on ty.oid = oc.opcintype
    where
    k.pos <= idx.indnkeyatts -- key columns only, excludes INCLUDE
    and ty.typname in ('ltree', '_ltree');
  3. 使用模式限定名称重新索引每个受影响的索引。REINDEX INDEX CONCURRENTLY 可以在线运行而不会停机,但不能在事务块内运行:

    REINDEX INDEX CONCURRENTLY <schema_name>.<index_name>;

除了上面提到的编码问题,这个版本还修复了 ltree 比较中的一个整数溢出:当值的标签超过大约 14,653 个时,可能会比较不正确,这会破坏基于它们构建的 B 树索引,无论你的数据库编码如何。下面的查询只会列出那些 ltree 列或表达式中实际包含这种值的 B 树索引,所以这些就是需要重建索引的对象(如果结果为空,就不需要做任何操作):

🌐 Separately from the encoding case above, this release also fixes an integer overflow in ltree comparisons: values with more than about 14,653 labels could compare incorrectly, which can corrupt B-tree indexes built over them, regardless of your database encoding. The following query lists only the B-tree indexes whose ltree column or expression actually contains such values, so they are the ones to reindex (an empty result means no action is needed):

SELECT s.schema_name || '.' || s.index_name AS index_to_reindex
FROM (
SELECT
n.nspname AS schema_name,
c.relname AS table_name,
ic.relname AS index_name,
min(pg_get_expr(i.indpred, i.indrelid)) AS pred, -- partial-index predicate, if any
string_agg('nlevel(' || pg_get_indexdef(i.indexrelid, k.pos::int, true) || ') > 14653', ' OR ') AS keys_cond
FROM pg_index i
JOIN pg_class ic ON ic.oid = i.indexrelid
JOIN pg_class c ON c.oid = i.indrelid
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_am am ON am.oid = ic.relam
JOIN LATERAL generate_series(1, i.indnkeyatts) AS k(pos) ON true
JOIN pg_attribute ia ON ia.attrelid = i.indexrelid AND ia.attnum = k.pos
JOIN pg_type t ON t.oid = ia.atttypid
WHERE am.amname = 'btree'
AND t.typname = 'ltree'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
GROUP BY n.nspname, c.relname, ic.relname
) s
WHERE (xpath(
'/row/cnt/text()',
query_to_xml(
format('SELECT count(*) AS cnt FROM %I.%I WHERE %s(%s)',
s.schema_name, s.table_name,
CASE WHEN s.pred IS NOT NULL THEN '(' || s.pred || ') AND ' ELSE '' END,
s.keys_cond),
false, true, ''
)
))[1]::text::bigint > 0
ORDER BY 1;

对返回的每个索引重新索引,使用模式限定的名称。REINDEX INDEX CONCURRENTLY 可以在线运行且不会停机,但不能在事务块中运行:

🌐 Reindex each index it returns, using the schema-qualified name. REINDEX INDEX CONCURRENTLY runs online with no downtime, but cannot run inside a transaction block:

REINDEX INDEX CONCURRENTLY <schema_name>.<index_name>;

Pgcrypto 传统 PGP 加密算法 #

🌐 Pgcrypto legacy PGP ciphers

适用于升级到 Postgres 15.19 或 17.11 时.

🌐 Applies when upgrading to Postgres 15.19 or 17.11.

这个版本修复了 CVE-2026-14663:之前,当服务器的 OpenSSL 构建中没有请求的 PGP 加密算法时,pgcrypto 没有应用它,因此受影响的值没有按预期受到保护,即使使用错误的密钥也能被解密。升级后,默认情况下解密这些消息会失败,用这些加密算法加密也会返回错误。

🌐 This release fixes CVE-2026-14663: previously, when a requested PGP cipher was unavailable in the server's OpenSSL build, pgcrypto did not apply it, so affected values were not protected as intended and can be decrypted even with the wrong key. After upgrading, decrypting such messages fails by default, and encrypting with those ciphers returns an error.

要找出受影响的行,用一个故意错误的密码短语扫描每个存储的值:正确加密的值会报错,而受影响的值即使用错密钥也能成功解密。在同一个会话中运行辅助程序和扫描(pg_temp 函数是会话范围的):

🌐 To find affected rows, scan each stored value with a deliberately wrong passphrase: properly encrypted values raise an error, while affected values decrypt successfully even with the wrong key. Run the helper and the scan in the same session (pg_temp functions are session-scoped):

create function pg_temp.affected_by_cve_2026_14663(msg bytea)
returns boolean
language plpgsql as $$
begin
perform pgp_sym_decrypt_bytea(msg, 'deliberately-wrong-key');
return true;
exception when others then
return false;
end $$;
select <id_column>
from <your_table>
where <your_encrypted_column> is not null
and pg_temp.affected_by_cve_2026_14663(<your_encrypted_column>);

返回的任何行都包含受影响的值。扫描涵盖对称(pgp_sym_*)消息;错误密钥探测不适用于公钥(pgp_pub_*)消息。如果你用受影响的 cipher-algo 选项之一调用 pgp_pub_encrypt,就把这些值当作受影响的,并用你的密钥对使用 pgp_pub_decrypt 和 pgp_pub_encrypt 重新加密它们。

🌐 Any rows returned hold affected values. The scan covers symmetric (pgp_sym_*) messages; the wrong-key probe does not apply to public-key (pgp_pub_*) messages. If you call pgp_pub_encrypt with one of the affected cipher-algo options, treat those values as affected and re-encrypt them the same way using pgp_pub_decrypt and pgp_pub_encrypt with your key pair.

用现代密码重新加密受影响的值。在你升级之前,当前版本仍然可以正常解密它们:

🌐 Re-encrypt affected values with a modern cipher. Before you upgrade, the current version still decrypts them normally:

update <your_table>
set <col> = pgp_sym_encrypt(
pgp_sym_decrypt(<col>, '<your-key>'),
'<your-key>', 'cipher-algo=aes256')
where <id_column> in (/* rows found by the scan above */);

升级后,默认情况下解密受影响的值会失败——添加 ignore-cipher-failure=1 来读取它们:

🌐 After you upgrade, decrypting affected values fails by default — add ignore-cipher-failure=1 to read them:

update <your_table>
set <col> = pgp_sym_encrypt(
pgp_sym_decrypt(<col>, '<your-key>', 'ignore-cipher-failure=1'),
'<your-key>', 'cipher-algo=aes256')
where <id_column> in (/* rows found by the scan above */);

如果明文是二进制的(用 pgp_sym_encrypt_bytea 加密),以同样的方式使用 pgp_sym_decrypt_bytea 和 pgp_sym_encrypt_bytea —— 文本函数无法处理二进制明文。在对所有行进行更新之前,先抽查一下恢复的值是否能解密为预期的明文。由于受影响的值没有按预期受到保护,考虑更换以这种方式存储的任何密钥。

🌐 If the plaintext is binary (encrypted with pgp_sym_encrypt_bytea), use pgp_sym_decrypt_bytea and pgp_sym_encrypt_bytea in the same way — the text functions reject binary plaintext. Spot-check that a recovered value decrypts to the expected plaintext before running the update across all rows. Because affected values were not protected as intended, consider rotating any secrets stored this way.

升级后,浮点列上的 Btree_gist 索引需要重新建索引 #

🌐 Btree_gist indexes on float columns require reindexing after upgrade

适用于升级到 Postgres 15.19 或 17.11 时.

🌐 Applies when upgrading to Postgres 15.19 or 17.11.

这个版本修复了 btree_gist 的 float4 和 float8 操作符类中对 NaN 的处理。在之前版本下建立的这些列的索引,如果包含 NaN 的行,在重新建立索引之前可能会返回错误结果。

🌐 This release fixes NaN handling in btree_gist's float4 and float8 operator classes. Indexes on those columns built under the previous version can return wrong results for rows containing NaN until the index is rebuilt.

为了解决这个问题:

🌐 To mitigate this issue:

  1. 在浮点列上查找 btree_gist 索引:

    select distinct
    n.nspname as schema_name,
    cls.relname as table_name,
    ic.relname as index_name
    from pg_index idx
    join pg_class ic on idx.indexrelid = ic.oid
    join pg_am am on ic.relam = am.oid
    join pg_class cls on idx.indrelid = cls.oid
    join pg_namespace n on ic.relnamespace = n.oid
    join lateral unnest(idx.indclass::oid[]) with ordinality as k(opclass, pos) on true
    join pg_opclass oc on oc.oid = k.opclass
    join pg_type ty on ty.oid = oc.opcintype
    where
    am.amname = 'gist'
    and k.pos <= idx.indnkeyatts
    and ty.typname in ('float4', 'float8');
  2. 如果返回了任何索引,并且这些列可能包含 NaN 值,请使用带架构限定的名称重新建立索引。REINDEX INDEX CONCURRENTLY 在线运行,无需停机,但不能在事务块中运行:

    REINDEX INDEX CONCURRENTLY <schema_name>.<index_name>;

自定义操作符选择性估算器 #

🌐 Custom operator selectivity estimators

适用于升级到 Postgres 15.19 或 17.11 时.

🌐 Applies when upgrading to Postgres 15.19 or 17.11.

现在将非内置(扩展或用户提供的)选择性估算器函数附加到操作符上需要超级用户权限。现有操作符仍然可以正常工作——该检查仅在操作符被(重新)创建时触发,最常见的情况是在 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:

ERROR: 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:

SELECT n.nspname AS schema, o.oprname AS operator,
o.oprrest::regproc AS restrict_estimator,
o.oprjoin::regproc AS join_estimator
FROM pg_operator o
JOIN pg_namespace n ON o.oprnamespace = n.oid
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
AND ((o.oprrest <> 0 AND o.oprrest::oid >= 10000)
OR (o.oprjoin <> 0 AND o.oprjoin::oid >= 10000))
AND NOT EXISTS (
SELECT 1 FROM pg_depend d
WHERE d.classid = 'pg_operator'::regclass AND d.objid = o.oid AND d.deptype = 'e'
);

如果没有返回任何行,你的项目不受影响。

🌐 If this returns no rows, your project is unaffected.