Postgres 导入导出数据库
在 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 指定表名 只迁移特定几张表

