测试从pg_receivewal的日志中恢复从库为主库:

主从配置async模式,配置pg_receivewal接收日志pg_receivewal -D /dbaas/pg/data/pg_receivewal_data -v -h 10.9.10.202

主插入1000万数据,当插入一半时,停止从库

主库插完数据,停止

将pg_receivewal的日志拷贝到从库/dbaas/pg/data/pg_receivewal_data下

修改从库recovery.conf文件,添加内容:

restore_command = 'cp /dbaas/pg/data/pg_receivewal_data/%f "%p"'

启动数据库,数据库成功恢复到10000000行。

另外一种用法:

restore_command = 'cp /dbaas/pg/data/pg_receivewal_data/%f "%p"'

standby_mode = on

primary_conninfo = 'host=10.9.10.203 port=5432 user=postgres connect_timeout=60'

recovery_target_timeline = 'latest'

trigger_file = '/dbaas/pg/data/.tfile'

这种把恢复和备库设置放一起,会先去从归档恢复,当恢复完成后,直接建立流复制关系,这样就相当方便了,当有归档时,不用重做从库。

测试pg_receivewal的同步机制:

-S slotname

--slot=slotname

Require pg_receivewal to use an existing replication slot (see Section 26.2.6). When this option is used, pg_receivewal will report a flush position to the server, indicating when each segment has been synchronized to disk so that the server can remove that segment if it is not otherwise needed.

When the replication client of pg_receivewal is configured on the server as a synchronous standby, then using a replication slot will report the flush position to the server, but only when a WAL file is closed. Therefore, that configuration will cause transactions on the primary to wait for a long time and effectively not work satisfactorily. The option --synchronous (see below) must be specified in addition to make this work correctly.

--synchronous

Flush the WAL data to disk immediately after it has been received. Also send a status packet back to the server immediately after flushing, regardless of --status-interval.

This option should be specified if the replication client of pg_receivewal is configured on the server as a synchronous standby, to ensure that timely feedback is sent to the server.

在这个说明中,使用了--slot=for_pgreceivewal --synchronous后,理论上是有点像sync同步一样,数据库会等待接收端进行回放,回放结束,再进行commit。

1)使slotsynchronous参数:

数据库端:

修改postgresql.conf参数synchronous_standby_name=‘pg_receivewal’

重启数据库

postgres=# select pg_create_physical_replication_slot('for_pgreceivewal');

pg_create_physical_replication_slot

-------------------------------------

(for_pgreceivewal,)

(1 row)

postgres=# select pg_get_replication_slots();

pg_get_replication_slots

----------------------------------------

(for_pgreceivewal,,physical,,f,f,,,,,)

(1 row)

postgres=# select pg_get_replication_slots();

pg_get_replication_slots

--------------------------------------------------------

(for_pgreceivewal,,physical,,f,t,629488,,,0/9DD77B00,)

(1 row)

接收端:

pg_receivewal -D /dbaas/pg/data/pg_receivewal_data --slot=for_pgreceivewal --synchronous -v -h 10.9.10.202

数据库端:

postgres=# select * from pg_stat_replication ;

pid   | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_start         | backend_xmin |   state   |  sent_lsn  | write_lsn  | flush_lsn  | replay_lsn |    write_lag    |    flush_lag    |   replay_lag    | sync_priority | sync_state

--------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------------+-----------------+-----------------+---------------+------------

912703 |       10 | postgres | pg_receivewal    | 10.9.10.203 |                 |       63103 | 2019-05-15 02:52:30.029814+00 |              | streaming | 0/D9E44528 | 0/D9E44528 | 0/D9E44528 |            | 00:00:00.010972 | 00:00:00.010972 | 00:06:49.964729 |             1 | sync

(1 row)

在数据库端,使用pgbench测试:

[postgres@90027282-dd74-4642-b5dd-359b6cc67aaf /dbaas/pg/data]$ pgbench -c 10 -j 5 -r -T 100 pgbench

starting vacuum...end.

transaction type: <builtin: TPC-B (sort of)>

scaling factor: 100

query mode: simple

number of clients: 10

number of threads: 5

duration: 100 s

number of transactions actually processed: 15290

latency average = 65.426 ms

tps = 152.845128 (including connections establishing)

tps = 152.855112 (excluding connections establishing)

statement latencies in milliseconds:

0.002  \set aid random(1, 100000 * :scale)

0.001  \set bid random(1, 1 * :scale)

0.001  \set tid random(1, 10 * :scale)

0.000  \set delta random(-5000, 5000)

0.046  BEGIN;

0.300  UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;

0.111  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;

0.417  UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;

2.878  UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;

0.092  INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);

61.539  END;

2)不使用slotsynchronous参数

数据库端,删除slot

postgres=# select pg_drop_replication_slot('for_pgreceivewal');

pg_drop_replication_slot

--------------------------

(1 row)

postgres=# select pg_get_replication_slots();

pg_get_replication_slots

--------------------------

(0 rows)

接收端:

pg_receivewal -D /dbaas/pg/data/pg_receivewal_data  -v -h 10.9.10.202

压测:

[postgres@90027282-dd74-4642-b5dd-359b6cc67aaf ~]$ pgbench -c 10 -j 5 -r -T 100 pgbench

starting vacuum...end.

transaction type: <builtin: TPC-B (sort of)>

scaling factor: 100

query mode: simple

number of clients: 10

number of threads: 5

duration: 100 s

number of transactions actually processed: 27015

latency average = 37.021 ms

tps = 270.120226 (including connections establishing)

tps = 270.138206 (excluding connections establishing)

statement latencies in milliseconds:

0.002  \set aid random(1, 100000 * :scale)

0.001  \set bid random(1, 1 * :scale)

0.001  \set tid random(1, 10 * :scale)

0.000  \set delta random(-5000, 5000)

0.042  BEGIN;

0.242  UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;

0.110  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;

0.291  UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;

1.778  UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;

0.091  INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);

34.396  END;

同步模式下,停止pg_receivewal,会导致主hang住:

postgres=# create table test(id int, info varchar(8), crt_time timestamp);

^CCancel request sent

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.

CREATE TABLE

pg_receivewal的使用场景思考:

1)当配置高可用集群时,一个备库很危险,容易出现单点故障,当同步节点死掉后,主节点会hang住(这是没有专业高可用工具的情况下,ecox这种高可用工具,会自动处理为单节点可写)。而部署两个同步节点又会浪费资源(不做读写分离的情况下),这个时候,可以创建一个pg_receivewal节点,使用同步模式,当一个同步节点停止后,它可以充当sync节点,给主节点报告LSN。

为了减少网络开销,还可以将pg_receivewal节点设置为主库本地,即起到了归档作用,又起到了同步节点的功能。唯一注意的是,要定期清理日志空间。

2)第二种情况,数据库集群不使用sync模式,想使用更加高性能的async模式。这时,使用pg_receivewal来做日志归档,至少比aync节点同步的日志要多。这样基于他的恢复,也将丢更少的数据。当数据库更新插入极端的大时,pg_receivewal归档的日志,可能还没有归档命令归档的多。归档是到本地,如果服务器挂了,那么归档也没有了,可以使用pgbackrest或者rync工具将归档同步到其他服务器。

用更加精炼的话说:

1)避免单点故障。这点比较鸡肋,某些高级的高可用工具本身就能解决单点故障。

2)用来做日志归档,归档到块级别,且能归档到远端。比archive_command要更加多(默认归档是完成一个wal文件才归档一个,还未写满的wal是不会归档的)。主从之间保持sync模式,那没必要用pg_receivewal来归档;如果是async模式追求性能,pg_receivewal也不能配成同步来影响性能啊(让步:将pg_receivewal放到本地,这样减少网络传输开销,保持同步,能否接受,答案是同步下性能还是很差,而且差距很大,下面是测试数据)。

postgres=# select * from pg_stat_replication ;
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state
--------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------------+-----------------+-----------------+---------------+------------
745643 | 10 | postgres | pg_receivewal | ::1 | | 58465 | 2019-05-16 03:53:06.628954+00 | | streaming | 1/CB059FC8 | 1/CB059FC8 | 1/CB059FC8 | | 00:00:00.191089 | 00:00:00.191089 | 00:00:32.187898 | 1 | sync
668818 | 10 | postgres | walreceiver | 10.9.10.203 | | 42007 | 2019-05-16 03:37:21.983067+00 | | streaming | 1/CB059FC8 | 1/CB059FC8 | 1/CB059FC8 | 1/CB059FC8 | | | | 0 | async
(2 rows) (END)

在本地同步性能:

[postgres@90027282-dd74-4642-b5dd-359b6cc67aaf /dbaas/pg]$ pgbench -c 10 -j 5 -r -T 100 pgbench
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: simple
number of clients: 10
number of threads: 5
duration: 100 s
number of transactions actually processed: 17313
latency average = 57.785 ms
tps = 173.054591 (including connections establishing)
tps = 173.066373 (excluding connections establishing)
statement latencies in milliseconds:
0.002 \set aid random(1, 100000 * :scale)
0.001 \set bid random(1, 1 * :scale)
0.001 \set tid random(1, 10 * :scale)
0.000 \set delta random(-5000, 5000)
0.048 BEGIN;
0.268 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.111 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.457 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
2.694 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.092 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
53.995 END;

异地同步性能更低:

[postgres@90027282-dd74-4642-b5dd-359b6cc67aaf /dbaas/pg]$ pgbench -c 10 -j 5 -r -T 100 pgbench
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: simple
number of clients: 10
number of threads: 5
duration: 100 s
number of transactions actually processed: 14289
latency average = 70.130 ms
tps = 142.591560 (including connections establishing)
tps = 142.601721 (excluding connections establishing)
statement latencies in milliseconds:
0.002 \set aid random(1, 100000 * :scale)
0.001 \set bid random(1, 1 * :scale)
0.001 \set tid random(1, 10 * :scale)
0.000 \set delta random(-5000, 5000)
0.045 BEGIN;
0.244 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.111 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.388 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
2.975 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.091 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
65.978 END;

异地异步,性能高很多:

[postgres@90027282-dd74-4642-b5dd-359b6cc67aaf /dbaas/pg]$ pgbench -c 10 -j 5 -r -T 100 pgbench
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: simple
number of clients: 10
number of threads: 5
duration: 100 s
number of transactions actually processed: 26333
latency average = 37.987 ms
tps = 263.246388 (including connections establishing)
tps = 263.264004 (excluding connections establishing)
statement latencies in milliseconds:
0.002 \set aid random(1, 100000 * :scale)
0.001 \set bid random(1, 1 * :scale)
0.001 \set tid random(1, 10 * :scale)
0.000 \set delta random(-5000, 5000)
0.042 BEGIN;
0.228 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.109 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.310 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
1.764 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.090 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
35.349 END;

本地异步呢,更快:

[postgres@90027282-dd74-4642-b5dd-359b6cc67aaf /dbaas/pg]$ pgbench -c 10 -j 5 -r -T 100 pgbench
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: simple
number of clients: 10
number of threads: 5
duration: 100 s
number of transactions actually processed: 29572
latency average = 33.821 ms
tps = 295.670234 (including connections establishing)
tps = 295.691390 (excluding connections establishing)
statement latencies in milliseconds:
0.002 \set aid random(1, 100000 * :scale)
0.001 \set bid random(1, 1 * :scale)
0.001 \set tid random(1, 10 * :scale)
0.000 \set delta random(-5000, 5000)
0.042 BEGIN;
0.219 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.108 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.253 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
1.592 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.091 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
31.412 END;

接下来要思考的场景:

那如果遇到一个落后很久的备库,想不重建的情况下恢复。有归档日志,我们应该怎么做?

1)先从归档恢复,再建立同步?不行,恢复后,日志线就+1了,不能再和主建立同步了。

2)将归档日志,从库缺少的地方开始,拷贝到主库pg_wal下,再进行启动从库。待验证。

3)直接在从库的recovery.conf文件配置如下,先从归档恢复,再恢复流复制关系,这样最靠谱:

restore_command = 'cp /dbaas/pg/data/pg_receivewal_data/%f "%p"'

standby_mode = on

primary_conninfo = 'host=10.9.10.203 port=5432 user=postgres connect_timeout=60'

recovery_target_timeline = 'latest'

trigger_file = '/dbaas/pg/data/.tfile'

pg_receivewal实践的更多相关文章

  1. webp图片实践之路

    最近,我们在项目中实践了webp图片,并且抽离出了工具模块,整合到了项目的基础模板中.传闻IOS10也将要支持webp,那么使用webp带来的性能提升将更加明显.估计在不久的将来,webp会成为标配. ...

  2. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  3. TDD在Unity3D游戏项目开发中的实践

    0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...

  4. Logstash实践: 分布式系统的日志监控

    文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...

  5. 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

    一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...

  6. Windows平台分布式架构实践 - 负载均衡

    概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...

  7. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  8. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  9. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

随机推荐

  1. Python---webserver

    一. # HTTP项目实战 - 深入理解HTTP协议 - 模拟后台服务程序基本流程和大致框架 - 每一个步骤一个文件夹 - 图解http协议,图解tcp/ip协议 # v01-验证技术 - 验证soc ...

  2. WinServer2008R2远程桌面长时间保持连接

    开始------运行------gpedit.msc 计算机配置------管理模板-----Windows组件-----远程桌面服务------远程桌面会话主机------会话时间限制 修改两项设置 ...

  3. 通俗理解vue路由的导航钩子中关于next()

    1 背景:你乘坐汽车从A景区想赶往B景区(模拟路由A跳转到路由B) 1.next() 你乘坐汽车要从A景区到B景区,路过关卡时,守门人拦下你,你量出了next(),守门人一看没问题,赶紧放行,于是你顺 ...

  4. Linux系统下lz4解压缩命令小结

    lz4是一个让"人见人爱.花见花开"的压缩算法,能够在多核上很好的扩展.lz4在压缩率上略微逊色, 但是在解压速度上有着惊人的优势 (大概是gzip的3倍(多次测试对比)).因为压 ...

  5. 实战build-react(四)一个模块的进化过程

    主框架结构 home/index.js    //模块主文件 创建Topic模块 阶段一  基础代码 import React, { Component } from 'react'; import ...

  6. windows10 下 gcc/g++ 的安装

    一.gcc的下载 网址:www.mingw.org ,点击右上方的 download installer 二.安装 打开安装程序,默认安装,弹出下列界面 找到mingw32-gcc-g++(注意cla ...

  7. 人工智能之基于Opencv与深度学习的计算机视觉实战课程

    https://www.bilibili.com/video/av66375362 imagewatch:https://blog.csdn.net/iracer/article/details/83 ...

  8. mac 下 git log 退出方法

    英文状态下按 Q (大小写无论)即可.

  9. 【商业智能VS人工智能】

    什么是智能? 从感觉到记忆到思维这一过程,称为“智慧”,智慧的结果就产生了行为和语言,将行为和语言的表达过程称为“能力”,两者合称“智能”,将感觉.去记.回忆.思维.语言.行为的整个过程称为智能过程, ...

  10. ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)G GCD Guessing Game

    G: 要你去才Paul的年龄,Paul的年龄在1~n之间,你每猜一个Paul会告诉你,你猜的这个数和他年龄的gcd,问在最坏情况下最少要猜多少次. 题解: 什么是最坏情况,我们直到如果他的年龄是1的话 ...