暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL WAL|redo mirror|multi mirror方法(wal 0丢失) - pg_receivewal+sync replication

digoal 2019-10-27
638

作者

digoal

日期

2019-10-27

标签

PostgreSQL , pg_receivewal , sync replication , mirror , redo , wal , 0丢失 , archive , reltime


背景

wal,redo是数据库的重做日志,事务提交前,务必保证事务产生的修改对应的重做日志都已经持久化,为什么不直接将修改的数据持久化,而是重做日志呢?主要是通常对事务对数据库产生的修改(数据新增、修改或索引数据块的新增和修改)涉及的数据本身是离散的,数据库被设计出来的时候,存储数据的媒介是机械盘,所以离散的写操作性能很差,因此为了弥补这个,设计了重做日志,重做日志的操作是顺序IO,同时重做日志也比较方便用来复制变化量到standby。

acid中d实际上指的就是事务结束时对数据库产生的修改对应redo数据的持久化。redo非常重要,商用数据库支持写多份redo,例如oracle通过创建redo group支持:

```
Add the mirrored groups:

alter database add logfile group 1 ('/oracle/SAL/origlogB/log_g11m1.dbf', '/oracle/SAL/mirrlogB/log_g11m2.dbf') size 100 M;

alter database add logfile group 2 ('/oracle/SAL/origlogA/log_g12m1.dbf', '/oracle/SAL/mirrlogA/log_g12m2.dbf') size 100 M;
```

目前PG暂时不支持mirror redo的功能,但是有一些变通的方法:

1、使用多个块设备 + zfs类似的文件系统 构建mirror

2、pg_receivewal + sync replication

本文介绍方法2,通过pg自身的同步流复制 + pg_receivewal实现多份wal存储。

1 同步流复制

https://www.postgresql.org/docs/12/runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES

[FIRST] num_sync ( standby_name [, ...] ) ANY num_sync ( standby_name [, ...] ) standby_name [, ...]

配置例子

```
standby1: recovery.conf > 'conn info -> application_name=s1'
standby2: recovery.conf > 'conn info -> application_name=s2'
standby3: recovery.conf > 'conn info -> application_name=s3'
standby4: recovery.conf > 'conn info -> application_name=s4'

primary: synchronous_standby_names :

FIRST 3 (s1, s2, s3, s4) 表示前三个为sync standby,后面的都是potential standby,前面不足3个时,接下来的potential standby自动升级为sync standby。

ANY 3 (s1, s2, s3, s4) 表示任意3个都可以为sync standby。
```

2 实时接收 wal

https://www.postgresql.org/docs/12/app-pgreceivewal.html

pg_receivewal [option...]

通过流复制协议,实时接收上游的redo信息。

3 配置多份 wal

例如要求本地写一份wal,同时异地写一份wal. 可以配置如下:

synchronous_standby_names='ANY 1 (s1, s2)'
synchronous_commit=remote_write

同时配置两个不同的异地pg_receivewal , 但是事务提交时,根据以上配置要求redo本地持久化,同时至少有一个receiver端收到redo。

当本地wal挂了,可以从两个receiver目标端,选择接收最多的那个,并使用如下方法配置,做到0丢失。

```
restore_command = 'cp /walarchive/%f %p || cp /walarchive/%f.partial %p'

.partial表示这个wal文件还没有写完,只有部分内容。如果是归档,没有写完的wal是不会归档的,而wal receiver可以实时接收wal,做到0丢失。
```

小结

通过同步流复制,pg_receivewal流士接收wal客户端,实现wal的mirror,即使本地wal文件损坏也不丢失事务。确保0丢失。

参考

https://www.cybertec-postgresql.com/en/never-lose-a-postgresql-transaction-with-pg_receivewal/

https://www.postgresql.org/docs/12/app-pgreceivewal.html

https://www.postgresql.org/docs/12/runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES

PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

9.9元购买3个月阿里云RDS PostgreSQL实例

PostgreSQL 解决方案集合

德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat

文章转载自digoal,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论