无缝迁移到 Azure Database for PostgreSQL 的最佳做法

适用于: Azure Database for PostgreSQL 灵活服务器

本文介绍了会遇到的常见陷阱,以及确保顺利成功迁移到 Azure Database for PostgreSQL 的最佳做法。

预迁移验证

迁移的第一步是在执行迁移之前运行迁移前验证。 可以使用迁移“设置”页中的“验证”和“验证和迁移”选项。 迁移前验证会针对预定义的规则集进行彻底检查。 目标是确定潜在问题,并提供可操作的见解来修正操作。 继续运行迁移前验证直到状态变为“成功”。 若要了解详细信息,请参阅预迁移验证

目标灵活服务器配置

在对数据进行初始基本复制期间,会在目标服务器上执行多个插入语句,进而生成提前写入日志 (WAL)。 在存档这些 WAL 之前,日志将使用目标服务器上的存储以及数据库所需的存储。

若要计算该数字,请登录到源实例并为所有要迁移的数据库运行以下命令:

SELECT pg_size_pretty( pg_database_size('dbname') );

建议在灵活服务器上分配足够的存储,相当于比前述命令输出中使用的存储多 1.25 倍或 25%。 还可使用存储自动增长

重要

在手动配置和存储自动增长中,无法降低存储大小。 存储配置范围中的每个步骤会将大小增加一倍,因此为谨慎起见,最好事先估算所需的存储。

使用门户创建 Azure Database for PostgreSQL 灵活服务器实例快速入门是很好的起点。 有关每个服务器配置的详细信息,请参阅 Azure Database for PostgreSQL 灵活服务器中的计算和存储选项

迁移时间线

迁移开始后,每个迁移的最大生存期为 7 天(168 小时),并在 7 天后超时。 可在数据验证完成后立即完成迁移和应用程序直接转换,并且完成所有检查,以避免迁移超时。在联机迁移中,初始基本复制完成后,直接转换窗口在超时之前的生存期为三天(72 小时)。在脱机迁移中,应用程序应停止向数据库写入内容,以免发生数据丢失。 同样,对于联机迁移,请在整个迁移过程中保持低流量。

大多数非生产服务器(开发、UAT、测试和暂存)是使用脱机迁移方法迁移的。 由于这些服务器的数据少于生产服务器,因此迁移速度很快。 要迁移生产服务器,需要知道完成迁移所需的时间,以提前做好规划。

完成迁移所需的时间取决于多个因素。 它包括数据库数、大小、每个数据库中的表数、索引数以及数据的跨表分布。 它还取决于目标服务器的 SKU,以及源服务器和目标服务器上可用的 IOPS。 由于有许多的因素会影响迁移时间,因此很难估算完成迁移所需的总时间。 最佳方法是使用工作负载执行测试迁移。

要计算执行生产服务器迁移导致的总停机时间,需要考虑以下阶段:

  • PITR 迁移:准确估算迁移生产数据库服务器所需时间的最佳方法是对生产服务器进行时间点还原 (PITR),然后在此新还原的服务器上运行脱机迁移

  • 缓冲区迁移:完成前一步骤后,可将实际的生产迁移安排在应用程序流量较低的时间段。 可将此迁移安排在同一天或大概一周后。 此时,源服务器的大小可能已经增大。 根据此增量更新生产服务器的估算迁移时间。 如果增量很大,考虑使用 PITR 服务器再执行一次测试。 但是对于大多数服务器而言,大小增量应该不是很大。

  • 数据验证:生产服务器的迁移完成后,需要验证灵活服务器中的数据是否是源实例的精确副本。 可使用开源或第三方工具或可手动进行验证。 在实际迁移之前准备好要执行的验证步骤。 验证可能包括:

    • 迁移中涉及的所有表的行计数匹配情况。

    • 所有数据库对象(表、序列、扩展、过程和索引)的匹配计数。

    • 比较关键的应用程序相关列的最大或最小 ID。

      注意

      数据库的相对大小不是验证的正确指标。 源实例可能有膨胀或死元组,从而可能会增大源实例的大小。 源实例和目标服务器之间存在大小差异是正常的。 前三个验证步骤中有问题表明迁移出现问题。

  • 迁移服务器设置:必须将任何自定义服务器参数、防火墙规则(如适用)、标记和警报从源实例手动复制到目标服务器

  • 更改连接字符串:成功验证后,应用程序应会更改其连接字符串以指向灵活服务器。 与应用程序团队协调此活动,以更改所有指向源实例的连接字符串引用。 在灵活服务器中,连接字符串中的用户参数采用 user=username 格式

例如:psql -h myflexserver.postgres.database.chinacloudapi.cn -u user1 -d db1

虽然迁移的运行通常不会出现任何问题,但如果需要更多时间进行调试,或需要重启迁移,则最好针对意外情况做好规划。

确定迁移速度基准

下表显示了使用迁移服务对各种大小的数据库执行迁移所需的时间。 迁移是通过使用具有 SKU Standard_D4ds_v4(4 核心,16 GB 内存,128 GB 磁盘空间和 500 IOPS)的灵活服务器执行的。

数据库大小 大约所需时间 (HH:MM)
1 GB 00:01
5 GB 00:03
10 GB 00:08
50 GB 00:35
100 GB 01:00
500 GB 04:00
1,000 GB 07:00

前面的数字提供了完成迁移所需的大致时间。 强烈建议使用工作负载运行测试迁移,以获取用于服务器迁移的精确值。

重要

为更快地执行迁移,请为灵活服务器选择更高的 SKU。 Azure Database for PostgreSQL 灵活服务器支持近零停机时间的计算和 IOPS 缩放,以便可在最短停机时间的情况下更新 SKU。 始终可以更改 SKU 来满足迁移后的应用程序需求。

提高迁移速度:表的并行迁移

由于 PostgreSQL 迁移服务会耗尽灵活服务器上的容器,因此建议对目标使用功能强大的 SKU。 SKU 越强大,可以并行迁移的表越多。 迁移后,可以将 SKU 缩减回首选配置。 本部分包含在表之间的数据分布需要更均衡或更强大的 SKU 对迁移速度没有显著影响时提高迁移速度的步骤。

如果源上的数据分布高度倾斜,大部分数据都存在于一个表中,则分配的迁移计算需要得到充分利用,这会造成瓶颈。 因此,将大型表拆分为较小的区块,然后将其并行迁移。 此功能适用于具有 1,000,000(1 百万)个以上元组的表。 如果满足以下条件之一,则有可能将表拆分为较小的区块:

  • 表必须有一个列为 intsignificant int 类型的简单(而非复合)主键或唯一索引。

    注意

    对于第一种或第二种方法,必须仔细评估向源架构添加唯一索引列的影响。 只有在确认添加唯一索引列不会影响应用程序后,你才能继续进行更改。

  • 如果表没有 intsignificant int 类型的简单主键或唯一索引,但具有满足数据类型条件的列,则可使用以下命令将该列转换为唯一索引。 此命令不需要对表进行锁定。

        create unique index concurrently partkey_idx on <table name> (column name);
    
  • 如果表没有简单的 simple int/big int 主键或唯一索引,也没有满足数据类型条件的任何列,则可以使用 ALTER 添加此类列,并在迁移后将其删除。 运行 ALTER 命令需要对表进行锁定。

        alter table <table name> add column <column name> big serial unique;
    

如果满足前述条件,则将以多个分区并行的方式迁移表,这应该会提高迁移速度。

工作原理

  • 迁移服务会查找必须拆分并并行迁移的表的主键/唯一索引的最大和最小整数值。
  • 如果最小值和最大值之差大于 1,000,000(1 百万),表会拆分为多个部分,并且每个部分将并行迁移。

总之,如果存在以下情况,PostgreSQL 迁移服务将通过并行线程迁移表,从而缩短迁移时间:

  • 表有一个列为 int 或 significant int 类型的简单主键或唯一索引。
  • 表至少包含 1,000,000(1 百万)行,因此主键的最小值和最大值之间的差异会超过 1,000,000(1 百万)。
  • 使用的 SKU 具有空闲核心,可用于以并行方式迁移表。

清空 PostgreSQL 数据库中的膨胀

由于数据会随时间推移而添加、更新和删除,PostgreSQL 可能会累积死行和浪费的存储空间。 这种膨胀可能导致存储需求增加,并导致查询性能降低。 清空是一项重要的维护任务,可帮助回收此浪费的空间,并确保数据库高效运行。 清空可解决死行和表膨胀等问题,以确保高效使用存储。 它还有助于确保迁移更快,因为迁移时间是数据库大小的函数。

PostgreSQL 提供了 VACUUM 命令,可用于回收死行占用的存储。 此外,ANALYZE 选项可收集统计信息,以进一步优化查询规划。 对于存在大量写入活动的表,VACUUM 过程可以通过使用 VACUUM FULL 变得更加主动,但需要更多时间来运行。

  • 标准清空

    VACUUM your_table;
    
  • 清空及分析

    VACUUM ANALYZE your_table;
    
  • 适用于大量写入表的主动清空

    VACUUM FULL your_table;
    

在此示例中,请将 your_table 替换为实际的表名称。 不带 FULLVACUUM 命令可高效回收空间,而 VACUUM ANALYZE 则会优化查询规划。 由于 VACUUM FULL 选项对性能影响较大,因此应谨慎使用此选项。

一些数据库可存储图像或文档等可能随时间推移促进数据库膨胀的大型对象。 VACUUMLO 命令专为 PostgreSQL 中的大型对象而设计。

  • 清空大型对象

    VACUUMLO;
    

定期合并这些清空策略可确保 PostgreSQL 数据库得到良好维护。

特殊注意事项

某些特殊条件通常是指你在继续学习教程或模块之前需要注意的特殊环境、配置或先决条件。 这些条件可能包括特定软件版本、硬件要求或成功完成学习内容所需的其他工具。

联机迁移

联机迁移使用pgcopydb follow,并应用一些逻辑解码限制。 我们还建议你在进行联机迁移的数据库的所有表中具有主键。 如果缺少主键,则该缺陷会导致仅在迁移期间反映 insert 操作,而不包括更新或删除。 在继续联机迁移之前,请将临时主键添加到相关表。

注意

在没有主键的情况下联机迁移表时,只会在目标上重播 insert 操作。 如果在源上更新或删除的记录不反映目标,则这可能会在数据库中引入不一致。

另一种方法是使用 ALTER TABLE 命令,其中操作为带有 FULL 选项的 REPLICA IDENTIYFULL 选项记录行中所有列的旧值,以便即使没有主键,所有 CRUD 操作也会在联机迁移期间反映在目标上。 如果这些选项都不起作用,请执行脱机迁移作为替代方法。

具有 postgres_fdw 扩展的数据库

postgres_fdw 模块提供了外来数据包装器 postgres_fdw,可用于访问存储在外部 PostgreSQL 服务器中的数据。 如果数据库使用此扩展,则必须执行以下步骤以确保成功迁移。

  1. 暂时移除(取消链接)源实例上的外来数据包装器。
  2. 使用迁移服务执行其余部分的数据迁移。
  3. 迁移完成后,将外来数据包装器角色、用户和链接还原到目标服务器。

具有 postGIS 扩展的数据库

postGIS 扩展在不同版本之间存在中断性变更/兼容性问题。 如果迁移到灵活服务器,则应针对较新的 postGIS 版本检查应用程序,以确保应用程序不会受到影响,或者必须对应用程序进行必要的更改。 postGIS 新闻发行说明是了解各个版本的中断性变更的良好起点。

数据库连接清理

有时,启动迁移时可能会遇到此错误:

CL003:Target database cleanup failed in the pre-migration step. Reason: Unable to kill active connections on the target database created by other users. Please add the pg_signal_backend role to the migration user using the command 'GRANT pg_signal_backend to <migrationuser>' and try a new migration.

在此场景中,可向 migration user 授予关闭与数据库所有活动连接的权限,也可以在重试迁移之前手动关闭连接。