如果您想将应用从 Spanner 或 Google Cloud迁移到其他 PostgreSQL 方言数据库,请参阅本页面,了解从 Spanner 迁移到其他 PostgreSQL 方言数据库时需要注意的主要事项和要遵循的步骤。如果您需要了解或证明迁移数据库的可行性(例如,为应急退出灾难预案做准备),也可以使用本页中的信息。
对于需要选择部署到其他与 PostgreSQL 兼容的环境( Google Cloud内或其他位置)的应用,Spanner 的 PostgreSQL 页面是最佳选择。PostgreSQL 页面使用 PostgreSQL 生态系统中熟悉的语法和标准客户端,让开发者和运维人员能够使用现有的 PostgreSQL 知识和技能。
它使用与 GoogleSQL 方言相同的查询处理、事务协调、分布式存储和网络基础架构。如果您需要支持可移植性的数据库,选择 PostgreSQL 页面后,您无需在 Spanner 的核心可伸缩性、一致性或性价比方面做出妥协。
详细了解 Spanner 中的 PostgreSQL 和 GoogleSQL 方言之间的差异。
大致步骤如下:
- 从查询和 DDL 语句中移除 Spanner 专用扩展
- 迁移架构
- 迁移数据
- 迁移应用
特定于 Spanner 的注意事项
Spanner 的 PostgreSQL 页面开箱即支持 PostgreSQL 查询,因此在 Spanner PostgreSQL 方言数据库上运行的大多数 SQL 查询的行为与其他兼容 PostgreSQL 的数据库相同。采用这种方法,从一个平台迁移到另一个平台所需的 SQL 和数据访问更改次数可能会很少。与类似的 GoogleSQL 方言数据库相比,这样可以让移植过程更快、更简单,并且不易出错。
除了广泛的 PostgreSQL 兼容性之外,PostgreSQL 页面还提供了一些特定于 Spanner 的扩展程序。如果您在应用中使用这些扩展,则必须将其移除或手动映射到 PostgreSQL 功能。查询语法扩展和架构管理 (DDL) 扩展中列出了一些值得注意的示例。
查询语法扩展
Spanner 的 PostgreSQL 页面提供了一些 Spanner 专用扩展。大多数使用前缀 spanner.
进行标识。下表列出了这些扩展程序,以及您可能需要执行的操作,以便在 PostgreSQL 数据库上运行同一应用。
扩展程序类型 | 特定扩展程序 | 迁移前要执行的操作 |
Spanner 专用函数 | 查找前缀为 spanner. 的函数,并移除这些调用。
|
|
类型扩展 |
|
移除 VECTOR LENGTH 语法,或考虑使用 pgvector。
|
查询语法 | 无需执行任何操作,因为提示会显示在注释中。
如需详细了解性能注意事项,请参阅查询迁移。 |
|
存储的系统过程 | 移除对 spanner.cancel_query() 的调用。
您可以选择将这些调用替换为 PostgreSQL 等效项。 |
|
SET/SHOW 操作 | 可以忽略,因为 PostgreSQL 没有任何以 spanner. 开头的内置参数,因此使用该前缀设置任何变量都不会对预期行为产生任何影响。 |
架构管理 (DDL) 扩展
Spanner 提供了一系列与数据管理相关的扩展,如数据定义语言 (DDL) 页面中所述。
扩展程序 | 迁移前要执行的操作 |
交错表
在物理存储空间中将多对一相关数据放置在一起,从而显著提高对这些数据进行联接的效率。 |
移除 INTERLEAVE IN 子句。 |
提交时间戳
支持以原子方式将事务的提交时间戳存储到列中。 |
请将 SPANNER.COMMIT_TIMESTAMP 替换为 PostgreSQL 时间戳类型,并在应用中管理时间戳设置,或者移除该列。
|
时间点恢复
可防止意外删除或写入。 |
移除所有用于设置 spanner.version_retention_period 的 DDL 语句。
|
存留时间 (TTL)
提示系统根据记录的存活时间自动删除记录。 |
移除 TTL INTERVAL 子句。考虑利用 cron 或安排的任务定期删除过时数据。行。
|
优化器选项
设置选项,以最大限度地降低在查询优化器或统计信息发生变化时出现性能回归的可能性。 |
移除了用于设置优化器选项的 DDL 语句。 |
变更数据流
近乎实时监控 Spanner 数据库的数据更改(插入、更新和删除)并将其流式传输出去。 |
移除与变更数据流相关的所有 DDL 语句。 |
默认主副本
可让您在双区域和多区域配置中为数据库指定主副本。 |
移除所有用于设置 spanner.default_leader 的 DDL 语句。
|
地理分区
可让您进一步对不同实例配置中数据库表内的行数据进行细分和存储。 |
移除与地理分区相关的所有 DDL 语句。 |
序列
Spanner 仅支持 bit_reversed_positive 序列。 |
将 bit_reversed_positive 替换为 PostgreSQL 中提供的序列。 |
架构迁移
您可以使用 PostgreSQL 语法导出 PostgreSQL 方言数据库架构。对于配置为使用 PostgreSQL 页面的数据库,您可以使用 psql
通过 PGAdapter 实现此目的,该边车代理可让您使用标准 PostgreSQL 驱动程序或客户端库连接到 Spanner:
psql -v ON_ERROR_STOP=1 \
--host "$PGADAPTER_HOST" \
--port "$PGADAPTER_PORT" \
--dbname "$SPANNER_DATABASE" \
-qAtX \
-c "show database ddl"
您还可以使用以下 gcloud
命令将架构输出为与 PostgreSQL 兼容的 SQL 脚本:
gcloud spanner databases ddl describe databasename
如果数据库使用 Spanner 专用架构扩展(例如架构管理扩展中所述的扩展),则在您运行此命令时,系统会列出这些扩展。您需要先移除这些字段,然后才能将架构迁移到 PostgreSQL。
数据迁移
Spanner 的 PostgreSQL 页面使用 PGAdapter 支持 PostgreSQL 的 COPY TO STDIN
和 STDOUT
扩展程序。这是将数据加载到 Spanner 和从中加载数据的一种方法。如需详细了解 COPY
命令,请参阅 Spanner 专用 psql 命令行工具文档。
以下脚本可将较少量的数据(建议不超过 100 GB)从 Spanner 的 PostgreSQL 页面导出到新的 PostgreSQL 数据库:
psql -h pgadapter-host -c "COPY $TABLE TO STDOUT BINARY" | \
psql -h postgresql-host -c "COPY $TABLE FROM STDIN BINARY"
对于较大的表(数据量大于或等于 100 GB),您可以启动将 Dataflow 导出到 CSV 模板。
您可以使用 Debezium Kafka 连接器执行实时数据迁移,以便将 Spanner 更新流式传输到 PostgreSQL。如果您使用 Spanner Change Streams API 直接访问变更数据捕获 (CDC) 数据流,则可以进一步对其进行自定义。
查询迁移
适用于 Spanner 的 PostgreSQL 页面实现了许多最常见的 PostgreSQL 查询语法、函数和运算符。
如果您在查询中使用了提示,则无需重写查询,因为 Spanner 上的查询提示是在与 PostgreSQL 兼容的注释中定义的:
SELECT s.FirstName, s.LastName,
s.SingerInfo, a.AlbumTitle, a.Charts
FROM Singers AS s
LEFT OUTER JOIN/*@JOIN_METHOD=APPLY_JOIN*/ Albums AS a
ON s.SingerId = a.SingerId;
这些注释由 Spanner 的查询规划器处理,但 PostgreSQL 数据库会忽略这些注释,因此您可以选择添加或移除这些注释。
为了在新环境中实现最佳性能,可能需要针对新环境优化查询和数据库架构(例如索引)。我们建议您运行基准测试以经验证实这一点。
应用迁移
在应用连接方面,迁移策略取决于在将应用配置为使用 Spanner 时做出的初始选择,例如您是使用 PostgreSQL 驱动程序、Spanner 驱动程序还是 Spanner 客户端库。本部分介绍了每种选项的注意事项。
PostgreSQL 驱动程序
Spanner 使用 PGAdaper 支持常见的 PostgreSQL 客户端;PGAdaper 是一个轻量级代理,可将 PostgreSQL 传输协议转换为 Spanner 的低级 gRPC 查询 API。如果您使用的是其中一种,则更改为其他 PostgreSQL 目标涉及更新连接字符串,使其直接指向新的 PostgreSQL 数据库,而不是 PGAdapter 代理。这种方法可提供出色的性能和强大的兼容性,因此非常适合在可移植性是首要考虑因素时使用。在 Spanner 的 PostgreSQL 页面上运行的大多数查询在其他 PostgreSQL 环境中也能正常运行。不过,反之亦然;PostgreSQL 支持 Spanner 不支持的语法和功能。
Spanner 驱动程序
这些驱动程序是适用于常用语言和应用框架的 Spanner 专用实现。例如,Spanner JDBC (Java) 驱动程序实现的 API 与 PostgreSQL JDBC 驱动程序实现的 API 相同,因此,当使用 Spanner JDBC 驱动程序的应用想要使用 PostgreSQL 运行应用时,可以更新其构建流程以关联等效的内置 PostgreSQL 驱动程序。如果您已经在使用 Spanner,或者正在寻找利用 Mutations API 等 Spanner 功能的高性能解决方案(使用内置 PostgreSQL 驱动程序无法实现),此选项最适合您。如果您需要与内置驱动程序完全兼容并实现值可移植性,则应改为考虑将 PostgreSQL 的内置驱动程序与 PGAdapter 搭配使用,以确保实现一定程度的应用可移植性。
如需了解详情,请参阅 PostgreSQL 驱动程序和 ORM。
Spanner 客户端库
Spanner 还提供各种惯用客户端库,可让您直接访问 Spanner,而无需实现或使用 PostgreSQL 标准化接口。这些客户端可最大限度地访问 Spanner 专用功能,但与 PostgreSQL 驱动程序的 API 不兼容。这些选项可提供最高级别的特征性能,但与前述选项相比,可移植性较差。
后续步骤
- 了解如何在 PostgreSQL 和 GoogleSQL 之间进行选择。
- 按照快速入门创建 PostgreSQL 数据库并与之交互。
- 详细了解 Spanner 的 PostgreSQL 语言支持。
- 了解 PGAdapter。
- 了解 PGAdapter GitHub 代码库。
- 查看 PostgreSQL 页面中的已知问题。