使用读取繁重的从站管理热备中 Postgres 复制的冲突和滞后

Manage conflicts and lag on Postgres Replication in Hot Standby with read heavy Slave

要求:

避免terminating connection due to conflict with recovery错误,也有acceptable replication lag.

Google Cloud PostgreSQL 9.6,复制开启(使用流式复制),PPGool-II 设置为仅进行负载平衡并在从站上具有以下属性:

work_mem    3276800
commit_delay    100
max_wal_size    940
max_standby_archive_delay   -1
max_standby_streaming_delay -1
hot_standby_feedback    on

机器配置:

vCPU:8,内存:30 GB,SSD 存储:76 GB

工作量:

Master 满载 writesreads,slave 也满载很多 reads。 查询的最大长度可能约为 8-10 秒。

我们之前尝试过的:

用于延迟的查询:

SELECT
  pg_last_xlog_receive_location() receive,
  pg_last_xlog_replay_location() replay,
  (
   extract(epoch FROM now()) -
   extract(epoch FROM pg_last_xact_replay_timestamp())
  )::int lag;

9 hours 期间每 1 秒测量的滞后图:

问题:

  1. 鉴于我们的用例(Slave 被积极用于读取查询,我们如何确保我们没有冲突错误合理的滞后(大约几秒)
  2. 滞后是什么意思?是不是只有table一个在Master后面?或者这是否意味着所有其他 WAL 也正在等待应用于 Slave。
  3. 如果 1. 使用配置属性无法实现,我们如何在代码中解决它(这是最不希望的,因为代码库很大并且需要大量更改)

谢谢!

您无法完全避免冲突——每个像 TRUNCATEALTER TABLE 这样需要 ACCESS EXCLUSIVE 锁的语句都会导致复制冲突。

但是可以避免VACUUM:

引起的复制冲突
  • 设置 hot_standby_feedback = on 以防止 PostgreSQL 删除备用数据库上仍然需要的元组。

  • old_snapshot_threshold 设置为默认值以外的(可能很高)值以避免 vacuum 截断.

    此截断需要 ACCESS EXCLUSIVE 锁,这也会导致冲突。

对于剩余的冲突,您可以选择延迟申请和取消查询。或者您更改工作负载以避免 ACCESS EXCLUSIVE 锁。

要找出是什么阻碍了您,您必须在 WAL 文件上使用 pg_xlogdump 并搜索 ACCESS EXCLUSIVE 锁。这将允许您找出哪个对象被锁定。要找出执行了哪种操作,请检查紧接在 (VACUUM?) 之前或紧接在之后 (DDL?) 的 WAL 条目。