亚马逊AWS官方博客
云中的 Oracle 到 PostgreSQL 迁移:为 AWS DMS 设置 PostgreSQL 目标数据库环境
AWS 云中的 Oracle 到 PostgreSQL 迁移可能是一个复杂度极高的多阶段流程:从评估阶段直到移交阶段,涉及到不同的技术和技能。这篇博文是系列博文中的第三篇,讨论了有关数据库迁移时要考虑的组件的高级方面。本系列博文并未探讨应用程序组件和不同场景的复杂性,因为这要取决于具体使用案例。为了更好地理解这些复杂性,请参阅 AWS Database 博文 Database Migration—What Do You Need to Know Before You Start?
我们在之前的 Migration process and infrastructure considerations 和 Source database considerations for the Oracle and AWS DMS CDC environment 这两篇博文中探讨了 Oracle 数据库的配置设置。本文讨论的内容包括 AWS Data Migration Service (AWS DMS) 和 AWS Schema Conversion Tool (AWS SCT) 的设置。完成这些设置后,并在开始数据迁移之前,我们必须使用所有相关架构和参数,让目标 PostgreSQL 数据库启动并正常运行。
本文是此系列博文的最后一篇文章,概述了如何设置 PostgreSQL 环境以协助完成使用 AWS DMS 和 AWS SCT 从 Oracle 数据库执行的迁移。本文为您提供了对迁移设置有用的 PostgreSQL 数据库参数的配置设置。
在迁移环境中,最好利用策略来实现高可用性、可扩展性、归档、备份、负载均衡和回滚。本文不会涉及到这些策略,也不会讨论数据库迁移的手动工作,同样不包含您可以根据自己的要求或应用程序依赖关系的复杂性作出调整的分步说明。如需详细了解这些信息,请参阅利用 PostgreSQL 从 Oracle Database 11g/12c 迁移到 Amazon Aurora 的迁移操作手册。该操作手册描述了如何手动将特定 Oracle 数据库对象和功能迁移到兼容 PostgreSQL 的 Amazon Aurora 的对应组件。
DMS 与辅助对象迁移
DMS 仅会迁移为保证有效地将数据从源迁移到目标所必需的对象。这其中包括主键,在某些情况下还包括唯一索引。DMS 不会迁移辅助对象,例如外键约束、触发器、二级索引等。
正是由于有这样一项功能,请务必在完全加载期间禁用外键约束和二级索引,因为 DMS 会逐个表执行迁移。如果您保留外键约束,完全加载就会失败。应在完全加载阶段后再启用外键约束和二级索引。您可以在应用缓存的更改之前应用索引,但首先需要对外键应用缓存的更改,之后才能启用外键。
关键 Amazon RDS for PostgreSQL 参数建议
下面给出了关键 Amazon RDS for PostgreSQL 参数的一些建议。仅针对您的数据加载将数据库参数组修改为包含以下设置。您应该测试各种参数设置,找到对您的数据库实例大小最有效的设置。在数据迁移完成后,您还需要将这些参数恢复为生产中所用的值。
在数据加载之前设置一些关键数据库实例参数设置:
- 禁用数据库实例备份(将
backup_retention
设置为 0)。此操作会在加载期间禁用自动备份。 - 禁用多可用区。我们建议执行这项操作,因为与单可用区部署相比,多可用区部署可能会产生更高的写入和提交延迟,原因在于要将数据同步复制到备用区。
- 将
wal_buffer
、Maintenance_work_mem
、checkpoint_segments
和checkpoint_timeout
设为较大的值(相关示例参见下文)。 - 禁用
synchronous_commit
(相关示例参见下文)。 - 不要禁用
AUTOVACUUM
。启用AUTOVACUUM
时,它会检查包含大量插入、更新或删除的元组的表。此功能预计会一直运行,直到在加载完成并停止大型数据加载的事务 ID 回卷。 - 不要修改
vacuum_freeze_min_age
。减少此设置会增加在必须再次清空表之前可能经过的事务数,并且可能造成事务 ID 回卷问题。 - 初始加载后执行 Vacuum 分析,以保证统计信息处于最新状态:
- 拥有合理准确的统计数据非常重要;否则计划选择不当可能会导致数据库性能下降。
- 对具有 LOBS 的表执行
VACUUM FULL
。DMS 通过更新行来加载数据,这会在 PostgreSQL 上产生膨胀。VACUUM FULL
可能会回收比标准形式的VACUUM
更多的磁盘空间,但运行速度比后者慢得多,因为标准形式可以与生产数据库操作并行运行。
- 将日志记录默认值调整为更详细的值。
Shared_buffers
确定要将 shared_buffers
参数设置为多大的值。起始值为系统内存的 25%,这也是 RDS PostgreSQL 参数中的默认设置(单位为 8KB)。在 Aurora PostgreSQL 中,默认设置是内存的 75%。
要检查此参数,请运行以下命令:
要显示此参数的当前值,请运行以下命令:
Max_Connections
估计最大连接数时要尽量多估计,因为这属于一项硬性限制。 达到限制后,客户端会被拒绝连接,系统将会挂起。
在 RDS PostgreSQL 9 和 10 中,此值为:LEAST({DBInstanceClassMemory/9531392},5000)
例如,假设 T2.micro 数据库实例类使用 RDS PostgreSQL 9 和 10。T2.micro 实例类有 1GB 的内存,等于 1024 * 1024 * 1024 字节/9531392,也就是 112.65。因为不可能存在 0.65 个连接,所以将最大连接数舍入为 112 或 113。您可以使用如下命令检查实例的 max_connections
值:
在 Aurora 中,默认参数组包含基于引擎、计算类和实例的已分配存储的数据库引擎默认值和 Amazon RDS 系统默认值。您不能修改默认数据库参数组的参数设置。要将参数设置更改为默认值以外的值,您必须按照 RDS 文档中的说明创建自己的数据库参数组。为此,您要在自定义参数组中修改 max_connections
参数。完成此操作后,您需要修改数据库实例以使用新参数组。
更改与某个数据库实例关联的数据库参数组时,必须在数据库实例使用新数据库参数组之前,手动重启实例。
预写式日志 (WAL)
您可以使用 WAL 文件记录有关数据库更改的信息。这些更改会存储在称为 WAL 段的段中。 WAL 段表示永久存储,而 WAL 缓冲区则是瞬时存储。WAL 段有助于确保内容(WAL 记录)可用于恢复和复制。wal_buffers
参数设置共享内存中用于 WAL 的磁盘页缓冲区数。此共享内存用于尚未写入磁盘的 WAL 数据。其值以 8KB 为单位。设置此参数有助于加快您的 WAL 生成速度。
可以使用在 WAL 段中测量的参数 max_wal_size
来控制 WAL 段。您无法在 Aurora PostgreSQL 中调整此参数,仅可在 RDS PostgreSQL 中调整。但 max_wal_size
也会影响检查点设置。之所以产生这种效果,是因为每隔 checkpoint_timeout
秒会启动一个检查点,或者在即将超出 max_wal_size
时启动一个检查点(以先到者为准)。对于 WAL 段,此参数确定在备用数据库需要利用它们进行恢复的情况下,磁盘上保留多少个 WAL 文件。每个文件的大小都是 16MB。RDS 的默认值是 32。但是,您可以根据自己的特定需求进行更改。例如,假设每个文件的大小是 16MB,将 max_wal_size
设置为 32 就意味着在磁盘上为 WAL 记录保留 512MB 的空间。
在 PostgreSQL 10 中,此参数的值已从文件个数更改为兆字节数。此更改意味着,在 PostgreSQL 10 中将 max_wal_size
设置为 32,就等同于将其设置为 32MB。
运行命令 pg=> show wal_buffers;
会得到类似于下面这样的输出结果:
参数 | 默认值 | 最大值 | 状态 | 当前 | 单位 | 描述 |
wal_buffers | -1 | 2147483647 | True | 引擎默认值 | 整数 | (8KB) 设置共享内存中用于 WAL 的磁盘页缓冲区数 |
根据 PostgreSQL 文档中所述,默认设置为 -1,此时会选择相当于 shared_buffers 1/32 的大小(大约为 3%)。
在为迁移处理 WAL 参数时,请执行以下操作:
- 将
work_mem
更改为 1M 默认值,除非您的数据库属于数据仓库。此参数根据排序和每个客户端所需进行设置,且不会耗尽内存。 - 基于内存的可调整参数(主要是
shared_buffers
和work_mem
)需要谨慎调整并保持一致,以确保系统不会彻底耗尽内存。对于 RAM 的每 GB 空间,将maintenance_work_mem
设置为大约 50MB。 - 将
wal_buffers
增大到 16MB;为此,将其设置为 2048,因为此参数的单位是 8KB。
检查点参数
有时,用户会将不良性能归咎于检查点参数未采用标准设置,从而导致存储 I/O 问题。Aurora PostgreSQL 中 IOPS 的处理方式与 PostgreSQL 引擎标准版本不同。Aurora 使用基于日志的存储系统,而不是传统 PostgreSQL 那种基于数据块的系统。
在这种情况下,两种引擎之间的写入操作截然不同。在 Aurora PostgreSQL 中,写入 IOPS 指标报告每秒生成的 Aurora 存储写入记录数。此数字大体与数据库生成的日志记录数相同。这些写入不对应于 8KB 页面写入,也不对应于发送的网络数据包数。此外,此值并非我们出于计费目的用于计量您的 I/O 用量的值。
如果未能根据工作负载正确设置检查点,则系统运行速度可能会极其缓慢。以下情况会导致检查点的出现:
- 已写入相当于
checkpoint_segments
的 WAL 文件。 - 自上个检查点之后已经过了
checkpoint_timeout
秒。 - 您可以使用 SQL 命令
CHECKPOINT
强制手动添加检查点。
某些设置有助于避免数据库检查点。在 RDS PostgreSQL 中,我们建议您将 checkpoint_segments
从 16 (256MB)
至少增大到 256 (256*16=4096=4GB)
,甚至可以增大到 1024。我们还建议您将 checkpoint_timeout 增加到 1800(默认值为 300)。您只能在 RDS PostgreSQL 中调整这些参数,而不能在 Aurora PostgreSQL 中调整。
类似地,对于 PostgreSQL 9.4(而非 9.5),将 max_wal_size
设置为 256(默认值是 128)。PostgreSQL 9.6 和 10 的默认 max_wal_size
值是 1GB。
Oracle 也是如此。某些设置会延迟将脏缓冲区高速缓存页写入磁盘上的数据库数据文件的操作。此类延迟会增加时间点恢复时间,并能提高数据迁移性能。如需此项改进,请按如下说明设置:
checkpoint_segments
– 自动 WAL 检查点之间的最大日志文件段数(每个段通常为 16MB)。此值默认为 16,即16*16MB=256MB
。如果服务器繁忙或正在进行大规模数据迁移,则可以轻松达到此最大值。checkpoint_timeout
– 自动 WAL 检查点之间的最大时间(单位为秒)。默认情况下,此值为 300 秒,即 5 分钟。在 RDS PostgreSQL 中,我们建议您将其更改为 1800(30 分钟)。您不能在 Aurora PostgreSQL 中修改此值。在 Aurora PostgreSQL 中,checkpoint_timeout
参数值设置为 60 秒。此设置基于开发团队的性能测试、RDS 恢复服务的依赖关系以及其他因素。
执行以下命令,检查上述当前检查点参数设置:
如需详细了解 PostgreSQL 中 WAL 参数的运行时配置,请参阅 PostgreSQL 文档中的预写式日志。
SYNC_Commit
不要禁用 FSYNC
。而是使用 DISABLE synchronous_commit
加速任何磁盘写入操作。仅为了获得几个百分点的性能提升而禁用 FSYNC
并不值得。禁用 FSYNC
只会将数据库置于可能的损坏风险之中。
Maintenance_work_mem
根据您的应用程序,将 maintenance_work_mem
参数设置为 16MB、512MB、1024MB 或 4096MB,观察能取得多大提升。我们推荐如下方法:
- 首先将其设置为 2GB,随后再向后逐一测试。
- 指定用于维护操作的最大内存量,例如
VACUUM
、CREATE INDEX
和ALTER TABLE ADD FOREIGN KEY
。 - 注意不要将默认值设置得过高。在
AUTOVACUUM
运行时,最多可分配相当于此内存量autovacuum_max_workers
倍的内存。在 RDS PostgreSQL 中,默认autovacuum_max_workers
值是 3。
以下命令可以显示 maintenance_work_mem
的当前值。
另一个相关参数 work_mem
按排序、客户端运行。通常,一个查询中不会有大量排序操作。通常仅会发生一项或两项排序操作。此外,并非每个活动的客户端都会同时执行排序。
对于 work_mem
的一般性指南是考虑在分配 shared_buffers
之后还有多少可用 RAM。需要相同的操作系统缓存大小数字来计算 effective_cache_size
。将此值除以 max_connections
,随后得出该数字的分数值。该数字的一半就是较为激进的 work_mem
值。我们可能不会让每个客户端同步执行两个活动排序,因为这可能导致服务器内存不足。
以下命令会显示 work_mem
的当前值。
有关调整 work_mem
和使用 log_temp_files
的详细信息,请参阅 PostgreSQL wiki 上的文章 Tuning Your PostgreSQL Server。您可以执行此类调整来记录排序、哈希和临时文件。您可以使用此日志记录来确定排序是否不能恰好保存到内存中,而是会溢出到磁盘。
另外一个相关解决方案是将 max_connection
设置为 1000,而非 RDS 默认值 (100)。
Vacuum 参数
默认情况下,RDS PostgreSQL 上会启用 autovacuum
参数。您可以通过运行以下命令来验证这一点:
要针对迁移进行设置,首先在加载数据之前执行手动 vacuum 操作,因为这样做可以提高迁移性能。还有一种实用的方法,请参阅 AWS Database 博文 Implement an Early Warning System for Transaction ID Wraparound in Amazon RDS for PostgreSQL。
在数据加载之前,我们建议您使用以下 vacuum 处理过程:
Shared_buffers 和 pg_buffercache
PostgreSQL 既有自己的专用内存(由 shared_buffers
参数指明),也会使用文件系统缓存。最初,您可以从 RDS 的 shared_buffers
和 effective_cache_size
默认设置开始。根据 shared_buffers
及操作系统缓存调整 effective_cache_size
。在 RDS PostgreSQL 9 中,默认值是 {DBInstanceClassMemory/16384
},也就是实例内存的一半,因为其单位是 8KB。
将操作系统缓存大小除以 max_connections,然后再除以 2。这能大致确定用于各客户端排序的 work_mem 的最大合理设置。默认值为 1M,您可以尝试 4M、8M,直到 1G,以了解针对数据仓库系统的执行情况。work_mem 的单位是 KB。
如果您的系统 RAM 为 1GB 或更大,那么 shared_buffers
合理的起始值是系统内存的四分之一。如果您的 RAM 较少,则必须更仔细地考虑操作系统占用的 RAM 量。在这种情况下,通常可以设为大致接近于系统内存 15% 的值。对于某些工作负载,更大的 shared_buffers 设置较为有效。但是,考虑到 PostgreSQL 还依赖于操作系统的缓存方式,您不太可能需要用到超过 RAM 40% 的内存量。
RDS PostgreSQL 对于 shared_buffers
的默认设置是 {DBInstanceClassMemory/32768} *8K = 8192/32768=1/4
。
以下表示服务器使用的共享内存缓冲区数。
shared_buffers -> {DBInstanceClassMemory/32768} -> 16-1073741823 -> true - > system -> static -> integer -> (8kB)
shared_buffers
参数是服务器所用共享内存的主要组成部分。它表示为缓存块分配的大数据块,从数据库读取并写入数据库。
如果 shared_buffers
的值设置过低,您可能会在启动时收到如下错误:
您可以通过查看系统 shared_buffers
的大小、确定 pg_buffercache
返回的条目计数是否匹配来确认该实用程序是否按预期工作。
为了帮助理解相关数据库内部的工作原理,您可以使用 pg_buffercache
模块查看 PostgreSQL shared_buffers 数据库缓存的当前内容。 通过此操作可以了解在您执行各种活动时,共享内存中的数据块会如何变化。使用 pg_buffercache
可以显示与您当前连接到的数据库相关的有用信息。
有关 pg_buffercache
的更多信息,请参阅 PostgreSQL 文档中的 pg_buffercache,以及 PostgreSQL wiki 上的文章 Tuning Your PostgreSQL Server。
要使用 pg_buffercache
查看缓存,请运行以下命令。
内存中的一个分页实际上包含一个数据块,加上少量额外开销,用于识别数据块究竟是什么,将什么称为缓冲区头。
effective_cache_size
effective_cache_size
参数是操作系统和 PostgreSQL 缓冲区高速缓存中可用内存量的指南,而非实际分配内存。此值仅供 PostgreSQL 查询计划程序使用,以确定它所考虑的计划是否适合 RAM。如果此参数设置得太低,则索引可能无法按照您期望的方式用于执行查询。此处不考虑 shared_buffers
的设置。仅考虑 effective_cache_size
值,因此也应该包含专用于数据库的内存。
将 effective_cache_size
设置为总内存量的一半是一种常用的保守型设置。
外键
如果在某些表上启用了外键,则首次加载会失败。在完全加载步骤中,您必须禁用外键依赖关系。或者,您可以使用下面讨论的其他属性来避免加载失败。否则,就会出现外键冲突。您可以为完全加载禁用外键,然后停止迁移任务,然后再重新启用外键。如需了解详情,请参阅 DMS 文档中的完全加载任务设置。
此外,您可能希望检查目标终端节点上是否具有额外的连接属性,以在完全加载期间禁用外键。如需了解详情,请参阅
DMS 文档中的将 PostgreSQL 作为 AWS DMS 目标时的额外连接属性。检查可用于将 PostgreSQL 配置为 AWS DMS 目标的额外连接属性:
具有外键的表的加载过程如下:
- 使用 AWS SCT 迁移架构。
- 禁用目标上的外键依赖关系,以防您未使用前面提到的属性使 AWS DMS 绕过所有外键和用户触发器。使用此属性可大大缩短使用完全加载模式时批量加载数据所需的时间。
- 创建目标准备模式为 DO NOTHING 的任务,并确保任务恰好在正在进行的复制开始之前停止。如需了解更多详情,请参阅 DMS 文档中的完全加载任务设置。
- 完全加载完成并且任务停止后,在目标上重新启用外键。
- 启动任务,在源和目标同步时,停止应用程序。访问源,等待几分钟,并确认目标上的开放事务已完成。
- 将应用程序指向目标,整个迁移过程随即开始。
小结
Oracle 到 PostgreSQL 的迁移可能是一个错综复杂的过程,需要多项专业技能完成数据迁移的不同阶段。本系列博文简要讨论了数据库迁移需要考虑的组件。本系列博文并未探讨应用程序组件和不同场景的复杂性,因为这要取决于具体实用案例。要更好地了解所涉及的复杂性,请参阅AWS 数据库博客文章:AWS Database Blog post Database Migration—What Do You Need to Know Before You Start?
在迁移过程中,您可以使用 AWS DB Freedom 计划提供的迁移方法。我们提供创新的现代化服务,使组织能够通过在现有软件应用程序中应用最新技术来创建新的 AWS 云解决方案。例如,这可能意味着将旧版 Oracle 应用程序迁移到 AWS 云,以便实时访问多个数据源,或者将旧版应用程序与 Aurora 或 RDS PostgreSQL 数据库配合使用。此外,您可以利用该过程,让实用旧语言的应用程序直接连接到较新的应用程序。为此,您可以使用相同的标准来迁移和集成旧数据,方法是使用 AWS Database Migration Service (AWS DMS),以及与 AWS 咨询服务合作伙伴 (AWS CSP) 和 AWS ISV 合作伙伴合作。通过这种方法,您就可以最大限度发挥现有应用程序的潜力。组织可以提高投资回报率,提高生产力和效率,并获得管理运营风险的能力。
我们通过三篇博文分别讨论了数据库迁移环境设置的不同阶段。如果您尚未阅读之前的文章,请阅读 Migration process and infrastructure considerations,这篇文章详细探讨了早期迁移流程和基础设施注意事项。您还可以阅读 Source database considerations for the Oracle and AWS DMS CDC environment,该文章可帮助您为使用变更数据捕获 (CDC) 的一次性迁移或单向连续复制设置源数据库环境。
这三篇博文结合在一起,简要概述了 Oracle 到 PostgreSQL 数据库的迁移的组件设置。这些博文涵盖了一些基本步骤,您必须在构建更全面的数据库迁移策略之前测试这些基本步骤。本系列所介绍的内容并非完整的解决方案。有关如何利用 PostgreSQL 兼容性同等组件手动将特定的 Oracle 数据库对象和功能迁移到 Aurora PostgreSQL 的更多信息,请参阅利用 PostgreSQL 从 Oracle Database 11g/12c 迁移到 Amazon Aurora 的迁移操作手册。
致谢
如果没有以下各位贡献者的全面审核和持久反馈,本博文也就无法面世:Melanie Henry、Wendy Neu、Eran Schitzer、Mitchell Gurspan、Ilia Gilderman、Kevin Jernigan、Jim Mlodgenski、Chris Brownlee、Ed Murray 和 Michael Russo。
关于作者
Mahesh Pakala 自 2014 年 4 月起一直在 Amazon 工作。在加入亚马逊之前,他曾在 Ingres、Oracle Corporation 和 Dell Inc. 等公司工作,为具有战略意义的大型客户提供高可用性可扩展应用程序设计、异构云应用程序迁移的建议,并协助其调优系统性能。