AWS 云中的 Oracle 到 PostgreSQL 迁移可能是一个复杂度极高的多阶段流程:从评估阶段直到移交阶段,涉及到不同的技术和技能。这篇博文是系列博文中的第三篇,讨论了有关数据库迁移时要考虑的组件的高级方面。本系列博文并未探讨应用程序组件和不同场景的复杂性,因为这要取决于具体使用案例。为了更好地理解这些复杂性,请参阅 AWS>
我们在之前的 Migration process and infrastructure considerations 和 Source>
本文是此系列博文的最后一篇文章,概述了如何设置 PostgreSQL 环境以协助完成使用 AWS DMS 和 AWS SCT 从 Oracle 数据库执行的迁移。本文为您提供了对迁移设置有用的 PostgreSQL 数据库参数的配置设置。
在迁移环境中,最好利用策略来实现高可用性、可扩展性、归档、备份、负载均衡和回滚。本文不会涉及到这些策略,也不会讨论数据库迁移的手动工作,同样不包含您可以根据自己的要求或应用程序依赖关系的复杂性作出调整的分步说明。如需详细了解这些信息,请参阅利用 PostgreSQL 从 Oracle top="1349">DMS 与辅助对象迁移
DMS 仅会迁移为保证有效地将数据从源迁移到目标所必需的对象。这其中包括主键,在某些情况下还包括唯一索引。DMS 不会迁移辅助对象,例如外键约束、触发器、二级索引等。
正是由于有这样一项功能,请务必在完全加载期间禁用外键约束和二级索引,因为 DMS 会逐个表执行迁移。如果您保留外键约束,完全加载就会失败。应在完全加载阶段后再启用外键约束和二级索引。您可以在应用缓存的更改之前应用索引,但首先需要对外键应用缓存的更改,之后才能启用外键。
关键 Amazon RDS for PostgreSQL 参数建议
下面给出了关键 Amazon RDS for PostgreSQL 参数的一些建议。仅针对您的数据加载将数据库参数组修改为包含以下设置。您应该测试各种参数设置,找到对您的数据库实例大小最有效的设置。在数据迁移完成后,您还需要将这些参数恢复为生产中所用的值。
在数据加载之前设置一些关键数据库实例参数设置:
Shared_buffers
确定要将 shared_buffers 参数设置为多大的值。起始值为系统内存的 25%,这也是 RDS PostgreSQL 参数中的默认设置(单位为 8KB)。在 Aurora PostgreSQL 中,默认设置是内存的 75%。
要检查此参数,请运行以下命令:
pg=> select setting from pg_settings where name like 'shared_buffers';( in 8K unit) setting
复制代码
要显示此参数的当前值,请运行以下命令:
pg=> show shared_buffers;# show actual value
shared_buffers
[oracle@ip-x-x-x-x ~]$ echo "62500*8"|bc
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 值:
postgres=> show 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
复制代码
参数 | 默认值 | 最大值 | 状态 | 当前 | 单位 | 描述 |
---|---|---|---|---|---|---|
wal_buffers | 2147483647 | 引擎默认值 | 整数 | (8KB) 设置共享内存中用于 WAL 的磁盘页缓冲区数 |
根据 PostgreSQL 文档中所述,默认设置为 -1,此时会选择相当于 shared_buffers 1/32 的大小(大约为 3%)。
在为迁移处理 WAL 参数时,请执行以下操作:
检查点参数
有时,用户会将不良性能归咎于检查点参数未采用标准设置,从而导致存储 I/O 问题。Aurora PostgreSQL 中 IOPS 的处理方式与 PostgreSQL 引擎标准版本不同。Aurora 使用基于日志的存储系统,而不是传统 PostgreSQL 那种基于数据块的系统。
在这种情况下,两种引擎之间的写入操作截然不同。在 Aurora PostgreSQL 中,写入 IOPS 指标报告每秒生成的 Aurora 存储写入记录数。此数字大体与数据库生成的日志记录数相同。这些写入不对应于 8KB 页面写入,也不对应于发送的网络数据包数。此外,此值并非我们出于计费目的用于计量您的 I/O 用量的值。
如果未能根据工作负载正确设置检查点,则系统运行速度可能会极其缓慢。以下情况会导致检查点的出现:
类似地,对于 PostgreSQL 9.4(而非 9.5),将 max_wal_size 设置为 256(默认值是 128)。PostgreSQL 9.6 和 10 的默认 max_wal_size 值是 1GB。
Oracle 也是如此。某些设置会延迟将脏缓冲区高速缓存页写入磁盘上的数据库数据文件的操作。此类延迟会增加时间点恢复时间,并能提高数据迁移性能。如需此项改进,请按如下说明设置:
pg=> select * from pg_settings where name like ‘%checkpoint%’;
如需详细了解 PostgreSQL 中 WAL 参数的运行时配置,请参阅 PostgreSQL 文档中的预写式日志。
SYNC_Commit
不要禁用 FSYNC。而是使用 DISABLE synchronous_commit 加速任何磁盘写入操作。仅为了获得几个百分点的性能提升而禁用 FSYNC 并不值得。禁用 FSYNC 只会将数据库置于可能的损坏风险之中。
Maintenance_work_mem
根据您的应用程序,将 maintenance_work_mem 参数设置为 16MB、512MB、1024MB 或 4096MB,观察能取得多大提升。我们推荐如下方法:
1.首先将其设置为 2GB,随后再向后逐一测试。
2.指定用于维护操作的最大内存量,例如 VACUUM、CREATE INDEX 和 ALTER TABLE ADD FOREIGN KEY。
3.注意不要将默认值设置得过高。在 AUTOVACUUM 运行时,最多可分配相当于此内存量 autovacuum_max_workers 倍的内存。在 RDS PostgreSQL 中,默认 autovacuum_max_workers 值是 3。
以下命令可以显示 maintenance_work_mem 的当前值。
postgres=> show maintenance_work_mem;
maintenance_work_mem
复制代码
另一个相关参数 work_mem 按排序、客户端运行。通常,一个查询中不会有大量排序操作。通常仅会发生一项或两项排序操作。此外,并非每个活动的客户端都会同时执行排序。
对于 work_mem 的一般性指南是考虑在分配 shared_buffers 之后还有多少可用 RAM。需要相同的操作系统缓存大小数字来计算 effective_cache_size。将此值除以 max_connections,随后得出该数字的分数值。该数字的一半就是较为激进的 work_mem 值。我们可能不会让每个客户端同步执行两个活动排序,因为这可能导致服务器内存不足。
以下命令会显示 work_mem 的当前值。
postgres=> select name,setting,unit from pg_settings where name = 'work_mem';
name| setting | unit
work_mem | 4076| kB
postgres=> show work_mem;
复制代码
有关调整 work_mem 和使用 log_temp_files 的详细信息,请参阅 PostgreSQL wiki 上的文章 Tuning Your PostgreSQL Server。您可以执行此类调整来记录排序、哈希和临时文件。您可以使用此日志记录来确定排序是否不能恰好保存到内存中,而是会溢出到磁盘。
另外一个相关解决方案是将 max_connection 设置为 1000,而非 RDS 默认值 (100)。
Vacuum 参数
默认情况下,RDS PostgreSQL 上会启用 autovacuum 参数。您可以通过运行以下命令来验证这一点:
postgres=> show autovacuum;
autovacuum
复制代码
要针对迁移进行设置,首先在加载数据之前执行手动 vacuum 操作,因为这样做可以提高迁移性能。还有一种实用的方法,请参阅 AWS>
在数据加载之前,我们建议您使用以下 vacuum 处理过程:
pg=> vacuum verbose;
pg=> vacuum full verbose;
pg=> select relname,last_vacuum, last_autovacuum, last_analyze, last_autoanalyze from pg_stat_user_tables;
pg=> select relname,last_vacuum, last_autovacuum, last_analyze, last_autoanalyze from pg_stat_all_tables where schemaname = 'public';
check table n_dead_tup > 0
pg=> select relname, n_dead_tup, last_vacuum, last_autovacuum from pg_catalog.pg_stat_all_tables where n_dead_tup > 0 [ and relname = 'pg_authid' ] order by n_dead_tup desc;
relname| n_dead_tup | last_vacuum | last_autovacuum
pg_authid |2 ||
复制代码
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 参数是服务器所用共享内存的主要组成部分。它表示为缓存块分配的大数据块,从数据库读取并写入数据库。
pg=> select name,setting,unit,current_setting(name) from pg_settings where;
name| setting | unit | current_setting
shared_buffers | 65000| 8kB| 500MB
复制代码
如果 shared_buffers 的值设置过低,您可能会在启动时收到如下错误:
FATAL: could not create shared memory segment: Invalid argument
DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600)
postgres=> SHOW rds.extensions;
(since RDS Postgres 9.4, pg_buffercache extension is available, RDS Postgres 9.3 doesn't support)
btree_gin,btree_gist,chkpass,citext,cube,dblink,dict_int,dict_xsyn,earthdistance,fuzzystrmatch,hstore,intagg,intarray,ip4r,isn,ltree,pgcrypto,pgrowlocks,pgstattuple,pg_buffercache,pg_prewarm,pg_stat_statements,pg_trgm,plcoffee,plls,plperl,plpgsql,pltcl,plv8,postgis,postgis_tiger_geocoder,postgis_topology,postgres_fdw,sslinfo,tablefunc,test_parser,tsearch2,unaccent,uuid-ossp
postgres=> select * from pg_available_extensions where name = 'pg_buffercache';
name| default_version | installed_version |comment
pg_buffercache | 1.0| 1.0| examine the shared buffer cache
postgres=> create extension pg_buffercache;
postgres=> select name,setting,unit,current_setting(name) FROM pg_settings where;
name| setting | unit | current_setting
shared_buffers | 25480| 8kB| 203840kB
postgres=> select count(*) from pg_buffercache;
复制代码
您可以通过查看系统 shared_buffers 的大小、确定 pg_buffercache 返回的条目计数是否匹配来确认该实用程序是否按预期工作。
为了帮助理解相关数据库内部的工作原理,您可以使用 pg_buffercache 模块查看 PostgreSQL shared_buffers 数据库缓存的当前内容。 通过此操作可以了解在您执行各种活动时,共享内存中的数据块会如何变化。使用 pg_buffercache 可以显示与您当前连接到的数据库相关的有用信息。
有关 pg_buffercache 的更多信息,请参阅 PostgreSQL 文档中的 pg_buffercache,以及 PostgreSQL wiki 上的文章 Tuning Your PostgreSQL Server。
要使用 pg_buffercache 查看缓存,请运行以下命令。
pg=> create extension pg_buffercache;
CREATE EXTENSION
pg=> SELECT c.relname, pg_size_pretty(count(*) * 8192) as buffered, round(100.0 * count(*) / ( SELECT setting FROM pg_settings WHERE)::integer,1) AS buffers_percent,round(100.0 * count(*) * 8192 / pg_relation_size(c.oid),1) AS percent_of_relation FROM pg_class c INNER JOIN pg_buffercache b ON b.relfilenode = c.relfilenode INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database()) WHERE pg_relation_size(c.oid) > 0 GROUP BY c.oid, c.relname ORDER BY 3 DESC LIMIT 10;
relname|buffered| buffers_percent | percent_of_relation
pg_depend| 520 kB|0.1 |106.6
pg_transform_type_lang_index | 8192 bytes |0.0 |100.0
TEST9| 8192 bytes |0.0 |100.0
awsdms_status| 8192 bytes |0.0 |100.0
t1| 8192 bytes |0.0 |100.0
TEST10| 8192 bytes |0.0 |100.0
pg_namespace_oid_index | 16 kB|0.0 |100.0
pg_constraint_oid_index| 16 kB|0.0 |100.0
pg_extension_oid_index| 16 kB|0.0 |100.0
TEST8_pkey| 16 kB|0.0 |100.0
复制代码
内存中的一个分页实际上包含一个数据块,加上少量额外开销,用于识别数据块究竟是什么,将什么称为缓冲区头。
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 目标的额外连接属性:
afterConnectScript=SET session_replication_role='replica'
复制代码
具有外键的表的加载过程如下:
1.使用 AWS SCT 迁移架构。
2.禁用目标上的外键依赖关系,以防您未使用前面提到的属性使 AWS DMS 绕过所有外键和用户触发器。使用此属性可大大缩短使用完全加载模式时批量加载数据所需的时间。
3.创建目标准备模式为 DO NOTHING 的任务,并确保任务恰好在正在进行的复制开始之前停止。如需了解更多详情,请参阅 DMS 文档中的完全加载任务设置。
4.完全加载完成并且任务停止后,在目标上重新启用外键。
5.启动任务,在源和目标同步时,停止应用程序。访问源,等待几分钟,并确认目标上的开放事务已完成。
6.将应用程序指向目标,整个迁移过程随即开始。
小结
Oracle 到 PostgreSQL 的迁移可能是一个错综复杂的过程,需要多项专业技能完成数据迁移的不同阶段。本系列博文简要讨论了数据库迁移需要考虑的组件。本系列博文并未探讨应用程序组件和不同场景的复杂性,因为这要取决于具体实用案例。要更好地了解所涉及的复杂性,请参阅 AWS 数据库博客文章:AWS>
在迁移过程中,您可以使用 AWS DB Freedom 计划提供的迁移方法。我们提供创新的现代化服务,使组织能够通过在现有软件应用程序中应用最新技术来创建新的 AWS 云解决方案。例如,这可能意味着将旧版 Oracle 应用程序迁移到 AWS 云,以便实时访问多个数据源,或者将旧版应用程序与 Aurora 或 RDS PostgreSQL 数据库配合使用。此外,您可以利用该过程,让实用旧语言的应用程序直接连接到较新的应用程序。为此,您可以使用相同的标准来迁移和集成旧数据,方法是使用 AWS>
我们通过三篇博文分别讨论了数据库迁移环境设置的不同阶段。如果您尚未阅读之前的文章,请阅读 Migration process and infrastructure considerations,这篇文章详细探讨了早期迁移流程和基础设施注意事项。您还可以阅读 Source>
这三篇博文结合在一起,简要概述了 Oracle 到 PostgreSQL 数据库的迁移的组件设置。这些博文涵盖了一些基本步骤,您必须在构建更全面的数据库迁移策略之前测试这些基本步骤。本系列所介绍的内容并非完整的解决方案。有关如何利用 PostgreSQL 兼容性同等组件手动将特定的 Oracle 数据库对象和功能迁移到 Aurora PostgreSQL 的更多信息,请参阅利用 PostgreSQL 从 Oracle top="12318">致谢
如果没有以下各位贡献者的全面审核和持久反馈,本博文也就无法面世: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. 等公司工作,为具有战略意义的大型客户提供高可用性可扩展应用程序设计、异构云应用程序迁移的建议,并协助其调优系统性能。
原文链接: