为什么 RDS PostgreSQL 总是在重启时恢复?

Chr*_*wis 9 postgresql aws postgresql-9.6 amazon-rds

我正在运行 PostgreSQL 9.6.3 的 RDS 实例:select version();返回PostgreSQL 9.6.3 on x86_64-pc-linux-gnu [...]

我发现在从 RDS 控制台发出停止命令并启动后,数据库总是报告数据库系统没有正确关闭,需要恢复。此行为已由至少一位其他 RDS PostgreSQL 用户 ( https://forums.aws.amazon.com/message.jspa?messageID=809401#809401 )独立验证。

查询

select name, setting
from pg_settings
where name in ('fsync', 'wal_sync_method', 'synchronous_commit');
Run Code Online (Sandbox Code Playgroud)

报告说fsync = onwal_sync_method = fdatasync(适用于 Linux 系统),和synchronous_commit = on

发出停止命令后,我在日志中看到以下内容:

2017-10-12 16:37:36 UTC::@:[3464]:LOG: received fast shutdown request
2017-10-12 16:37:36 UTC::@:[3464]:LOG: aborting any active transactions
2017-10-12 16:37:36 UTC::@:[3515]:LOG: autovacuum launcher shutting down
2017-10-12 16:37:36 UTC::@:[3512]:LOG: shutting down
2017-10-12 16:37:36 UTC::@:[3512]:LOG: checkpoint starting: shutdown immediate
2017-10-12 16:37:36 UTC::@:[3512]:LOG: checkpoint complete: wrote 1 buffers (0.0%); 0 transaction log file(s) added, 0 removed, 1 recycled; write=0.007 s, sync=0.002 s, total=0.145 s; sync files=1, longest=0.002 s, average=0.002 s; distance=16384 kB, estimate=16402 kB
2017-10-12 16:37:36 UTC::@:[3464]:LOG:  database system is shut down
Run Code Online (Sandbox Code Playgroud)

发出开始后的以下内容:

2017-10-12 17:05:33 UTC::@:[3293]:LOG: database system was interrupted; last known up at 2017-10-12 16:37:50 UTC
2017-10-12 17:05:33 UTC::@:[3293]:LOG: database system was not properly shut down; automatic recovery in progress
2017-10-12 17:05:33 UTC::@:[3293]:LOG: redo starts at 165/1160
2017-10-12 17:05:33 UTC::@:[3293]:LOG: unexpected pageaddr 164/D2000000 in log segment 000000010000016500000003, offset 0
2017-10-12 17:05:33 UTC::@:[3293]:LOG: redo done at 165/20000A0
2017-10-12 17:05:33 UTC::@:[3293]:LOG: last completed transaction was at log time 2017-10-12 16:50:53.823582+00
2017-10-12 17:05:33 UTC::@:[3293]:LOG: checkpoint starting: end-of-recovery immediate
2017-10-12 17:05:33 UTC::@:[3293]:LOG: checkpoint complete: wrote 2 buffers (0.0%); 0 transaction log file(s) added, 0 removed, 3 recycled; write=0.029 s, sync=0.002 s, total=0.046 s; sync files=2, longest=0.002 s, average=0.001 s; distance=49147 kB, estimate=49147 kB
2017-10-12 17:05:33 UTC::@:[3293]:LOG: MultiXact member wraparound protections are now enabled
Run Code Online (Sandbox Code Playgroud)

鉴于我对 PostgreSQL 的(快速)关闭和启动序列的理解,上面的日志消息似乎表明 PostgreSQL 正在写入并完成关闭前的最终检查点,然后成功关闭。

但是,基于 xlog.c 第 6023 行和 xlog.c 第 6503 行的代码(https://github.com/postgres/postgres/blob/ca9cfed883333d5801716eb01cf28b6b5be2b5cd/src/backend/access/transam/xlog.c ;发布超过 2 个链接),分别对应于database system was interrupted [...]database system was not properly shut down [...]日志行,看起来至少pg_control文件没有刷新到磁盘。这让我很担心,因为我希望 Amazon 已经注意确保存储 PostgreSQL 数据和日志文件的卷是适合用途的(即它们在fsync真正完成之前不会报告完成)。

这种行为还有其他解释吗?

Chr*_*wis 1

该问题的答案已在最初发布的 AWS 开发者论坛主题中提供。

概括

RDS PostgreSQL(截至 2018 年 4 月推出的版本)在重启后并不总是能恢复;但是,如果 RDS 实例在未指定的超时时间内未关闭,RDS 将强制终止该实例,要求 PostgreSQL 在重新启动时恢复。

回复全文

感谢您使用 RDS!

我看到这个帖子在其他地方引用,我想我应该快速输入。我与 PostgreSQL 服务团队密切合作,我可以确认您观察到的行为是正确的。截至今天(2018 年 4 月),有时候,如果关闭没有足够快地完成,RDS 自动化将超时并强制终止。类似的各种行为其实已经存在很长时间了,所以你可能以前就观察过。在本线程讨论的少数具体案例中,我无法真正评论为什么 PostgreSQL(或其他数据库引擎)需要比平时更长的时间才能关闭 - 可能有许多不同的可能原因。

需要明确的是,关于是否以及如何以及何时发生强制终止的具体细节可能会随着时间的推移而变化,具体取决于许多变量。永远不会改变的是 RDS 团队对客户数据的持久性和可用性的承诺。这意味着 (1) 我们的工程师在精心设计时考虑到了安全,避免了可能以任何方式增加腐败风险的事情,并且 (2) 我们的工程师始终牢记停机时间(无论以分钟、秒或毫秒为单位)值得尽量减少,因为尽可能安全。

我希望这对您有所帮助,因为您所观察到的现象是经过设计的!

-杰里米