Supabase 怎么用 CLI 备份数据库并恢复到另一个项目?
【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase
如果你的 Supabase 项目要换项目、换组织,或者只是想在另一个项目上重放一份数据库,官方文档给出的做法是:在本地用 Supabase CLI 把旧项目的数据库逻辑备份(db dump)成三个 SQL 文件,再用psql把它们恢复到你自己新建的目标项目。这条路适用于把数据恢复到托管的 Supabase 项目;如果你只是想检查一个已暂停项目的数据,CLI 还支持把下载的备份恢复到本地实例(见文末说明)。
官方步骤对应文档:Backup and Restore using the CLI。
准备工作:安装 CLI 和 psql
- 安装 Supabase CLI。文档按平台给出渠道:npm(
npm install supabase --save-dev,之后用npx supabase执行命令,要求 Node.js 20 或更高)、macOS/Linux 用 Homebrew(brew install supabase/tap/supabase)、Windows 用 Scoop、Linux 也可安装官方 Releases 提供的.apk/.deb/.rpm包。 - 安装 Postgres 客户端以提供
psql(恢复步骤要用)。官方给出的安装方式是 postgres_installation 片段中的内容:macOS 执行brew install postgresql@17;Windows 从 Postgres 官方安装页下载安装包,并把bin目录(例如C:\Program Files\PostgreSQL\17\bin)加入系统 PATH。两种情况下都要重开终端,用psql --version验证可用;报错时按文档检查 PATH 设置。
从旧项目备份数据库
先拿到旧项目的数据库连接信息,然后在本地执行三条 dump 命令,把角色、结构、数据分别存成三个文件。
- 获取连接字符串:在项目 Dashboard 的 Connect 面板查看。默认使用 Session pooler 连接串;如果你的网络支持 IPv6 或启用了 IPv4 add-on,则使用直连(direct)连接串。文档给出的两种形式(
[PROJECT-REF]、[YOUR-PASSWORD]需替换为你项目的实际值):
# Session pooler 连接串 postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgres # 直连连接串 postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.com:5432/postgres- 获取数据库密码:在 Dashboard 的 Database Settings 页重置密码,把上面连接串中的
[YOUR-PASSWORD]换成该密码。 - 执行备份:把
[CONNECTION_STRING]替换为第 1、2 步拼好的完整连接串,依次执行:
supabase db dump --db-url [CONNECTION_STRING] -f roles.sql --role-onlysupabase db dump --db-url [CONNECTION_STRING] -f schema.sqlsupabase db dump --db-url [CONNECTION_STRING] -f data.sql --use-copy --data-only -x "storage.buckets_vectors" -x "storage.vector_indexes"三条命令分别产出roles.sql(仅角色定义)、schema.sql(库结构)和data.sql(仅数据,使用 COPY 格式,并排除storage.buckets_vectors、storage.vector_indexes两张表)。
注意:如果你使用的是 Restore to a new project(平台内克隆,付费计划且源项目开启了物理备份)或 Branching 流程,平台会自动把加密根密钥复制到新项目,本文的手动流程(含密钥复制步骤)不适用。
创建并配置目标项目
- 新建一个 Supabase 项目。
- 在新项目里做两项按需配置:旧数据库用过 Webhooks 的,启用 Database Webhooks;用过非默认扩展的,在 Extensions 页面把它们启用。
- 按上一节同样的方式,获取新项目的连接字符串和数据库密码(忘记密码时可在 Database > Settings 页重置)。
用 psql 恢复备份到新项目
把[CONNECTION_STRING]替换为新项目的连接串后,在项目目录(即存放roles.sql、schema.sql、data.sql的目录)执行:
psql \ --single-transaction \ --variable ON_ERROR_STOP=1 \ --file roles.sql \ --file schema.sql \ --command 'SET session_replication_role = replica' \ --file data.sql \ --dbname [CONNECTION_STRING]其中--single-transaction与--variable ON_ERROR_STOP=1使恢复在出错时中止,不会留下恢复到一半的状态;SET session_replication_role = replica的作用文档明确说明:在导入期间禁用触发器,防止列被重复加密。
使用 Vault 或列加密时:先复制根加密密钥
如果你在新旧项目中使用了 Supabase Vault 或 pgsodium,必须在恢复前先复制根加密密钥,否则从旧项目恢复出来的 Vault 密钥和加密列无法解密。文档强调两点限制:
- 一定要在暂停或删除旧项目之前取出根密钥。该 API 只对项目处于活动状态时返回密钥;旧项目一旦暂停或删除,密钥(以及用该密钥加密的数据)将无法取回。
- 备份文件本身不含根密钥,只有加密数据;新建的项目会初始化自己的新密钥。覆盖项目的根密钥会使用其他密钥加密的数据不可访问。
使用你的 Personal Access Token 执行(<old_project_ref>、<new_project_ref>替换为对应项目 ref,即项目 URL 中https://与.supabase.co之间的值;<personal_access_token>替换为你的 token):
export OLD_PROJECT_REF="<old_project_ref>" export NEW_PROJECT_REF="<new_project_ref>" export SUPABASE_ACCESS_TOKEN="<personal_access_token>" curl "https://api.supabase.com/v1/projects/$OLD_PROJECT_REF/pgsodium" \ -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" | curl "https://api.supabase.com/v1/projects/$NEW_PROJECT_REF/pgsodium" \ -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \ -X PUT --json @-这个 endpoint 返回和写入的都是 64 字符十六进制的根密钥。
恢复后重新启用 Publication
如果旧数据库为 Supabase Realtime 使用了复制,需要在 Dashboard 的 Database > Publications 页面对相关表重新启用 publication,Realtime 才会恢复工作。
两个可选的补充迁移
这两项不是每次迁移都需要,仅当对应条件成立时执行。
保留迁移历史:如果旧数据库一直用 Supabase CLI 管理迁移、且你想在新项目里保留迁移记录,需要单独导出并导入supabase_migrationsschema:
supabase db dump --db-url "$OLD_DB_URL" -f history_schema.sql --schema supabase_migrations supabase db dump --db-url "$OLD_DB_URL" -f history_data.sql --use-copy --data-only --schema supabase_migrations psql \ --single-transaction \ --variable ON_ERROR_STOP=1 \ --file history_schema.sql \ --file history_data.sql \ --dbname "$NEW_DB_URL"迁移对auth、storageschema 的修改:如果你在旧项目改过auth或storageschema(例如加了触发器或 RLS 策略),这些改动要单独恢复。文档给出用 CLI diff 出差异的方法:
supabase link --project-ref "$OLD_PROJECT_REF" supabase db diff --linked --schema auth,storage > changes.sql恢复过程中常见报错及处理
文档列出了四类已知的恢复报错及对应处理方式,出现时按描述修改 SQL 文件后重新执行即可:
- 自定义角色需要密码:如果旧项目创建过带
LOGIN属性的自定义角色,必须在新项目里手动给它们设置密码:
alter user "YOUR_USER" with password 'SOME_NEW_PASSWORD';supabase_admin权限错误:打开schema.sql,注释掉包含下面这类内容的行:
ALTER ... OWNER TO "supabase_admin"cli_login_postgres授权报错:如果看到
ERROR: permission denied to grant role "postgres" DETAIL: Only roles with the ADMIN option on role "postgres" may grant this role.打开roles.sql,注释掉这一行:
GRANT "postgres" TO "cli_login_postgres" WITH INHERIT FALSE GRANTED BY "supabase_admin";- 克隆后
cli_login_postgres角色冲突:cli_login_role必须由supabase_admin角色创建,如果迁移过程先把该角色克隆了过去,CLI 会报role "postgres" is a member of role "cli_login_postgres"。删除这个角色后 CLI 会用正确权限重建它:
DROP ROLE IF EXISTS cli_login_postgres;边界与替代路径
- 恢复命令在单事务中执行且遇到错误即停(
ON_ERROR_STOP=1),没有报错跑完即表示三个文件都导入成功;之后的 Webhooks、扩展、publications 属于按需重新启用项,不是恢复命令的一部分。 - 如果你面对的其实是已暂停项目的备份(从 Dashboard 下载、文件名类似
db_cluster.backup的归档),而不是上面这种逻辑备份,对应的是另一条路径:本地恢复用于检查与提取数据。做法见 Restoring a downloaded backup locally:
supabase init echo '15.6.1.115' > supabase/.temp/postgres-version supabase db start --from-backup db_cluster.backup其中 Postgres 版本值取自备份文件上PG:前缀后面的版本号,例如文档示例中的15.6.1.115;本地恢复支持的最早版本是15.1.0.55,更早版本可能报错。启动成功后用psql 'postgresql://postgres:postgres@localhost:54322/postgres'连接验证数据。注意文档明确说明:用 CLI 启动的本地 Postgres 不是生产就绪的,只应用于本地开发;要把备份恢复到托管项目,仍应走本文这条逻辑恢复路径。
更多psql连接方式可参考 Connecting with PSQL。
【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考