Dim*_*las 4 postgresql replication amazon-rds
在 aws RDS 上的 postgresql 主从复制方案上的复制服务器中,我收到以下错误:
SQLSTATE[40001]: Serialization failure: 7 ERROR: canceling statement due to conflict with recovery
Run Code Online (Sandbox Code Playgroud)
据我了解,原因是复制的发生类似于数据库迁移。查询序列被写入称为 WAL 的内容,然后以 FIFO 序列执行。
另外,我了解到,一旦在执行 wal 时执行查询,可能会导致冲突,因为有时当前正在执行的查询可能会导致获取陈旧数据。
因此,根据文档,存在延迟,允许首先执行当前查询,然后应用 wal 更改。这些是:
max_standby_archive_delay
max_standby_streaming_delay
但是在繁重的查询(查询执行时间> 30秒)上将这些值设置为-1会导致副本在较长时间内拥有过时的数据吗?
是的,就是这个想法。在复制冲突的情况下,PostgreSQL 只有两个选择:
取消查询
延迟复制更改的应用。
设置max_standby_streaming_delay
为 -1 将无限期地延迟复制。
有多种方法可以减少复制冲突:
设置hot_standby_feedback = on
以消除由 引起的复制冲突VACUUM
。您所付出的代价是,在备用数据库上长时间运行的查询可能会使您的表膨胀。
在您的工作负载中不要有任何类似DROP TABLE
、TRUNCATE
、ALTER TABLE
和类似的语句会导致ACCESS EXCLUSIVE
锁定。
在 PostgreSQL v12 中,您可以设置
ALTER TABLE atable SET (vacuum_truncate = off);
Run Code Online (Sandbox Code Playgroud)
禁用 autovacuum 截断(这也会导致短ACCESS EXCLUSIVE
锁定)。在旧版本中,只有粗略且未记录的解决方法,即设置old_snapshot_threshold
为默认值以外的其他值。
这一切都很复杂,并且可能会产生不良影响,因此最好的建议是:如果您想要一个不会超过必要滞后的备用服务器,但您还想在备用服务器上运行长时间运行的查询,则应该使用两个备用服务器,一个用于这些相互冲突的目的中的每一个。