searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

PostgreSQL备库的查询高概率报错

2023-06-08 10:33:11
87
0

一、问题描述

Hot Standby环境下的 standby节点执行查询时报错,报错信息如下::
ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed.

PostgreSQL 的 Hot Standby常被用来当只读的数据库提供查询或者统计服务, 但是由于各种原因查询SQL可能被cancel掉。

二、分析过程

R/W instance -> wal -> RO instance -> startup process replay wal -> conflict with query ->replay recovery等待query -> 有限度的等待 -> cancel query
replay的wal里面包含什么信息时会和query冲突?
1)最常见的情况: vacuum某些tuple version, 与query快照的xid(xmin)相冲突
2)其他: 删除表空间, 锁冲突, pinned buffer, 死锁等

参数max_standby_streaming_delay默认为30秒,也就是说vacuum的时候,相关需要清理的tuple数据仍有其他事物在使用,则认为有冲突,等待这个参数设置的值,30秒后则中断query连接,报出以上错误。
这里可能是DDL,比如drop table,truncate table,drop database,drop tablespace等等,也可能是DML,delete,update等等语句都会引起错误发生。

三、解决办法

要避免DDL发生,那么需要设置参数max_standby_streaming_delay=-1,这样就会一直等待查询的语句结束为止;如果是从归档中回放产生的冲突,那就max_standby_archive_delay设置为-1。
要避免DML,也就是VACUUM产生的冲突,除了以上方法,还可以引入另外一个参数hot_standby_feedback,可以打开该参数(设置为on)避免;hot_standby_feedback 的原理很简单,就是将备节点的最小活跃事务 ID(xmin) 定期告知主节点,使得主节点在执行 VACUUM 时对这些事务还需要的数据手下留情。

另外也可以考虑设置vacuum_defer_cleanup_age参数,这个参数可以延迟清理dead tuple,使得在备节点的查询可以读取这些dead tuple,默认为0,这个参数是在主节点上设置,也是由主节点度量的,所以这个值很难确定设置多少为有效,如果主节点事物数增长很快,那么很快dead tuple就会被清理,对于备节点的查询冲突没什么效果,所以还会引发的冲突错误,不建议设置该参数解决。

1)从节点调大replay等待时长,设置query feedback(hot_standby_feedback) 

a.根据实际情况,调大参数:max_standby_streaming_delay = 5min,比如有慢SQL执行时间估计在5min左 右,从而Standby库主动 cancel query 了;也可以将这个参数设置成 -1,表示 standby 节点永远等侍这个查询, 但是有风险的,如果这个查询不结束,那么从库一直处于与主库的中断状态,不会同步主库数据,而会一 直等从库这个SQL执行完成;
b.开启hot_standby_feedback=on

2)主节点设置延迟回收

vacuum_defer_cleanup_age
综合使用以上参数,能够有效的降低冲突发生的概率。

四、总结

开启max_standby_streaming_delay或者max_standby_archive_delay也有弊端,如果备节点有长事物,那么备节点会长时间跟不上主节点,主备节点的数据无法保证实时读一致性(延时)
设置 hot_standby_feedback 的好处是可以减少备节点执行查询时复制冲突的可能,但也有其弊端,即会使主节点先相关表的数据延迟回收,从而导致主节点vacuum出现无用功,相关表膨胀,如果业务频繁查询,更新,删除,那么这些膨胀的表DML处理肯定效率低下,将会影响业务响应;极端情况下,如果备节点有一个很长的事务,且涉及表上 DML 操作又很频繁,则表的膨胀则会很严重。
另外vacuum_defer_cleanup_age效果不好,主要是在主节点度量这个值,所以不建议设置。

0条评论
0 / 1000
ly
8文章数
0粉丝数
ly
8 文章 | 0 粉丝
原创

PostgreSQL备库的查询高概率报错

2023-06-08 10:33:11
87
0

一、问题描述

Hot Standby环境下的 standby节点执行查询时报错,报错信息如下::
ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed.

PostgreSQL 的 Hot Standby常被用来当只读的数据库提供查询或者统计服务, 但是由于各种原因查询SQL可能被cancel掉。

二、分析过程

R/W instance -> wal -> RO instance -> startup process replay wal -> conflict with query ->replay recovery等待query -> 有限度的等待 -> cancel query
replay的wal里面包含什么信息时会和query冲突?
1)最常见的情况: vacuum某些tuple version, 与query快照的xid(xmin)相冲突
2)其他: 删除表空间, 锁冲突, pinned buffer, 死锁等

参数max_standby_streaming_delay默认为30秒,也就是说vacuum的时候,相关需要清理的tuple数据仍有其他事物在使用,则认为有冲突,等待这个参数设置的值,30秒后则中断query连接,报出以上错误。
这里可能是DDL,比如drop table,truncate table,drop database,drop tablespace等等,也可能是DML,delete,update等等语句都会引起错误发生。

三、解决办法

要避免DDL发生,那么需要设置参数max_standby_streaming_delay=-1,这样就会一直等待查询的语句结束为止;如果是从归档中回放产生的冲突,那就max_standby_archive_delay设置为-1。
要避免DML,也就是VACUUM产生的冲突,除了以上方法,还可以引入另外一个参数hot_standby_feedback,可以打开该参数(设置为on)避免;hot_standby_feedback 的原理很简单,就是将备节点的最小活跃事务 ID(xmin) 定期告知主节点,使得主节点在执行 VACUUM 时对这些事务还需要的数据手下留情。

另外也可以考虑设置vacuum_defer_cleanup_age参数,这个参数可以延迟清理dead tuple,使得在备节点的查询可以读取这些dead tuple,默认为0,这个参数是在主节点上设置,也是由主节点度量的,所以这个值很难确定设置多少为有效,如果主节点事物数增长很快,那么很快dead tuple就会被清理,对于备节点的查询冲突没什么效果,所以还会引发的冲突错误,不建议设置该参数解决。

1)从节点调大replay等待时长,设置query feedback(hot_standby_feedback) 

a.根据实际情况,调大参数:max_standby_streaming_delay = 5min,比如有慢SQL执行时间估计在5min左 右,从而Standby库主动 cancel query 了;也可以将这个参数设置成 -1,表示 standby 节点永远等侍这个查询, 但是有风险的,如果这个查询不结束,那么从库一直处于与主库的中断状态,不会同步主库数据,而会一 直等从库这个SQL执行完成;
b.开启hot_standby_feedback=on

2)主节点设置延迟回收

vacuum_defer_cleanup_age
综合使用以上参数,能够有效的降低冲突发生的概率。

四、总结

开启max_standby_streaming_delay或者max_standby_archive_delay也有弊端,如果备节点有长事物,那么备节点会长时间跟不上主节点,主备节点的数据无法保证实时读一致性(延时)
设置 hot_standby_feedback 的好处是可以减少备节点执行查询时复制冲突的可能,但也有其弊端,即会使主节点先相关表的数据延迟回收,从而导致主节点vacuum出现无用功,相关表膨胀,如果业务频繁查询,更新,删除,那么这些膨胀的表DML处理肯定效率低下,将会影响业务响应;极端情况下,如果备节点有一个很长的事务,且涉及表上 DML 操作又很频繁,则表的膨胀则会很严重。
另外vacuum_defer_cleanup_age效果不好,主要是在主节点度量这个值,所以不建议设置。

文章来自个人专栏
数据库运维
8 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0