Chapter 3. PostGIS管理

Table of Contents
3.1. 性能调整
3.1.1. 启动
3.1.2. 运行时
3.2. 配置栅格支持
3.3. 创建空间数据库
3.3.1. 使用扩展在空间上启用数据库
3.3.2. 在不使用扩展的情况下在空间上启用数据库(不鼓励)
3.3.3. 从模板创建支持空间的数据库
3.4. 升级空间数据库
3.4.1. 软升级
3.4.2. 硬升级

3.1. 性能调整

针对PostGIS性能进行的调优与针对任何PostgreSQL工作负载进行的调优非常相似。唯一需要注意的是,几何图形和栅格通常都很大,因此与内存相关的优化通常比其他类型的PostgreSQL查询对PostGIS的影响更大。

有关优化PostgreSQL的一般详细信息,请参阅 调整您的PostgreSQL服务器

对于PostgreSQL 9.4+,无需接触即可在服务器级别设置配置 postgresql.confpostgresql.auto.conf 通过使用 ALTER SYSTEM 指挥部。

ALTER SYSTEM SET work_mem = '256MB';
-- this forces non-startup configs to take effect for new connections
SELECT pg_reload_conf();
-- show current setting value
-- use SHOW ALL to see all settings
SHOW work_mem;

除Postgres设置外,PostGIS还具有中列出的一些自定义设置 Section 8.23, “大统一自定义变量(GUC)”

3.1.1. 启动

这些设置在中配置 postgresql.conf

constraint_exclusion

  • 默认:分区

  • 这通常用于表分区。默认设置为“PARTITION”,这对于PostgreSQL 8.4和更高版本来说非常理想,因为它将强制规划者只分析处于继承层次结构中的表的约束考虑,否则不会支付规划者的惩罚。

shared_buffers

  • 默认:在PostgreSQL 9.6中为~128MB

  • 设置为可用RAM的约25%到40%。在Windows上,您可能无法将其设置为高。

max_worker_processes 此设置仅适用于PostgreSQL 9.4+。对于PostgreSQL 9.6+,此设置具有额外的重要性,因为它控制您可以拥有的并行查询的最大进程数。

  • 默认:8

  • 设置系统可以支持的最大后台进程数。此参数只能在服务器启动时设置。

3.1.2. 运行时

work_mem -设置用于排序操作和复杂查询的内存大小

  • 默认:1-4MB

  • 针对大型数据库、复杂查询、大量RAM进行调整

  • 向下调整以适应并发用户较多或RAM较低的情况。

  • 如果您有大量的RAM,但开发人员很少:

    SET work_mem TO '256MB';

maintenance_work_mem -真空、创建索引等使用的内存大小。

  • 默认:16-64MB

  • 通常过低-占用I/O,在交换内存时锁定对象

  • 建议在具有大量RAM的生产服务器上使用32MB到1 GB,但这取决于并发用户数。如果您有大量的RAM,但开发人员很少:

    SET maintenance_work_mem TO '1GB';

max_parallel_workers_per_gather

此设置仅适用于PostgreSQL 9.6+,并且只会影响PostGIS 2.3+,因为只有PostGIS 2.3+支持并行查询。如果设置为大于0,则某些查询(如涉及关系函数的查询)如下 ST_Intersects 可以使用多个进程,并且运行速度是多个进程的两倍以上。如果您有很多处理器可供备用,则应该将此值更改为您所拥有的处理器数量。也要确保你的身体健康 max_worker_processes 至少和这个数字一样高。

  • 默认值:0

  • 设置一台计算机可以启动的最大工作进程数 Gather 节点。并行工作进程是从 max_worker_processes 。请注意,所请求的工作进程数在运行时可能实际上不可用。如果发生这种情况,该计划运行时的员工人数将少于预期,这可能会降低效率。将此值设置为0(默认值)将禁用并行查询执行。

3.2. 配置栅格支持

如果您启用了栅格支持,您可能希望阅读下面的如何正确配置它。

从PostGIS 2.1.3开始,默认情况下禁用数据库外栅格和所有栅格驱动程序。要重新启用这些环境变量,您需要设置以下环境变量 POSTGIS_GDAL_ENABLED_DRIVERSPOSTGIS_ENABLE_OUTDB_RASTERS 在服务器环境中。对于PostGIS 2.2,您可以使用更具跨平台的方法来设置相应的 Section 8.23, “大统一自定义变量(GUC)”

如果要启用脱机栅格,请执行以下操作:

POSTGIS_ENABLE_OUTDB_RASTERS=1

任何其他设置或根本没有设置都将禁用数据库栅格。

要启用GDAL安装中可用的所有GDAL驱动程序,请按如下方式设置此环境变量

POSTGIS_GDAL_ENABLED_DRIVERS=ENABLE_ALL

如果只想启用特定驱动程序,请按如下方式设置环境变量:

POSTGIS_GDAL_ENABLED_DRIVERS="GTiff PNG JPEG GIF XYZ"
[Note]

如果您使用的是Windows,请不要引用驱动程序列表

环境变量的设置因操作系统而异。对于通过apt-postgreSQL安装在Ubuntu或Debian上的PostgreSQL,首选方式是编辑 /etc/postgresql/10/main/environment 其中,10表示PostgreSQL的版本,main表示集群。

在Windows上,如果你是作为一项服务运行的,你可以通过系统变量来设置在Windows 7中,你可以通过右击Computer- > 属性高级系统设置或在资源管理器中导航到 Control Panel\All Control Panel Items\System 。然后点击 高级系统设置- > 高级->环境变量 以及添加新的系统变量。

设置环境变量后,需要重新启动PostgreSQL服务才能使更改生效。

3.3. 创建空间数据库

3.3.1. 使用扩展在空间上启用数据库

如果您使用的是PostgreSQL9.1+,并且已经编译和安装了扩展/postgis模块,则可以使用扩展机制将数据库转换为空间数据库。

核心的Postgis扩展包括几何、地理、空间参考系统以及所有的函数和注释。栅格和拓扑被打包为单独的扩展。

在要在空间上启用的数据库中运行以下SQL代码片段:

CREATE EXTENSION IF NOT EXISTS plpgsql;
      CREATE EXTENSION postgis;
      CREATE EXTENSION postgis_raster; -- OPTIONAL
      CREATE EXTENSION postgis_topology; -- OPTIONAL

3.3.2. 在不使用扩展的情况下在空间上启用数据库(不鼓励)

[Note]

通常只有当您不能或不想在PostgreSQL扩展目录中安装PostGIS时(例如,在测试、开发期间或在受限环境中),才需要这样做。

将PostGIS对象和函数定义添加到数据库中的方法是加载位于 [prefix]/share/contrib 如在构建阶段指定的。

核心PostGIS对象(几何和地理类型及其支持函数)位于 postgis.sql 剧本。栅格对象位于 rtpostgis.sql 剧本。拓扑对象位于 topology.sql 剧本。

对于一组完整的EPSG坐标系定义标识符,还可以将 spatial_ref_sys.sql 定义文件并填充 spatial_ref_sys 数据表。这将允许您对几何体执行ST_Transform()操作。

如果您想要向PostGIS函数添加注释,可以在 postgis_comments.sql 剧本。只需输入以下内容即可查看评论 \dd [function_name] 从一个 psql 终端窗口。

在您的终端中运行以下外壳命令:

DB=[yourdatabase]
    SCRIPTSDIR=`pg_config --sharedir`/contrib/postgis-3.2/

    # Core objects
    psql -d ${DB} -f ${SCRIPTSDIR}/postgis.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/spatial_ref_sys.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/postgis_comments.sql # OPTIONAL

    # Raster support (OPTIONAL)
    psql -d ${DB} -f ${SCRIPTSDIR}/rtpostgis.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/raster_comments.sql # OPTIONAL

    # Topology support (OPTIONAL)
    psql -d ${DB} -f ${SCRIPTSDIR}/topology.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/topology_comments.sql # OPTIONAL

3.3.3. 从模板创建支持空间的数据库

一些打包的PostGIS发行版(特别是用于PostGIS的Win32安装程序 > =1.1.5)将PostGIS函数加载到名为 template_postgis 。如果 template_postgis 数据库存在于您的PostgreSQL安装中,则用户和/或应用程序可以使用单个命令创建空间启用的数据库。请注意,在这两种情况下,数据库用户都必须被授予创建新数据库的权限。

从外壳中:

# createdb -T template_postgis my_spatial_db

来自SQL:

postgres=# CREATE DATABASE my_spatial_db TEMPLATE=template_postgis

3.4. 升级空间数据库

升级现有的空间数据库可能很棘手,因为它需要替换或引入新的PostGIS对象定义。

遗憾的是,并不是所有的定义都可以在实时数据库中轻松替换,所以有时您最好的选择是转储/重新加载过程。

PostGIS为次要或错误修复版本提供了软升级过程,为主要版本提供了硬升级过程。

在尝试升级PostGIS之前,备份您的数据总是值得的。如果您使用-fc标志来pg_ump,您将始终能够通过硬升级恢复转储。

3.4.1. 软升级

如果您使用扩展安装数据库,则还需要使用扩展模型进行升级。如果您使用旧的SQL脚本方式安装,建议您将安装切换到扩展,因为脚本方式不再受支持。

3.4.1.1. 使用扩展的软件升级9.1+

如果您最初安装的是带有扩展的PostGIS,那么您也需要使用扩展进行升级。用扩展进行一个小的升级是相当容易的。

如果您运行的是PostGIS3或更高版本,则应使用 PostGIS_Extensions_Upgrade 功能可升级到您已安装的最新版本。

SELECT postgis_extensions_upgrade();

如果您运行的是PostGIS 2.5或更低版本,请执行以下操作:

ALTER EXTENSION postgis UPDATE;
SELECT postgis_extensions_upgrade();
-- This second call is needed to rebundle postgis_raster extension
SELECT postgis_extensions_upgrade();

如果您安装了多个版本的PostGIS,并且不想升级到最新版本,则可以按如下方式明确指定版本:

ALTER EXTENSION postgis UPDATE TO "3.3.0dev";
ALTER EXTENSION postgis_topology UPDATE TO "3.3.0dev";

如果收到类似以下内容的错误通知:

No migration path defined for … to 3.3.0dev

然后,您需要备份数据库,创建一个新的数据库,如中所述 Section 3.3.1, “使用扩展在空间上启用数据库” 然后在这个新数据库上恢复备份。

如果您收到如下通知消息:

Version "3.3.0dev" of extension "postgis" is already installed

那么一切都已经是最新的,您可以放心地忽略它。 UNLESS 您正在尝试从开发版本升级到下一个版本(没有获得新的版本号);在这种情况下,您可以在版本字符串后附加“Next”,下一次您将需要再次删除“Next”后缀:

ALTER EXTENSION postgis UPDATE TO "3.3.0devnext";
ALTER EXTENSION postgis_topology UPDATE TO "3.3.0devnext";
[Note]

如果最初安装的PostGIS没有指定版本,则在恢复之前通常可以跳过重新安装postgis扩展模块,因为备份刚刚 CREATE EXTENSION postgis 从而在恢复期间获取最新的最新版本。

[Note]

如果要从3.0.0之前的版本升级PostGIS扩展模块,您将拥有一个新的扩展模块 postgis_raster 如果您不需要栅格支持,则可以安全地将其删除。您可以按如下方式删除:

DROP EXTENSION postgis_raster;

3.4.1.2. 9.1+版或无扩展版的软件升级

本节仅适用于安装了未使用扩展的PostGIS的用户。如果您有扩展并尝试使用此方法进行升级,您将收到如下消息:

can't drop … because postgis extension depends on it

注意:如果要从PostGIS 1.*迁移到PostGIS 2.*或从PostGIS 2.*迁移到r7409之前的版本,则不能使用此过程,而是需要执行 硬升级

在编译和安装(Make Install)之后,您应该会找到一组 *_upgrade.sql 安装文件夹中的文件。您可以使用以下命令将它们全部列出:

ls `pg_config --sharedir`/contrib/postgis-3.3.0dev/*_upgrade.sql

依次加载它们,从 postgis_upgrade.sql

psql -f postgis_upgrade.sql -d your_spatial_database

同样的过程也适用于栅格、拓扑和sfcga扩展模块,升级文件的名称为 rtpostgis_upgrade.sqltopology_upgrade.sqlsfcgal_upgrade.sql 分别为。如果需要,请执行以下操作:

psql -f rtpostgis_upgrade.sql -d your_spatial_database
psql -f topology_upgrade.sql -d your_spatial_database
psql -f sfcgal_upgrade.sql -d your_spatial_database

建议您通过运行以下命令切换到基于扩展的安装

psql -c "SELECT postgis_extensions_upgrade();"
[Note]

如果您找不到 postgis_upgrade.sql 特定于升级您的版本您正在使用的版本对于软升级来说太早了,并且需要执行 硬升级

这个 PostGIS_Full_Version 函数应使用“PROCS Need Upgrade”消息通知您是否需要运行此类升级。

3.4.2. 硬升级

我们所说的硬升级是指完全转储/重新加载启用了postgis的数据库。当PostGIS对象的内部存储发生变化或无法进行软升级时,您需要进行硬升级。这个 发行说明 附录报告了每个版本是否需要转储/重新加载(硬升级)才能升级。

转储/重新加载过程得到postgis_Restore.pl脚本的帮助,该脚本负责从转储跳过属于PostGIS(包括旧定义)的所有定义,允许您将模式和数据恢复到安装了PostGIS的数据库中,而不会出现重复的符号错误或转发不推荐使用的对象。

有关Windows用户的补充说明,请访问 Windows硬件升级

具体步骤如下:

  1. 为您想要升级的数据库创建一个“定制格式”的转储文件(我们称之为 olddb )包括二进制斑点(-b)和详细(-v)输出。用户可以是数据库的所有者,不需要是postgres超级帐户。

    pg_dump -h localhost -p 5432 -U postgres -Fc -b -v -f "/somepath/olddb.backup" olddb
  2. 在新数据库中全新安装PostGIS--我们将该数据库称为 newdb 。请参阅 Section 3.3.2, “在不使用扩展的情况下在空间上启用数据库(不鼓励)”Section 3.3.1, “使用扩展在空间上启用数据库” 获取有关如何执行此操作的说明。

    将恢复在转储中找到的SPATIAL_REF_SYS条目,但不会覆盖SPATIAL_REF_SYS中的现有条目。这是为了确保官方集中的修复将被正确地传播到恢复的数据库。如果出于任何原因,您确实希望覆盖自己的标准条目,那么在创建新的数据库时,不要加载spatial_ref_sys.sql文件。

    如果您的数据库真的很旧,或者您知道您在视图和函数中使用了长期不推荐使用的函数,则可能需要加载 legacy.sql 以便您的所有函数和视图等都能正常恢复。只有在真的需要时才这样做。如果可能的话,在转储之前考虑升级您的视图和功能。不推荐使用的函数稍后可以通过加载 uninstall_legacy.sql

  3. 将您的备份恢复到新的 newdb 使用postgis_Restore.pl的数据库。意外错误(如果有)将由psql打印到标准错误流中。把这些都记下来。

    perl utils/postgis_restore.pl "/somepath/olddb.backup" | psql -h localhost -p 5432 -U postgres newdb 2> errors.txt

在以下情况下可能会出现错误:

  1. 您的一些视图或函数使用了不推荐使用的PostGIS对象。要修复此问题,您可以尝试加载 legacy.sql 在恢复之前编写脚本,否则您将不得不恢复到仍然包含这些对象的PostGIS版本,并在移植代码后再次尝试迁移。如果 legacy.sql 方法适用于您,不要忘记修复您的代码以停止使用不推荐使用的函数,并停止加载它们 uninstall_legacy.sql

  2. 转储文件中SPATIAL_REF_SYS的某些自定义记录的SRID值无效。有效的SRID值大于0小于999000。999000.999999范围内的值保留供内部使用,而大于999999的值根本不能使用。具有无效SRID的所有自定义记录都将被保留,那些 >999999的记录将被移入保留范围,但是SPATIAL_REF_SYS表将失去一个检查约束,该约束保护该不变量以及它的主键(当多个无效的SRID被转换为相同的保留SRID值时)。

    In order to fix this you should copy your custom SRS to a SRID with a valid value (maybe in the 910000..910999 range), convert all your tables to the new srid (see 更新几何SRID), delete the invalid entry from spatial_ref_sys and re-construct the check(s) with:

    ALTER TABLE spatial_ref_sys ADD CONSTRAINT spatial_ref_sys_srid_check check (srid > 0 AND srid < 999000 );

    ALTER TABLE spatial_ref_sys ADD PRIMARY KEY(srid));

    If you are upgrading an old database containing french IGN cartography, you will have probably SRIDs out of range and you will see, when importing your database, issues like this :

     WARNING: SRID 310642222 converted to 999175 (in reserved zone)

    In this case, you can try following steps : first throw out completely the IGN from the sql which is resulting from postgis_restore.pl. So, after having run :

    perl utils/postgis_restore.pl "/somepath/olddb.backup" > olddb.sql

    run this command :

    grep -v IGNF olddb.sql > olddb-without-IGN.sql

    Create then your newdb, activate the required Postgis extensions, and insert properly the french system IGN with : this script After these operations, import your data :

    psql -h localhost -p 5432 -U postgres -d newdb -f olddb-without-IGN.sql  2> errors.txt