PostGIS备份恢复怎么做?pg_dump命令是?
PostGIS备份恢复怎么做?pg_dump命令是? 这是很多 GIS 工程师在迁移空间数据库、上线 WebGIS 项目、重装服务器或做数据安全方案时都会遇到的问题。PostGIS 本质上是 PostgreSQL 的空间扩展,所以备份恢复既要遵循 PostgreSQL 的规则,也要特别注意空间表、几何字段、空间索引、扩展版本和坐标系等 GIS 细节。
本文以实际工作流为主,讲清楚 PostGIS备份恢复的常用方式、pg_dump命令怎么写、恢复时容易失败的原因,以及如何验证空间数据是否恢复正确。适合正在维护 PostGIS 数据库、做 WebGIS 后端、或需要迁移 GIS 项目的读者。

引言:PostGIS备份恢复到底备份了什么
在 PostGIS 中,常见数据不只是普通属性表,还包括 geometry 或 geography 空间字段、空间索引、视图、函数、触发器、权限、schema,以及 PostGIS 扩展依赖。做 PostGIS备份恢复时,不能只把 shp、geojson 或业务表导出来就算完成。
简单理解,pg_dump 是 PostgreSQL 官方提供的逻辑备份工具。它可以把数据库对象和数据导出为文件,再在另一台服务器或另一个数据库中恢复。对于 PostGIS 数据库,pg_dump 通常是最常用、最稳妥的迁移方式之一。
一句话记住:PostGIS 的空间数据备份,优先考虑 pg_dump;如果是整个数据库集群级别迁移,再考虑 pg_dumpall 或物理备份。
背景:什么时候需要做PostGIS备份恢复
GIS 项目中,PostGIS备份恢复常见于以下场景:
- 服务器迁移:从旧服务器迁移到新服务器。
- 项目上线:把开发库或测试库迁移到生产库。
- 数据安全:定期备份行政区、道路、管网、影像索引等空间数据。
- 版本升级:升级 PostgreSQL 或 PostGIS 前做完整备份。
- 误删恢复:误删空间表、schema 或业务数据后回滚。
- 跨环境同步:本地 QGIS 编辑后的 PostGIS 数据同步到服务器。
很多恢复失败的问题,并不是 pg_dump命令本身写错,而是目标数据库没有安装 PostGIS 扩展、字符编码不一致、用户权限不足,或者 PostgreSQL/PostGIS 版本差异过大。
原理:pg_dump命令和PostGIS空间数据的关系
pg_dump 是逻辑备份工具,它导出的不是 PostgreSQL 数据目录的原始文件,而是可以重建数据库对象和数据的 SQL 或归档文件。对于 PostGIS 空间表来说,pg_dump 会处理表结构、geometry 字段、空间索引、约束、视图等对象。
常见导出格式有两类:
- SQL 文本格式:通常是
.sql文件,用psql恢复,适合阅读和小规模调整。 - 自定义归档格式:通常是
.dump或.backup文件,用pg_restore恢复,适合生产环境和大库迁移。
在实际项目中,建议优先使用自定义格式:
pg_dump -Fc -h localhost -p 5432 -U postgres -d gisdb -f gisdb.dump
其中:
-Fc表示导出为 custom 自定义归档格式。-h指定数据库主机。-p指定端口,PostgreSQL 默认是 5432。-U指定数据库用户。-d指定要备份的数据库。-f指定输出文件。
步骤:PostGIS备份恢复的推荐操作流程
步骤1:检查源数据库的PostGIS版本
备份前先连接源数据库,确认 PostgreSQL 和 PostGIS 版本。这样恢复到目标环境时,能提前发现版本不兼容风险。
SELECT version();
SELECT postgis_full_version();
如果源库和目标库的 PostgreSQL 主版本差异较大,建议使用新版本客户端的 pg_dump 去备份旧版本数据库。通常不要用低版本 pg_dump 去备份高版本 PostgreSQL 数据库。
步骤2:确认空间表和数据量
可以先查看有哪些 geometry 字段,避免漏掉关键 schema 或空间表。
SELECT f_table_schema, f_table_name, f_geometry_column, srid, type
FROM geometry_columns
ORDER BY f_table_schema, f_table_name;
如果数据库中有多个 schema,例如 public、base、planning、webgis,要确认是备份整个数据库,还是只备份某个 schema。
步骤3:使用pg_dump命令备份整个PostGIS数据库
备份整个数据库是最常见的 PostGIS备份恢复方式:
pg_dump -Fc -h 127.0.0.1 -p 5432 -U postgres -d gisdb -f /backup/gisdb_20250101.dump
如果你希望看到详细过程,可以加上 -v:
pg_dump -Fc -v -h 127.0.0.1 -p 5432 -U postgres -d gisdb -f /backup/gisdb_20250101.dump
如果是在 Linux 定时任务中使用,建议配合 PGPASSWORD 或 .pgpass 文件,避免命令执行时卡在密码输入。
export PGPASSWORD='your_password'
pg_dump -Fc -h 127.0.0.1 -p 5432 -U postgres -d gisdb -f /backup/gisdb_20250101.dump
步骤4:只备份某个schema
如果 GIS 项目按 schema 管理,例如所有业务空间表都在 webgis schema 中,可以只备份该 schema:
pg_dump -Fc -h 127.0.0.1 -p 5432 -U postgres -d gisdb -n webgis -f /backup/webgis_schema.dump
-n 用于指定 schema。这个方式适合多项目共用一个数据库的情况。
步骤5:只备份某张空间表
如果只想备份道路表、地块表或行政区表,可以使用 -t 参数:
pg_dump -Fc -h 127.0.0.1 -p 5432 -U postgres -d gisdb -t public.roads -f /backup/roads.dump
注意,单表备份可能不会完整包含依赖对象。例如视图、函数、关联表、权限等可能需要额外处理。生产环境不建议长期只靠单表备份做灾备。
步骤6:在目标库安装PostGIS扩展
恢复前,目标数据库最好先创建并启用 PostGIS 扩展:
CREATE DATABASE gisdb_restore;
c gisdb_restore
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology;
如果原库没有使用 topology,可以不创建 postgis_topology。但 postgis 扩展通常是必须的,否则 geometry 类型和空间函数无法识别。
步骤7:使用pg_restore恢复.dump文件
如果备份文件是 -Fc 生成的自定义格式,应使用 pg_restore 恢复:
pg_restore -h 127.0.0.1 -p 5432 -U postgres -d gisdb_restore -v /backup/gisdb_20250101.dump
如果目标数据库是空库,这通常可以直接恢复。如果目标库已有同名表,可以加 --clean,让恢复前先删除已有对象:
pg_restore --clean --if-exists -h 127.0.0.1 -p 5432 -U postgres -d gisdb_restore -v /backup/gisdb_20250101.dump
生产环境使用 --clean 要非常谨慎,因为它会删除目标库中的同名对象。
步骤8:如果是.sql文件,用psql恢复
如果 pg_dump 导出的是 SQL 文本文件:
pg_dump -h 127.0.0.1 -p 5432 -U postgres -d gisdb -f /backup/gisdb.sql
恢复时使用 psql:
psql -h 127.0.0.1 -p 5432 -U postgres -d gisdb_restore -f /backup/gisdb.sql
SQL 文本格式的优点是可读、可编辑;缺点是恢复灵活性不如自定义格式,不适合较大的 PostGIS 数据库。
步骤9:验证PostGIS空间数据是否恢复成功
恢复完成后,不要只看命令没有报错,还要验证空间数据是否可用。
建议检查以下内容:
- 空间表数量是否一致。
- 关键表记录数是否一致。
- geometry 字段是否存在。
- SRID 是否正确。
- 空间索引是否恢复。
- QGIS 是否能正常连接和加载图层。
- WebGIS 服务是否能正常查询和渲染。
常用 SQL 如下:
SELECT COUNT(*) FROM public.roads;
SELECT ST_SRID(geom) FROM public.roads LIMIT 5;
SELECT GeometryType(geom) FROM public.roads LIMIT 5;
SELECT ST_IsValid(geom), COUNT(*)
FROM public.roads
GROUP BY ST_IsValid(geom);
检查空间索引:
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'roads';
如果空间查询明显变慢,可以对表执行统计信息更新:
ANALYZE public.roads;
常见坑:PostGIS备份恢复失败的典型原因
1. 目标库没有安装PostGIS扩展
恢复时报错类似 type "geometry" does not exist,通常说明目标数据库没有启用 PostGIS 扩展。
解决方法:
CREATE EXTENSION postgis;
2. pg_dump和数据库版本不匹配
如果使用低版本 pg_dump 备份高版本 PostgreSQL,可能出现版本不支持的错误。建议使用与目标或源数据库兼容的较新版本客户端工具。
3. 恢复时用户权限不足
如果恢复时报 permission denied,说明当前用户没有创建 schema、表、扩展或索引的权限。可以使用数据库超级用户恢复,或提前授予权限。
GRANT CREATE ON DATABASE gisdb_restore TO gis_user;
GRANT USAGE, CREATE ON SCHEMA public TO gis_user;
4. schema没有恢复到预期位置
有些项目习惯把空间表放在 public 之外的 schema 中。恢复后如果 QGIS 或程序找不到表,先确认 schema 名称和搜索路径。
SHOW search_path;
SELECT schemaname, tablename
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema');
5. 空间索引存在但查询还是慢
恢复后空间索引可能存在,但统计信息不完整,查询计划未必立刻最优。对大表执行 ANALYZE 或 VACUUM ANALYZE 很有必要。
VACUUM ANALYZE public.roads;
6. 字符编码或中文字段乱码
如果源库和目标库编码不一致,中文地名、字段注释或属性值可能出现乱码。创建目标数据库时应使用合适编码,常见为 UTF8。
CREATE DATABASE gisdb_restore
WITH ENCODING 'UTF8'
TEMPLATE template0;
7. 只备份表,漏掉视图和函数
WebGIS 项目常用数据库视图封装图层查询,也可能用函数处理空间过滤。只备份单表时,这些对象可能没有同步,导致应用接口报错。
方法比较:pg_dump、pg_dumpall、物理备份怎么选
| 方法 | 适用场景 | 优点 | 注意事项 |
|---|---|---|---|
| pg_dump | 备份单个 PostGIS 数据库、schema 或表 | 灵活、常用、适合迁移和恢复 | 大库恢复时间较长,需要关注扩展和权限 |
| pg_dumpall | 备份整个 PostgreSQL 集群的角色和所有数据库 | 可包含用户、角色等全局对象 | 灵活性不如 pg_dump,恢复控制粒度较粗 |
| pg_basebackup | 物理备份、主从复制、较大生产库 | 适合完整实例级备份 | 对版本、目录、恢复流程要求更高 |
| 导出SHP或GeoPackage | 只交换部分空间图层 | 便于 QGIS、ArcGIS Pro 使用 | 不适合完整数据库备份,容易丢失权限、视图、函数和索引 |
对大多数 GIS 项目来说,如果目标是“迁移一个 PostGIS 项目库”或“定期备份空间数据库”,优先选择 pg_dump -Fc。如果只想把某个图层交给制图人员或外部单位,再考虑 GeoPackage、SHP 或 GeoJSON。
检查清单:执行PostGIS备份恢复前后要确认什么
备份前检查
- 确认源数据库名称、主机、端口和用户。
- 确认 PostgreSQL 和 PostGIS 版本。
- 确认要备份的是整个数据库、某个 schema,还是某些表。
- 确认磁盘空间足够。
- 确认备份文件保存路径有写入权限。
- 确认是否需要备份角色和权限。
- 确认业务系统是否需要暂停写入。
恢复前检查
- 目标 PostgreSQL 服务正常运行。
- 目标数据库编码为 UTF8。
- 目标库已安装 PostGIS 扩展。
- 恢复用户有足够权限。
- 目标库中是否已有同名表,是否允许覆盖。
- 备份文件完整可读。
恢复后检查
- 关键空间表记录数是否正确。
- geometry 字段类型和 SRID 是否正确。
- 空间索引是否存在。
- 视图、函数、触发器是否恢复。
- QGIS 能否正常加载图层。
- WebGIS 服务能否正常访问地图接口。
- 执行
ANALYZE更新统计信息。
FAQ:PostGIS备份恢复常见问题
pg_dump命令是PostGIS专用命令吗?
不是。pg_dump 是 PostgreSQL 的官方逻辑备份命令。PostGIS 是 PostgreSQL 的空间扩展,所以 PostGIS 数据库也使用 pg_dump 进行备份。只要数据库中的 PostGIS 扩展和空间对象处理正确,pg_dump 可以备份空间表和 geometry 字段。
PostGIS备份恢复应该用pg_restore还是psql?
取决于备份格式。如果使用 pg_dump -Fc 导出自定义格式,应使用 pg_restore。如果导出的是普通 .sql 文件,应使用 psql -f 恢复。
为什么恢复时报geometry类型不存在?
通常是目标数据库没有执行 CREATE EXTENSION postgis;。PostGIS 的 geometry 类型由扩展提供,目标库未安装扩展时,恢复空间表结构就会失败。
只备份SHP文件能代替PostGIS备份吗?
不能。SHP 只能保存部分空间图层数据,无法完整保存数据库中的 schema、权限、视图、函数、触发器、空间索引和复杂字段类型。对于正式项目,SHP 导出只能作为数据交换方式,不能替代 PostGIS备份恢复。
PostGIS数据库很大,pg_dump很慢怎么办?
可以优先使用 -Fc 自定义格式,并在恢复时使用并行参数。备份阶段也可以按 schema 或业务模块拆分。对于非常大的生产库,应评估物理备份、主从复制和增量备份方案。
pg_restore -j 4 -h 127.0.0.1 -p 5432 -U postgres -d gisdb_restore /backup/gisdb.dump
恢复后QGIS连接正常,但地图加载很慢怎么办?
先检查空间索引是否存在,再执行 VACUUM ANALYZE。如果 WebGIS 或 QGIS 使用空间范围查询,还要确认查询条件能命中 GiST 空间索引。
VACUUM ANALYZE public.roads;
备份时是否需要停止WebGIS服务?
pg_dump 可以在数据库运行时执行,并能获得一致性快照。但如果业务正在大量写入数据,为了减少数据状态争议,建议在低峰期备份,或在关键迁移前短暂停止写入服务。
结论:推荐的PostGIS备份恢复命令组合
如果你只需要记住一套常用命令,推荐使用下面的 PostGIS备份恢复组合。
备份:
pg_dump -Fc -v -h 127.0.0.1 -p 5432 -U postgres -d gisdb -f /backup/gisdb.dump
创建目标库并启用 PostGIS:
CREATE DATABASE gisdb_restore;
c gisdb_restore
CREATE EXTENSION postgis;
恢复:
pg_restore -v -h 127.0.0.1 -p 5432 -U postgres -d gisdb_restore /backup/gisdb.dump
验证:
SELECT postgis_full_version();
SELECT COUNT(*) FROM public.roads;
SELECT ST_SRID(geom), GeometryType(geom)
FROM public.roads
LIMIT 5;
实际工作中,PostGIS备份恢复不要只关注“命令能不能跑完”,更要关注恢复后的空间表、SRID、空间索引、视图函数和应用连接是否正常。把 pg_dump命令、pg_restore 恢复和恢复后检查清单结合起来,才能真正完成一次可靠的 GIS 数据库备份迁移。