暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

LightDB/PostgreSQL ERROR: canceling statement due to conflict with recovery浅析

原创 姚崇 2023-05-30
583

应用连接数据库从库查询报错

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

分析

这个错误是由于 LightDB 的并发控制(MVCC)机制与在线备份和恢复(HOT Standby)机制发生冲突。

在 LightDB/Postgres 中,每个事务对数据的修改都会生成新的数据版本,旧的数据版本不会立即删除,而是会保留一段时间,以供其他正在运行的事务使用。当所有事务都不再需要旧的数据版本时,它们才会被清理(vacuum)。这就是 MVCC(多版本并发控制)的工作原理。

然而,在在线备份和恢复(Hot Standby)模式下,备份服务器需要在主服务器上保留足够多的旧版本数据,以便备份服务器可以捕获到所有数据的变更。

这种情况下,如果有一个查询需要看到的数据版本已经被清理,就会出现你看到的错误:canceling statement due to conflict with recovery。此时,PostgreSQL 会尝试取消正在运行的查询,以防止它看到不一致的数据。

解决此问题的方法取决于你的具体情况。以下是一些可能的选项:

  1. 尝试减少长时间运行的大事务,因为它们可能会阻止旧版本数据的清理。
  2. 考虑增大 max_standby_archive_delay 和 max_standby_streaming_delay 配置参数的值。这些参数控制了备份服务器在数据冲突发生时可以等待的时间。
  3. 考虑禁用热备模式,或者在主服务器上启用逻辑复制。这两种方式都可以避免数据版本冲突的问题,但可能有其他的副作用,需要谨慎使用。

在 LightDB的主从复制环境中,备库在默认情况下是以只读模式运行的,用于备份和查询。这种模式也被称为热备模式或 Hot Standby。

你遇到的错误信息在热备模式下是常见的,原因是主库在运行事务并生成新的数据版本,而从库在试图查询那些可能已经被清理的旧数据版本。在主库清理行版本时,如果有需要这些行版本的查询在备库上运行,LightDB 将取消这些查询以避免数据不一致。这就是你看到的“canceling statement due to conflict with recovery”的错误信息。

要解决这个问题,你可以尝试以下方法:

  1. 在从库上调整 max_standby_archive_delay 和 max_standby_streaming_delay 的设置。这两个参数决定了在数据冲突发生时,备库可以等待的最长时间。如果增加这两个参数的值,从库可以等待更长的时间,从而降低查询被取消的可能性。
  2. 优化查询或减少查询的复杂性,使其尽可能快地完成,减少需要旧版本数据的时间。
  3. 考虑在主库上启用逻辑复制,而不是物理复制。逻辑复制可以避免这种数据版本冲突的问题,但可能会导致其他问题,需要谨慎使用。
  4. 如果可能,考虑在不那么繁忙的时间执行大型查询操作。

这些都是一些可能的解决办法,但具体的最佳选择将取决于你的具体情况和需求。

这两个参数 max_standby_archive_delay 和 max_standby_streaming_delay 在 PostgreSQL 的备份服务器(standby)上控制当出现数据冲突时,备份服务器等待主服务器(primary)的最大延迟时间。

在 PostgreSQL 的主备(primary-standby)复制环境中,备库(即从库)在默认情况下是以只读模式运行的,这种模式也被称为热备模式(Hot Standby)。备库在这个模式下主要用于查询和备份,同时接收并应用主库的数据更改。如果备库的查询需要访问已经被主库清理的行版本,就会发生数据冲突。

这两个参数的具体含义如下:

max_standby_archive_delay: 这个参数控制备库在应用存档(archive)恢复的 WAL (Write-Ahead Log)记录时的最大延迟时间。当主备之间的数据冲突发生时,备库会等待一段时间来尝试解决这个冲突,这个等待的最大时间就由 max_standby_archive_delay 控制。其默认值是 30 秒。

max_standby_streaming_delay: 这个参数控制备库在应用流(streaming)恢复的 WAL 记录时的最大延迟时间。这个流恢复的过程是主库将其最新的 WAL 记录实时传送到备库,备库再应用这些记录。当主备之间的数据冲突发生时,备库也会等待一段时间来尝试解决这个冲突,这个等待的最大时间就由 max_standby_streaming_delay 控制。其默认值也是 30 秒。

简单来说,这两个参数都是在处理主从数据冲突时,备库等待的最大时间。如果增加这两个参数的值,备库可以等待更长的时间,从而降低因数据冲突导致查询被取消的可能性。
参考:
https://stackoverflow.com/questions/14592436/postgresql-error-canceling-statement-due-to-conflict-with-recovery

最后修改时间:2023-07-10 18:59:47
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论