Chapter 3. PostGIS管理

目录
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.conf postgresql.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_DRIVERS POSTGIS_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.sql topology_upgrade.sql sfcgal_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