进阶 postgis.net 2026-10-09 21:31:24 · 6 阅读

第15章 PostGIS 第15章:将 postgis_sfcgal 升级到 3.1 及以上版本

第15章:将 postgis_sfcgal 升级到 3.1 或更高版本

从 PostGIS 3.1 开始,PostGIS 的 sfcgal 支持库不再作为 postgis 核心库的一部分,而是被分离并创建为一个新的库 `postgis_sfcgal-3`。对于从编译时包含 SFCGAL 的 PostGIS < 3.1 进行常规软升级到包含 SFCGAL 的 PostGIS >= 3.1 的用户来说,这一变化并不构成问题,只需使用 `ALTER EXTENSION postgis_sfcgal UPDATE;` 或 `SELECT postgis_extensions_upgrade();` 即可。

然而,如果你使用 pg_upgrade,可能会遇到类似“postgis-3 does not contain function postgis_sfcgal_version()”(这是 postgis_sfcgal 扩展的一部分)的错误。导致这种不兼容性的主要原因有三点:

1. 我们希望 postgis-3 库无论是否使用 SFCGAL 编译,都暴露相同的函数接口。这一变更最初计划在 PostGIS 3.0 中实施,但当时仅移除了后端切换的机制,而未完全实现分离。 2. 这使得打包者可以提供 postgis_sfcgal(可能作为单独的包),而不必强制仅需要 postgis 的用户安装 boost 和 CGAL。 3. 过去,postgis_sfcgal 和 postgis 扩展在底层库中紧密耦合,因为存在诸如 ST_3DIntersects 和 ST_Intersects 这样名称重叠的函数。向用户解释这套机制的工作原理(例如在需要扩展 3D 功能时切换后端到 sfcgal,以及在升级过程中可能出现的 GUC 后端通知带来的额外麻烦)是一件非常令人头疼且性价比很低的事情。因此,未来我们将不再在这两个扩展之间复用函数名称,而是仅使用非重叠的函数名称。

选项 1

在使用 pg_upgrade 升级 PostGIS < 3.1 的 postgis_sfcgal 时,最简单的修复方法是在运行 pg_upgrade 之前先删除(drop)postgis_sfcgal 扩展。由于 postgis_sfcgal 扩展仅包含函数而不包含数据类型,因此删除该扩展不会导致数据丢失。

可以在旧集群中执行以下命令来删除扩展:

```sql -- 在尝试 pg_upgrade 之前的旧集群中执行 -- 此步骤仅适用于 PostGIS < 3.1.0 DROP EXTENSION postgis_sfcgal; ```

如果存在绑定到 postgis_sfcgal 函数的视图、SQL 函数或约束,上述 `DROP EXTENSION` 命令将会失败。在这种情况下,你可以在 pg_upgrade 之前一并删除这些依赖项,并确保你拥有重建这些对象的代码。或者,你可以选择执行选项 2。

在旧集群中删除扩展后,即可运行 pg_upgrade。pg_upgrade 完成后,在新集群中重新添加该扩展:

```sql CREATE EXTENSION postgis_sfcgal; ```

如果未将扩展安装在与 postgis 扩展相同的模式中,创建扩展时将报错。如果出现错误,请显式指定安装 postgis 的模式:

```sql CREATE EXTENSION postgis_sfcgal SCHEMA postgis; ```

选项 2

在旧集群上,确保已安装 3.1 或更高版本的 postgis 二进制文件,然后执行以下操作:

```sql ALTER EXTENSION postgis UPDATE; SELECT postgis_extensions_upgrade(); ```

随后,按照常规流程运行 pg_upgrade。

评论 (0)