Postgres 导入导出数据库

作者: adm 分类: postgresql 发布时间: 2025-04-26

在 PostgreSQL 中,导入导出数据库主要依赖 pg_dump 和 psql(或 pg_restore)这两个核心工具。选择哪种方式,取决于你的目标是简单备份、跨用户迁移,还是处理像 vector 扩展这类有特殊依赖的场景。下面用具体的 Demo 来演示几种常见做法。

场景一:标准备份与恢复(纯文本 SQL)

这是最直观的方式,导出的文件是 SQL 文本,可以用编辑器查看,也方便用 psql 直接回放。

1. 导出(备份)
使用 pg_dump 将 old_db 导出为 backup.sql:

pg_dump -h localhost -U postgres -d old_db -f backup.sql

-h、-U、-d:分别指定主机、用户名和数据库名。
-f:指定输出文件。如果不加 -f,结果会打印到屏幕。
2. 导入(恢复)
首先,需要手动创建一个空数据库(pg_dump 不会自动建库):

createdb -h localhost -U postgres new_db

然后,用 psql 执行导出的 SQL 文件:

psql -h localhost -U postgres -d new_db -f backup.sql

注意:如果源库的对象所有者(owner)在目标实例中不存在,导入会报错 role “xxx” does not exist。这时候需要加上 –no-owner 参数重新导出,或者先在目标库创建对应的角色。

场景二:处理权限与所有者冲突(跨用户迁移)

结合你之前“一个用户管一个数据库”的需求,如果你是用 pg_dump 导出的,文件里会包含 ALTER … OWNER TO 原用户 的语句。如果目标库没有这个用户,导入就会中断。

解决方案:在导出时加上 –no-owner,让导入后的对象自动归属于执行导入的当前用户。

Demo(导出时忽略所有者):

# 导出时忽略所有权信息
pg_dump -h localhost -U postgres -d old_db --no-owner -f backup_no_owner.sql

导入:

# 确保你用目标用户(如 user_a)连接并导入
psql -h localhost -U user_a -d db_a -f backup_no_owner.sql

这样,所有表、序列在 db_a 里的主人就是 user_a,避开了 role “twoass” does not exist 这类报错。

场景三:自定义格式与并行恢复(更高效)

纯文本格式在数据量大时,恢复速度较慢,且无法选择性地只恢复部分表。使用 pg_dump 的自定义格式(-Fc)配合 pg_restore,会更灵活。

1. 导出为自定义格式:

pg_dump -h localhost -U postgres -d old_db -Fc -f old_db.dump

-Fc:输出适合 pg_restore 读取的压缩格式。
2. 使用 pg_restore 导入:
同样,先建好空库 new_db,然后执行:

pg_restore -h localhost -U postgres -d new_db --no-owner -v old_db.dump

–no-owner:作用同上,忽略原所有者。
-v:详细模式,能看到恢复进度。
自定义格式的好处是,你还可以用 -j 参数开启并行恢复(例如 -j 4 使用 4 个核心),大幅提升大库的导入速度。
场景四:处理特殊扩展(以 vector 为例)

pg_dump 会导出 CREATE EXTENSION vector 语句,但如果目标库没有安装该扩展,或者扩展安装的 schema 不一致,就会失败。

排查与解决 Demo:

步骤 1:确认源库扩展位置
在源库执行,看 vector 装在哪个 schema:

sql

SELECT e.extname, n.nspname
FROM pg_extension e
JOIN pg_namespace n ON n.oid = e.extnamespace
WHERE e.extname = 'vector';

步骤 2:在目标库预先安装扩展
假设源库显示在 public schema。在导入数据之前,先连接到目标库 db_a,以足够权限的用户执行:

sql

CREATE EXTENSION IF NOT EXISTS vector WITH SCHEMA public;

步骤 3:再执行数据导入
扩展就位后,再用 pg_restore 或 psql 导入,就不会再报类型不存在了。如果扩展原本装在非 public 的 schema(比如 old_db.vector),则需要确保目标库也有同名 schema,并在其中创建扩展。

关键选项速查

选项	作用	适用场景
-Fc	输出自定义压缩格式	配合 pg_restore,支持并行、选择性恢复
--no-owner	不设置对象所有者	跨用户/跨实例迁移,避免角色不存在报错
-s	仅导出模式(表结构)	只想要建表语句,不要数据
-a	仅导出数据	表结构已手动建好,只灌数据
-t	指定表名	只迁移特定几张表

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!