Ubuntu 24.04 PostgreSQL + PostGIS 完整安装与配置指南
PostGIS 是 PostgreSQL 的空间数据库扩展,为地理空间数据提供了强大的存储、查询和分析功能。本教程将详细介绍在 Ubuntu 24.04 上集成 PostGIS 的完整流程。
1. 系统环境准备
1.1 更新系统包
bash
# 更新软件包列表
sudo apt update
# 升级现有软件包
sudo apt upgrade -y
# 清理不需要的包
sudo apt autoremove -y
1.2 安装必要的依赖
bash
# 安装编译工具和依赖
sudo apt install -y \
build-essential \
wget \
curl \
git \
software-properties-common \
lsb-release \
ca-certificates \
gnupg
2. 安装 PostgreSQL
2.1 添加 PostgreSQL 官方仓库
bash
# 创建仓库配置文件
sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# 导入 GPG 密钥
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
# 更新包列表
sudo apt update
2.2 安装 PostgreSQL 16(最新稳定版)
bash
# 安装 PostgreSQL 16 及其常用扩展
sudo apt install -y \
postgresql-16 \
postgresql-client-16 \
postgresql-contrib-16 \
postgresql-server-dev-16
2.3 验证安装
bash
# 检查 PostgreSQL 服务状态
sudo systemctl status postgresql
# 查看 PostgreSQL 版本
sudo -u postgres psql -c "SELECT version();"
# 设置开机自启
sudo systemctl enable postgresql
3. 安装 PostGIS
3.1 安装 PostGIS 扩展
bash
# 安装 PostGIS 及其依赖
sudo apt install -y \
postgis \
postgresql-16-postgis-3 \
postgresql-16-postgis-3-scripts \
postgresql-16-postgis-3-dbgsym
# 安装 PostGIS 工具和额外扩展
sudo apt install -y \
postgis-gui \
postgis-doc \
gdal-bin \
proj-bin \
libgeos-dev \
libproj-dev
3.2 验证 PostGIS 安装
bash
# 检查 PostGIS 相关包是否安装成功
dpkg -l | grep postgis
# 查看 GDAL 版本(PostGIS 依赖)
gdalinfo --version
# 查看 GEOS 版本
geos-config --version
4. 创建空间数据库
4.1 切换到 postgres 用户
bash
sudo -i -u postgres
4.2 创建专用空间数据库
bash
# 创建新的数据库
createdb gis_database
# 进入 PostgreSQL 控制台
psql -d gis_database
4.3 启用 PostGIS 扩展
在 psql 命令行中执行:
sql
-- 启用 PostGIS 核心扩展
CREATE EXTENSION postgis;
-- 启用 PostGIS 拓扑扩展(用于拓扑关系)
CREATE EXTENSION postgis_topology;
-- 启用 PostGIS 栅格扩展(处理栅格数据)
CREATE EXTENSION postgis_raster;
-- 启用 PostGIS SFCGAL 扩展(3D 和高级几何操作)
CREATE EXTENSION postgis_sfcgal;
-- 启用地址标准化扩展
CREATE EXTENSION address_standardizer;
CREATE EXTENSION address_standardizer_data_us;
-- 启用三维扩展
CREATE EXTENSION postgis_rtpostgis;
-- 查看已启用的扩展
\dx
4.4 验证 PostGIS 安装成功
sql
-- 检查 PostGIS 版本
SELECT PostGIS_Version();
SELECT PostGIS_Full_Version();
-- 测试空间函数
SELECT ST_Point(1, 2);
SELECT ST_Area(ST_GeomFromText('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'));
-- 查看空间参考系统
SELECT srid, auth_name, auth_srid, srtext FROM spatial_ref_sys LIMIT 5;
5. 配置远程访问
5.1 退出 psql 并返回普通用户
sql
-- 退出 psql
\q
-- 退出 postgres 用户
exit
5.2 配置 PostgreSQL 允许远程连接
bash
# 编辑 PostgreSQL 配置文件
sudo nano /etc/postgresql/16/main/postgresql.conf
修改以下配置:
ini
# 监听所有网络接口
listen_addresses = '*'
# 设置端口(默认 5432)
port = 5432
# 增加连接数限制
max_connections = 100
# 共享缓冲区大小(根据内存调整)
shared_buffers = 256MB
# 工作内存
work_mem = 16MB
# 维护工作内存
maintenance_work_mem = 64MB
5.3 配置客户端认证
bash
sudo nano /etc/postgresql/16/main/pg_hba.conf
在文件末尾添加:
ini
# 允许所有 IP 通过密码访问(开发环境)
# 生产环境建议限制特定 IP 或网段
# IPv4 本地连接
host all all 127.0.0.1/32 scram-sha-256
# IPv4 远程连接
host all all 0.0.0.0/0 scram-sha-256
# IPv6 本地连接
host all all ::1/128 scram-sha-256
# IPv6 远程连接
host all all ::/0 scram-sha-256
5.4 设置 PostgreSQL 密码
bash
# 切换到 postgres 用户
sudo -u postgres psql
# 在 psql 中修改密码
ALTER USER postgres WITH PASSWORD 'YourStrongPassword123!';
# 创建专用 GIS 用户
CREATE USER gis_admin WITH PASSWORD 'GisAdminPass456!';
ALTER USER gis_admin WITH SUPERUSER;
# 授予数据库权限
GRANT ALL PRIVILEGES ON DATABASE gis_database TO gis_admin;
# 退出
\q
5.5 重启 PostgreSQL 服务
bash
sudo systemctl restart postgresql
# 检查服务状态
sudo systemctl status postgresql
6. 防火墙配置
bash
# 如果使用 UFW 防火墙
sudo ufw allow 5432/tcp
sudo ufw reload
# 查看防火墙状态
sudo ufw status
# 如果使用 iptables
sudo iptables -A INPUT -p tcp --dport 5432 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
7. 安装 QGIS 桌面客户端(可选)
bash
# 添加 QGIS 官方仓库
sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
# 更新包列表
sudo apt update
# 安装 QGIS
sudo apt install -y qgis qgis-plugin-grass
# 安装 QGIS 服务器
sudo apt install -y qgis-server
8. 测试空间数据库功能
8.1 创建测试数据表
bash
# 使用新用户连接数据库
psql -h localhost -U gis_admin -d gis_database
执行以下 SQL:
sql
-- 创建包含空间字段的表
CREATE TABLE buildings (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
geometry GEOMETRY(Polygon, 4326),
height FLOAT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建点数据表
CREATE TABLE points_of_interest (
id SERIAL PRIMARY KEY,
poi_name VARCHAR(100),
description TEXT,
location GEOMETRY(Point, 4326),
category VARCHAR(50)
);
-- 创建空间索引
CREATE INDEX idx_buildings_geometry ON buildings USING GIST (geometry);
CREATE INDEX idx_poi_location ON points_of_interest USING GIST (location);
-- 插入测试数据
INSERT INTO buildings (name, geometry, height) VALUES
('Main Building',
ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))', 4326),
25.5);
INSERT INTO points_of_interest (poi_name, description, location, category) VALUES
('Central Park',
'Main city park with playground',
ST_SetSRID(ST_MakePoint(-74.0060, 40.7128), 4326),
'Park');
-- 空间查询示例
-- 1. 计算面积
SELECT name, ST_Area(geometry) as area FROM buildings;
-- 2. 计算距离
SELECT poi_name,
ST_Distance(
location,
ST_SetSRID(ST_MakePoint(-74.0059, 40.7129), 4326)
) as distance_meters
FROM points_of_interest;
-- 3. 缓冲区查询
SELECT * FROM points_of_interest
WHERE ST_DWithin(
location,
ST_SetSRID(ST_MakePoint(-74.0060, 40.7128), 4326),
0.01 -- 约 1.1km
);
-- 查看所有空间表
SELECT f_table_name, f_geometry_column, srid, type
FROM geometry_columns;
9. 常用维护命令
9.1 数据库管理
bash
# 备份数据库(包含 PostGIS 数据)
sudo -u postgres pg_dump -Fc -Z 9 gis_database > gis_backup.dump
# 恢复数据库
sudo -u postgres pg_restore -d gis_database gis_backup.dump
# 查看数据库大小
sudo -u postgres psql -c "\l+ gis_database"
# 清理数据库
sudo -u postgres vacuumdb --analyze --all
9.2 空间数据处理工具
bash
# 使用 shp2pgsql 导入 Shapefile
shp2pgsql -s 4326 -I path/to/shapefile.shp table_name | psql -d gis_database
# 使用 ogr2ogr 导入多种格式
ogr2ogr -f "PostgreSQL" PG:"dbname=gis_database host=localhost user=gis_admin" input.geojson
# 使用 pgsql2shp 导出 Shapefile
pgsql2shp -f output.shp -h localhost -u gis_admin gis_database "SELECT * FROM buildings"
10. 性能优化配置
10.1 PostgreSQL 优化
bash
sudo nano /etc/postgresql/16/main/postgresql.conf
添加或修改以下配置:
ini
# PostGIS 特定优化
shared_preload_libraries = 'postgis-3'
# 增加工作内存用于复杂空间查询
work_mem = 32MB
# 增加维护内存
maintenance_work_mem = 128MB
# 设置 checkpoint 间隔
checkpoint_completion_target = 0.9
# 启用并行查询
max_parallel_workers_per_gather = 4
max_parallel_workers = 8
# 统计信息收集
track_counts = on
track_activities = on
track_io_timing = on
10.2 重启服务应用配置
bash
sudo systemctl restart postgresql
11. 监控和调试
11.1 监控工具安装
bash
# 安装监控扩展
sudo -u postgres psql -d gis_database -c "CREATE EXTENSION pg_stat_statements;"
# 安装 PostGIS 调试工具
sudo apt install -y postgis-utils
11.2 常用监控查询
sql
-- 查看空间表大小
SELECT
table_name,
pg_size_pretty(pg_total_relation_size(table_name)) as total_size,
pg_size_pretty(pg_relation_size(table_name)) as table_size,
pg_size_pretty(pg_total_relation_size(table_name) - pg_relation_size(table_name)) as index_size
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY pg_total_relation_size(table_name) DESC;
-- 查看最慢的查询
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
-- 查看空间索引使用情况
SELECT
tablename,
indexname,
idx_scan as index_scans
FROM pg_indexes
WHERE schemaname = 'public'
ORDER BY idx_scan DESC;
12. 常见问题解决
12.1 PostGIS 扩展启用失败
bash
# 重新安装 PostGIS 扩展
sudo apt install --reinstall postgresql-16-postgis-3
# 在数据库中重新创建扩展
sudo -u postgres psql -d gis_database -c "DROP EXTENSION IF EXISTS postgis CASCADE;"
sudo -u postgres psql -d gis_database -c "CREATE EXTENSION postgis;"
12.2 空间参考系统问题
sql
-- 查看可用的空间参考系统
SELECT srid, auth_name, srtext
FROM spatial_ref_sys
WHERE auth_name = 'EPSG'
AND srid IN (4326, 3857, 26910);
-- 添加自定义空间参考系统(如果需要)
INSERT INTO spatial_ref_sys (srid, auth_name, auth_srid, srtext, proj4text)
VALUES (999999, 'LOCAL', 999999, 'CUSTOM CRS', '+proj=longlat +datum=WGS84 +no_defs');
12.3 连接问题
bash
# 检查 PostgreSQL 日志
sudo tail -f /var/log/postgresql/postgresql-16-main.log
# 测试本地连接
psql -h localhost -U gis_admin -d gis_database
# 测试远程连接(从另一台机器)
psql -h <服务器IP> -p 5432 -U gis_admin -d gis_database
13. 生产环境建议
-
安全加固:
- 使用 SSL/TLS 加密连接
- 配置更严格的 pg_hba.conf 规则
- 定期更新密码
-
备份策略:
bash# 创建每日备份脚本 sudo nano /usr/local/bin/backup_gis.shbash#!/bin/bash BACKUP_DIR="/var/backups/postgresql" DATE=$(date +%Y%m%d_%H%M%S) sudo -u postgres pg_dump -Fc gis_database > $BACKUP_DIR/gis_backup_$DATE.dump find $BACKUP_DIR -name "*.dump" -mtime +7 -delete -
监控告警:
- 设置磁盘空间监控
- 监控数据库连接数
- 定期检查慢查询日志