天天看点

异步流复制模式如何保证不丢数据?

postgresql , 流复制 , 异步 , 2pc , 3pc

postgresql支持多种事务commit模式,以一主多备的同步流复制为例,事务的redo信息持久化是怎样的呢?

配置synchronous_commit参数如下,以及对应的含义:

local:表示redo本地持久化。

on:表示本地持久化,以及一个备库持久化。

remote_write:表示本地持久化,以及备库异步write完成。

off:表示本地写wal buffer完成。

quorum:表示本地持久化,同时加上备库已持久化的个数,需要超过半数节点。

很显然,如果只有一个备库,并且synchronous_commit使用local模式的话,在发生ha时,不能保证不丢数据。

但是有什么方法能做到只有一个备库,并且synchronous_commit使用local模式,还能不丢数据呢?

两阶段提交(2pc),在很多分布式数据库中,被用于确保分布式事务的一致性。

在单个数据库中,也可以被业务用于多个事务之间的依赖保证。

实际上,如果你要保证事务提交后,在异步的备库也提交,也可以使用2pc来实现。

首先我们要了解如何判断备库的延迟.

查看当前数据库的lsn位置。

查看备库接收并持久化的wal lsn位置。

当 "备库的lsn >= 当前主库的lsn" 时,说明你前面提交的事务都已经同步到备库了。

主库

产生一个2pc事务

查看备库lsn是否大于等于主库当前的lsn

确保 备库lsn是否大于等于主库当前的lsn 后,关闭主库(模拟主库down机)

查看备库现在有没有未结束的2pc事务,当前还没有激活,所以看不到

激活备库

再次查看备库,未提交的2pc出现了。

你要做的是提交或回滚这些2pc事务即可。

使用这种方式,我们在异步的流复制节点中,也可以做到不丢事务。(虽然这么做比较繁琐。)

对于非常关键的事务,你可以通过以上方式来实现异步复制也不丢数据。

实际上postgresql的同步级别(synchronous_commit)可以配置在事务中,也就是说,可以对可靠性要求高的事务,设置为同步模式。

对于可靠性要求低的事务,设置为异步模式。

例子,设置事务为同步模式。

例子,设置事务为异步模式。

<a href="https://github.com/digoal/blog/blob/master/201703/20170312_18.md">《postgresql 10.0 preview 功能增强 - slave支持waitlsn 'lsn', time;用于设置安全replay栅栏》</a>

<a href="https://www.postgresql.org/docs/9.6/static/sql-prepare-transaction.html">https://www.postgresql.org/docs/9.6/static/sql-prepare-transaction.html</a>

<a href="https://www.postgresql.org/docs/9.6/static/sql-commit-prepared.html">https://www.postgresql.org/docs/9.6/static/sql-commit-prepared.html</a>

<a href="https://www.postgresql.org/docs/9.6/static/sql-rollback-prepared.html">https://www.postgresql.org/docs/9.6/static/sql-rollback-prepared.html</a>

<a href="https://www.postgresql.org/docs/9.6/static/view-pg-prepared-xacts.html">https://www.postgresql.org/docs/9.6/static/view-pg-prepared-xacts.html</a>