七叶笔记 » 数据库 » postgresql流复制原理以及流复制和逻辑复制的区别说明

postgresql流复制原理以及流复制和逻辑复制的区别说明

SyncRepWaitForLSN @ src/backend/replication/syncrep.c

注意用户进入等待状态后,只有主动cancel , 或者kill(terminate) , 或者主进程die才能退出无限的等待状态。后面会讲到如何将同步级别降级为异步。

前面提到了,用户端需要等待LATCH的释放信号。

那么谁来给它这个信号了,是wal sender进程,源码和解释如下 :

src/backend/replication/walsender.c

SyncRepWakeQueue @ src/backend/replication/syncrep.c

如何设置事务可靠性级别

PostgreSQL 支持在会话中设置事务的可靠性级别。

off 表示commit 时不需要等待wal 持久化。

local 表示commit 是只需要等待本地数据库的wal 持久化。

remote_write 表示commit 需要等待本地数据库的wal 持久化,同时需要等待sync standby节点wal write buffer完成(不需要持久化)。

on 表示commit 需要等待本地数据库的wal 持久化,同时需要等待sync standby节点wal持久化。

提醒一点, synchronous_commit 的任何一种设置,都不影响wal日志持久化必须先于shared buffer脏数据持久化。 所以不管你怎么设置,都不好影响数据的一致性。

如何实现同步复制降级

从前面的代码解析可以得知,如果 backend process 进入了等待循环,只接受几种信号降级。 并且降级后会告警,表示本地wal已持久化,但是sync standby节点不确定wal有没有持久化。

如果你只配置了1个standby,并且将它配置为同步流复制节点。一旦出现网络抖动,或者sync standby节点故障,将导致同步事务进入等待状态。

怎么降级呢?

方法1.

修改配置文件并重置

然后cancel 所有query .

收到这样的信号,表示事务成功提交,同时表示WAL不知道有没有同步到sync standby。

同时它会读到全局变量synchronous_commit 已经是 local了。

这样就完成了降级的动作。

方法2.

方法1的降级需要对已有的正在等待wal sync的pid使用cancel进行处理,有点不人性化。

可以通过修改代码的方式,做到更人性化。

SyncRepWaitForLSN for循环中,加一个判断,如果发现全局变量sync commit变成local, off了,则告警并退出。这样就不需要人为的去cancel query了.

WARNING: canceling wait for synchronous replication due to user request

DETAIL: The transaction has already committed locally, but might not have been replicated to the standby.

以上为个人经验,希望能给大家一个参考,也希望大家多多支持七叶笔记。如有错误或未考虑完全的地方,望不吝赐教。

相关文章