想用 PostgreSQL 热备进行只读查询?请先做好恢复冲突检查

数据库 其他数据库
统计信息视图 pg_stat_database_conflicts 包含了,自上次统计信息重置以来,发生的所有恢复冲突的详细说明。您必须在备用服务器(而不是主服务器)上查看该视图,因为只有那里才会发生恢复冲突。

什么是恢复冲突?

每当恢复进程,因为应用更改会中断在进行的查询处理,无法将来自主服务器的 WAL 信息应用到备用服务器时,就会发生恢复冲突。这些查询冲突不会在主服务器上发生,但它们会发生在流复制中的备用服务器上,因为主服务器对备用服务器上发生的情况了解有限。

有几种类型的恢复冲突:

快照恢复冲突

这是最常见的恢复冲突。

如果 VACUUM 处理过一个表并删除了死元组,则可能会发生快照冲突。删除操作将在备用数据库上重做。现在,备用数据库上的一个查询,可能已在主数据库进行 VACUUM 之前启动(它具有较老的快照),因此它仍然可以看到应删除的元组。这样就构成了快照冲突。

锁恢复冲突

备用服务器上的查询,会对它们正在读取的表进行 ACCESS SHARE 锁定。因此,主服务器上的任何 ACCESS EXCLUSIVE 锁定(与 ACCESS SHARE 冲突),都必须在备用服务器上重放,以防止在表上出现不兼容的操作。PostgreSQL 对与SELECT 冲突的操作都会进行这样的锁定,例如DROP TABLE、TRUNCATE 和许多 ALTER TABLE 语句。如果备用数据库需要在一个查询使用的表上重放这样的锁定,就会出现锁冲突。

缓冲页销恢复冲突

减少 VACUUM 工作量的一种方法是使用 HOT(heap-only tuples)更新。然后,当主节点上的任何查询,访问带有死去的堆元组的页面,并可以在其上获得排他锁时,都可以修剪 HOT 链。PostgreSQL 只会在短时间内保持这样的页面锁定,从而跟主数据库上的处理不会冲突。页面锁定还有其他原因,但这可能是最常见的原因。

当备用服务器需要重放此类排他性页面锁定,并且有查询正在使用该页面时(在 PostgreSQL 术语中为 “页面已上销”),您将收到缓冲页销恢复冲突。页面可能会上销一段时间,例如,在对嵌套循环连接的外侧表进行顺序扫描期间。

当然,HOT 链修剪也会导致快照恢复冲突。

罕见的恢复冲突类型

以下类型的冲突很少见,不太会干扰您:

• 死锁恢复冲突:在共享缓冲页上面重放来自主数据库的 WAL 时,备用数据库上的查询访问该缓冲页会阻塞。PostgreSQL 将立即取消此类查询。

• 表空间恢复冲突:在备用服务器上 temp_tablespaces 中有一个表空间,并且有查询在那里有临时文件。当主服务器上发生 DROP TABLESPACE 操作时,我们会遇到冲突。在这种情况下,PostgreSQL 会取消备用服务器上的所有查询。

• 数据库恢复冲突:如果备用服务器在数据库上有活动会话,DROP DATABASE 操作的复制会发生冲突。在这种情况下,PostgreSQL 会终止与备用服务器上的数据库的所有连接。

备用服务器如何解决恢复冲突?

参数 max_standby_streaming_delay 确定当 WAL 重放遇到恢复冲突时会发生什么情况(有一个类似的参数 max_standby_archive_delay,对于归档恢复进行相同的处理)。PostgreSQL 暂停 WAL 信息的重放,最多 max_standby_streaming_delay 毫秒。如果冲突的查询在该时间之后仍在运行,PostgreSQL 会取消它,并显示类似下面内容的错误消息:

ERROR:  canceling statement due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.

详细信息显示,这是由快照恢复冲突产生的错误。

max_standby_streaming_delay 默认值为 30 秒,因此,备用数据库上的查询,有半分钟的“宽限时间”来完成,如果它们引起了恢复冲突,它们会被取消掉。这是底限值 0(PostgreSQL 立即取消查询,无重放延迟)和特殊值 -1(PostgreSQL 从不取消查询,重放延迟可以任意长)之间的中间取值。

查询 pg_stat_database 视图

统计信息视图 pg_stat_database_conflicts 包含了,自上次统计信息重置以来,发生的所有恢复冲突的详细说明。您必须在备用服务器(而不是主服务器)上查看该视图,因为只有那里才会发生恢复冲突。

请注意,此视图不会显示发生的所有恢复冲突,它仅显示导致备用数据库上查询被取消的冲突。我们可以使用下面的查询,来检查恢复冲突:

SELECT conflicts FROM pg_stat_database
  WHERE datname = current_database();

一旦发现有许多恢复冲突,您就可以找到那些导致恢复冲突的查询,并调整它们。

责任编辑:武晓燕 来源: 红石PG
相关推荐

2017-06-16 10:39:51

双机热备软件

2018-10-16 16:45:05

数据库读写分离

2018-03-26 17:40:29

数据库PostgreSQL主备环境搭建

2009-01-09 22:37:43

服务器系统故障

2021-09-28 11:15:49

MySQL备份数据库

2023-10-10 07:33:30

Kubernetes容器

2018-01-22 10:05:14

灾备

2024-01-31 12:06:32

PostgreSQL递归函数查询

2021-07-14 23:38:02

PostgreSQLOracle模式

2009-11-17 10:16:45

2012-12-20 16:20:38

灾难恢复数据保护

2024-11-15 08:00:00

2015-07-03 10:59:19

数据中心灾备

2018-09-04 11:09:58

容灾灾备系统

2010-05-12 17:15:57

2013-03-27 11:17:09

宝德虚拟化双机热备

2011-12-16 10:25:52

2020-09-10 16:50:32

mysqldump数据库热备

2022-01-19 10:50:36

灾难恢复

2011-09-22 10:48:20

MySQL集群HAProxy
点赞
收藏

51CTO技术栈公众号