使用读取繁重的从站管理热备中 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 满载 writes
和 reads
,slave 也满载很多 reads
。
查询的最大长度可能约为 8
-10
秒。
我们之前尝试过的:
将 max_standby_archive_delay
和 max_standby_streaming_delay
设置为 900000
(900 秒),但是我们看到了很多 conflict
错误。
将max_standby_archive_delay
和max_standby_streaming_delay
设置为-1
,这使得冲突错误消失了,但是延迟增加了很多(大约23mins
)
将 max_standby_archive_delay
和 max_standby_streaming_delay
设置为 -1
,将 hot_standby_feedback
设置为 on
。这也使冲突错误消失,但我们仍然看到复制滞后(大约 500 secs
)
用于延迟的查询:
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 秒测量的滞后图:
问题:
- 鉴于我们的用例(Slave 被积极用于读取查询,我们如何确保我们没有冲突错误和合理的滞后(大约几秒)
- 滞后是什么意思?是不是只有table一个在Master后面?或者这是否意味着所有其他 WAL 也正在等待应用于 Slave。
- 如果 1. 使用配置属性无法实现,我们如何在代码中解决它(这是最不希望的,因为代码库很大并且需要大量更改)
谢谢!
您无法完全避免冲突——每个像 TRUNCATE
或 ALTER 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 条目。
要求:
避免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 满载 writes
和 reads
,slave 也满载很多 reads
。
查询的最大长度可能约为 8
-10
秒。
我们之前尝试过的:
将
max_standby_archive_delay
和max_standby_streaming_delay
设置为900000
(900 秒),但是我们看到了很多conflict
错误。将
max_standby_archive_delay
和max_standby_streaming_delay
设置为-1
,这使得冲突错误消失了,但是延迟增加了很多(大约23mins
)将
max_standby_archive_delay
和max_standby_streaming_delay
设置为-1
,将hot_standby_feedback
设置为on
。这也使冲突错误消失,但我们仍然看到复制滞后(大约500 secs
)
用于延迟的查询:
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 秒测量的滞后图:
问题:
- 鉴于我们的用例(Slave 被积极用于读取查询,我们如何确保我们没有冲突错误和合理的滞后(大约几秒)
- 滞后是什么意思?是不是只有table一个在Master后面?或者这是否意味着所有其他 WAL 也正在等待应用于 Slave。
- 如果 1. 使用配置属性无法实现,我们如何在代码中解决它(这是最不希望的,因为代码库很大并且需要大量更改)
谢谢!
您无法完全避免冲突——每个像 TRUNCATE
或 ALTER 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 条目。