Skip to content

编译源码安装Postgresql和PostGIS(17.4和3.5.2)

wandoubaba / 2025-04-23

介绍

Postgresql简称Postgres或者PG,是开源免费的关系型数据库,各方面指标都可以平替Mysql,甚至可以替代商业数据库产品。

PostGIS是PG的一个可以支持地理信息数据的扩展。

目前笔者刚开始学习GIS领域的知识,需要用到GIS数据库,由于对PG比较了解,所以就自然选择了PostGIS。

环境

学习任何技术都要先从环境开始,本来Docker已经很流行了,在hub.docker.com上也有PostGIS的官方镜像,但是为了学习,我决定先从编译安装开始,下面我将记录整个过程。

本指南的环境如下:

环境项版本
操作系统Debian 12 Arm64
Postgres17.4
PostGIS3.5.2

安装

创建postgres用户和组

sh
sudo groupadd postgres
sudo useradd -g postgres -m postgres

安装依赖

sh
sudo apt-get install -y \
    bzip2 \
    build-essential \
    git wget curl \
    libicu-dev \
    pkg-config \
    bison \
    flex \
    libreadline-dev \
    zlib1g-dev \
    libsystemd-dev \
    libxml2-utils

下载源码

sh
curl -O https://ftp.postgresql.org/pub/source/v17.4/postgresql-17.4.tar.bz2
curl -O https://postgis.net/stuff/postgis-3.5.2.tar.gz

编译安装Postgres

编译

由于安装后我打算通过systemctl设置系统服务,所以加上--with-systemd参数

sh
tar jxvf postgresql-17.4.tar.bz2
cd postgresql-17.4
./configure --with-systemd

构建并安装

sh
make all
su
make install

安装fuzzystrmatch扩展

fuzzystrmatch 是 PostgreSQL 的一个内置扩展模块,提供一组用于模糊字符串匹配的函数。它的核心作用是支持基于相似度的字符串比较,而非精确匹配。

PostGIS由于以下原因而需要用到 fuzzystrmatch 扩展:

  • 地理编码依赖:postgis_tiger_geocoder(美国地址地理编码器)使用 fuzzystrmatch 的算法来:
    • 匹配不规范的地址输入(如拼写错误、缩写)。
    • 计算地址字符串与数据库中记录地址的相似度。
  • 地址标准化:address_standardizer 扩展也依赖它来清洗和标准化地址数据。

在postgres源码目录下执行下面的操作安装fuzzystrmatch扩展。

sh
cd contrib/fuzzystrmatch
make
sudo make install

配置环境

sh
echo 'export PATH=/usr/local/pgsql/bin:$PATH' >> /etc/profile.d/postgres.sh
echo 'export LD_LIBRARY_PATH=/usr/local/pgsql/lib:$LD_LIBRARY_PATH' >>  /etc/profile.d/postgres.sh
source /etc/profile.d/postgres.sh

这里可以验证一下

sh
psql --version

应该可以看到结果

sh
psql (PostgreSQL) 17.4

初始化数据库

sh
mkdir -p /usr/local/pgsql/data
chown -R postgres:postgres /usr/local/pgsql/data
su - postgres
initdb -D /usr/local/pgsql/data

最后一句执行后应该可以看到类似下面的结果

sh
su: warning: cannot change directory to /home/postgres: No such file or directory
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /usr/local/pgsql/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Asia/Shanghai
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /usr/local/pgsql/data -l logfile start

首次启动postgres服务

sh
pg_ctl -D /usr/local/pgsql/data -l logfile start

应该看到类似下面的消息

sh
waiting for server to start.... done
server started

修改配置

编辑postgresql.conf

sh
vim /usr/local/pgsql/data/postgresql.conf

修改内容:

ini
# 监听IP地址设置为*表示允许其他主机连接
listen_addresses = '*'
# 端口号
port = 5432

编辑pg_hba.conf

sh
vim /usr/local/pgsql/data/pg_hba.conf

添加下面这一行表示信任来自本地局域网的连接(根据实际情况编写IP地址)

ini
# IPv4 LAN connections:
host	all		all		192.168.156.0/24	trust

重启postgres服务

sh
pg_ctl -D /usr/local/pgsql/data -l logfile restart

这个时候通过数据库客户端试着连接这个数据库服务,使用用户名postgres,密码空,默认数据库postgres,端口号5432,应该可以连接成功。

配置systemd服务

接下来我们配置一下systemd系统服务:

使用exit命令退出postgres用户,应该可以直接返回到root用户

sh
vim /etc/systemd/system/postgres.service

编辑如下内容

ini
[Unit]
Description=PostgreSQL database server
Documentation=man:postgres(1)
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=infinity

[Install]
WantedBy=multi-user.target

然后让服务生效并实现开机自启

sh
su - postgres -c 'pg_ctl -D /usr/local/pgsql/data -l /usr/local/pgsql/data/logfile stop'
systemctl daemon-reload
systemctl enable postgres
systemctl start postgres

完成上面的操作,postgres服务已经安装完成,重启系统试一下,postgres服务应该可以开机自启。

编译安装PostGIS扩展

安装依赖

sh
sudo apt-get install -y \
    libxml2-dev \
    libgeos-dev \
    libproj-dev \
    libprotobuf-c-dev \
    protobuf-c-compiler \
    libgdal-dev \
    libsfcgal-dev

编译

sh
tar zxvf postgis-3.5.2.tar.gz
cd postgis-3.5.2
./configure \
  --prefix=/usr/local/pgsql \
  --with-pgconfig=/usr/local/pgsql/bin/pg_config \
  --with-geosconfig=/usr/bin/geos-config \
  --with-proj \
  --with-gdalconfig=/usr/bin/gdal-config \
  --with-json-c \
  --with-sfcgal

构建并安装

sh
make
make install

创建数据库并启用PostGIS扩展

sh
sudo su - postgres -c 'createdb postgis_template'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION postgis;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION postgis_raster;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION postgis_sfcgal;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION fuzzystrmatch;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION address_standardizer;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION address_standardizer_data_us;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION postgis_tiger_geocoder;"'
sudo su - postgres -c 'psql postgis_template -c "CREATE EXTENSION postgis_topology;"

验证Postgres和PostGIS

sh
sudo su - postgres -c 'psql -d postgis_template -c "SELECT postgis_full_version();"'

应该可以看到类似下面的结果

sh
POSTGIS="3.5.2 dea6d0a" [EXTENSION] PGSQL="170" GEOS="3.11.1-CAPI-1.17.1" PROJ="9.1.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/pro
j.db" (compiled against PROJ 9.1.1) GDAL="GDAL 3.6.2, released 2023/01/02" LIBXML="2.9.14" LIBJSON="0.16" LIBPROTOBUF="1.4.1" WAGYU="0.5.0 (Internal)" TOPOLOGY RASTER
(1 row)

再试着进入psql命令行:

sh
sudo su - postgres -c 'psql -d postgis_template;'

在psql命令行中执行下面的SQL:

sh
SELECT ST_AsText(ST_GeomFromText('POINT(1 1)'));

应该能看到下面的结果

sh
 st_astext
------------
 POINT(1 1)
(1 row)

执行下面的查询:

sql
SELECT name, default_version,installed_version
FROM pg_available_extensions WHERE name LIKE 'postgis%' or name LIKE 'address%';

应该能看到下面的结果:

sh
             name             | default_version | installed_version
------------------------------+-----------------+-------------------
 postgis                      | 3.5.2           |
 address_standardizer         | 3.5.2           |
 postgis_sfcgal               | 3.5.2           |
 postgis_raster               | 3.5.2           |
 postgis_tiger_geocoder       | 3.5.2           |
 address_standardizer_data_us | 3.5.2           |
 postgis_topology             | 3.5.2           |
(7 rows)

exit命令可以退出psql命令行

完成

以上过程是本人边操作边记录的,结束后又在新的虚拟机上重现了一遍,所以可以保证成功。

Released under the MIT License.