在Amazon RDS for PostgreSQL中使用蓝绿部署进行维护任务和架构修改并尽量减少停机时间
作者:Anita Singh Nathan Ballance Baji Shaik Sarabjeet Singh日期:2024年5月13日类别:高级300 Amazon Aurora PostgreSQL兼容 RDS for PostgreSQL 技术操作指南
关键要点
本文介绍如何通过蓝绿部署以最小的停机时间执行Amazon RDS for PostgreSQL数据库或Amazon Aurora PostgreSQLCompatible版集群的架构更改和常见维护任务如表和索引重组、VACUUM FULL和物化视图刷新。蓝绿部署使您可以在隔离的测试环境中执行更改,避免影响生产系统。具体用例包括收集统计信息、执行VACUUM FULL、调整表的填充因子、重建索引、添加新列等。文章还讨论了如何设置测试环境并执行维护任务。在这篇文章中,我们将指导您如何通过蓝绿部署实例在Amazon RDS for PostgreSQL数据库或Amazon Aurora PostgreSQLCompatible版集群中,以最小的停机时间执行架构更改和常见维护任务,例如表和索引重组、VACUUM FULL以及物化视图刷新。
解决方案概述
Amazon RDS蓝绿部署使您可以在隔离的测试环境中执行更改。它首先创建一个与当前生产环境蓝相同的拓扑结构的测试环境绿。蓝绿环境通过逻辑复制保持同步。该功能在Amazon RDS for PostgreSQL 版本 1121 及以后的版本可用。
当源数据库蓝和测试数据库绿之间的复制延迟较小或不存在时,蓝绿环境已准备好进行维护活动。您可以在绿环境中执行维护活动,同时应用程序继续使用蓝数据库。推荐在应用程序的低活动时间安排维护活动,以避免高复制延迟,从而提高测试的整体性能。
使用蓝绿部署,您可以以最小的停机时间或不影响源环境的情况下解决以下用例:
用例描述使用 ANALYZE 收集统计信息更新数据库的统计以优化查询性能对目录表执行VACUUM FULL清理无效数据以释放空间调整表的填充因子优化数据的存储和更新效率重建索引优化查询性能并增加数据访问速度添加新列包含或不包含默认值扩展表结构以满足新的业务需求扩展表中列的大小适应数据库的增长刷新物化视图更新视图以确保数据的最新性启用所需扩展确保所需功能正常运作
接下来,我们将深入探讨通过蓝绿部署在最小停机时间内实施数据库更改的场景。请参考蓝绿部署的限制以确保该功能的兼容性。
前提条件
完成以下步骤以设置测试环境:
如果您还没有RDS for PostgreSQL实例或Amazon Aurora PostgreSQL集群,请创建一个。有关说明,请参见创建 PostgreSQL DB 实例或创建 Amazon PostgreSQL DB 集群。创建新的集群参数组,将rdslogicalreplication设置为1,以使WAL转换为逻辑操作,并将maxlogicalreplicationworkers设置为10每个客户数据库和rdsadmin数据库都有一个逻辑复制槽。将集群参数组关联到新创建的RDS实例。更多信息请参考新功能 完全托管的蓝绿部署在Amazon Aurora PostgreSQL和Amazon RDS for PostgreSQL中。创建一个Amazon EC2 实例以安装PostgreSQL客户端以访问RDS for PostgreSQL实例。有关说明,请参见创建EC2资源并启动EC2实例。或者,您可以一键设置RDS数据库和EC2计算实例之间的连接。安装PostgreSQL客户端。在Amazon Linux 2023上,您可以使用以下命令下载psql命令行工具:
bashsudo dnf install postgresql15x8664
在源数据库上创建一个示例数据库用于测试:
bashpostgres=gt create database analyzetestdbCREATE DATABASE
我们使用pgbench,一个简单的PostgreSQL基准测试工具,进行我们的测试用例。运行pgbench命令,使用插入工作负载选项创建四个表并插入测试数据:
bash[ec2user@ip10032224 ] pgbench h useast1rdsamazonawscom p 5432 U benchmarkdba i s 150 analyzetestdbPassworddropping old tablesNOTICE table pgbenchaccounts does not exist skippingNOTICE table pgbenchbranches does not exist skippingNOTICE table pgbenchhistory does not exist skippingNOTICE table pgbenchtellers does not exist skippingcreating tablesgenerating data (clientside)15000000 of 15000000 tuples (100) done (elapsed 6397 s remaining 000 s)vacuumingcreating primary keysdone in 11176 s (drop tables 000 s create tables 002 s clientside generate 6500 s vacuum 949 s primary keys 3725 s)
创建RDS蓝绿环境。请参考新功能 完全托管的蓝绿部署在Amazon Aurora PostgreSQL和Amazon RDS for PostgreSQL中的前提条件和说明以设置蓝绿环境。
当蓝绿环境准备好并且复制延迟最小时,使用psql客户端建立与绿环境的连接。绿环境的默认设置为只读模式。要在绿环境中启用写操作,运行以下命令将defaulttransactionreadonly参数设置为session级别的off。这允许在绿环境中进行写操作。
bashanalyzetestdb=gt SET defaulttransactionreadonly TO offSET
注意:您可以在绿环境中运行VACUUM和ANALYZE操作而无需在session级别启用“写”。
验证数据库会话是否处于读/写模式:
bashanalyzetestdb=gt SHOW defaulttransactionreadonlydefaulttransactionreadonly
安卓加速器免费off(1 row)
请确保持续监控蓝绿环境之间的复制延迟,如下所示:
监控绿环境的复制延迟
在对绿环境进行写操作更改时,监控蓝环境的复制槽是很重要的。如果发生任何逻辑复制问题,复制延迟将继续增长。如果发生这种情况,绿环境将不会消耗WAL,磁盘使用率将会增加,导致数据库挂起。以下查询使用日志序列号lsn检查蓝环境的延迟。
bashanalyzetestdb=gt SELECT slotnameconfirmedflushlsnpgcurrentwallsn()(pgcurrentwallsn() confirmedflushlsn) AS lsndistanceFROM pgreplicationslotsslotname confirmedflushlsn pgcurrentwallsn lsndistancerdsuseast1ojyxjuttnhucw4q7vdg5vbo5fqbgslot16435 F/7C422EC0 F/832607E0 115595552(1 row)
监控绿环境中的RDS for PostgreSQL日志:
bashanalyzetestdb=gt SELECT slotnameconfirmedflushlsnpgcurrentwallsn()(pgcurrentwallsn() confirmedflushlsn) AS lsndistanceFROM pgreplicationslotsslotname confirmedflushlsn pgcurrentwallsn lsndistancerdsuseast1eroldf42vugb3zhgtzqo6x4nnibgslot14717 A/C4000A10 A/C4000A10 0rdsuseast1eroldf42vugb3zhgtzqo6x4nnibgslot16433 A/C4000A10 A/C4000A10 0rdsuseast1eroldf42vugb3zhgtzqo6x4nnibgslot16434 A/BC0008D0 A/C4000A10 134218048rdsuseast1eroldf42vugb3zhgtzqo6x4nnibgslot16435 A/C4000A10 A/C4000A10 0rdsuseast1eroldf42vugb3zhgtzqo6x4nnibgslot16436 A/C4000A10 A/C4000A10 0rdsuseast1eroldf42vugb3zhgtzqo6x4nnibgslot16384 A/C4000A10 A/C4000A10 0(6 rows)
用例
设置好蓝绿部署的测试环境后,接下来我们将深入实际代码示例,展示如何通过Amazon RDS蓝绿部署完成各种维护任务。
使用ANALYZE收集统计信息
Amazon RDS for PostgreSQL数据库的主要版本升级MVU使用pgupgrade模块。然而,该模块不会将先前版本的优化器统计信息转移过来,这可能会影响升级后查询的性能。因此,在主实例的每个数据库上运行ANALYZE命令以重新生成这些统计信息非常重要。
蓝绿部署方法是一种有效的策略,可以减轻这个操作的影响。使用户在切换应用程序工作负载之前,在绿新环境上运行ANALYZE操作。
然而,在为主要版本升级设置蓝绿部署时,绿环境中不会有优化器统计信息可用。可以通过查询pgstats来验证这些表级统计信息:
bashanalyzetestdb=gt SELECT avgwidthndistinctcorrelation from pgstats WHERE tablename=pgbenchaccounts AND attname=aid(0 rows)
如果没有找到统计信息,则需要更新。虽然绿环境继续从蓝环境进行逻辑复制,但ANALYZE操作是不会被逻辑复制的。因此,必须手动在绿环境中运行ANALYZE命令。
以下是对绿环境中表进行分析的命令:
bashanalyzetestdb=gt ANALYZE VERBOSE pgbenchaccountsINFO analyzing publicpgbenchaccountsINFO pgbenchaccounts scanned 30000 of 245902 pages containing 1830000 live rows and 0 dead rows 30000 rows in sample 15000022 estimated total rowsANALYZETime 9043929 ms (0009044)
此命令返回publicpgbenchaccounts表的详细分析,包括活跃行数、死行数、样本中的行数以及估计的总行数。
验证通过ANALYZE命令收集的统计信息以确认它们已正确更新:
bashanalyzetestdb=gt SELECT avgwidthndistinctcorrelation from pgstats WHERE tablename=pgbenchaccounts AND attname=aid[ RECORD 1 ]avgwidth 4ndistinct 1correlation 1
对目录表执行VACUUM FULL
在PostgreSQL中,bloat是指由无效元组占据的多余空间,这些元组实际上是旧数据的残余,不再有效。这种情况可能由于数据库表中频繁更新和删除而发生。
在目录表的bloat方面,主要是由于高频率地创建和删除数据库中的对象所致。要消除这种bloat并减少表的大小,必须执行VACUUM FULL操作,这需要对表进行ACCESS EXCLUSIVE LOCK。
对目录表的锁将不允许对数据库的任何查询。
虽然像pgrepack这样的工具可以通过在较短的时间内锁定表,帮助减少处理用户表时的停机时间,但这不适用于目录表。有关pgrepack的更多信息,请参见使用pgrepack消除Amazon Aurora和RDS for PostgreSQL中的膨胀问题。
然而,在蓝绿部署模型中,您可以有效管理这种停机时间。您可以在绿环境中运行VACUUM FULL操作,而蓝环境将继续处理实时流量,从而对数据库操作造成最小中断。以下是在绿环境中运行的命令:
bashanalyzetestdb=gt SET defaulttransactionreadonly TO offSET
analyzetestdb=gt vacuum full pgclassVACUUM
调整表的填充因子
调整数据库中表的填充因子是一个重要的操作,它对性能有重大影响。填充因子是每个页面PostgreSQL中存储的基本单元中数据填充的百分比,保留其余空间以供数据更新。例如,70的填充因子意味着PostgreSQL会尝试在写出时保留每个叶页面的30空白,以便后续的现有数据更新可以将更新的行放在与原始行相同的页面上。这可以避免高成本的页面拆分。
例如,您的业务可能有一个高更新量的表。起初,该表的填充因子为100,这意味着数据插入时页是完全填充的。随着时间的推移,状态更新时,数据库需要查找新的页面以存储更新的行,导致bloat和空间使用效率低下。
由于数据库花费了大量时间寻找空余空间和移动行,因此这些频繁的更新会导致性能问题。在这类工作负载中,您可以将此表的填充因子更改为留出足够的空间,用于未来的更新。
然而,改变表的填充因子需要较长时间的ACCESS EXCLUSIVE LOCK具体时间取决于表的大小。为了避免停机,可以在绿环境中运行此操作。完成以下步骤:
将会话设置为可读/写,然后执行ALTER:
bashanalyzetestdb=gt SET defaulttransactionreadonly TO offSETanalyzetestdb=gt SHOW defaulttransactionreadonlydefaulttransactionreadonly
off(1 row)
将pgbenchtellers表的填充因子更改为10:
bashanalyzetestdb=gt ALTER TABLE IF EXISTS publicpgbenchtellers SET (FILLFACTOR=10)ALTER TABLEanalyzetestdb=gt d pgbencht