首页 > 数据库 >postgresql流复制三(延迟备库)

postgresql流复制三(延迟备库)

时间:2023-09-01 23:22:50浏览次数:45  
标签:主库 postgresql create delay time 备库 apply 延迟

延迟备库是指可以配置备库和主库的延迟时间,这样备库始终和主库保持指定时间的延迟,例如设置备库和主库之间的延迟时间为1小时 ,理论上备库和主库的延时始终保持在一小时左右。

延迟备库

1 延迟备库的意义

PostgreSQL 流复制环境下,如果主库不是很忙并且备库硬件资源充分,通常备库和主库的延时能在毫秒级别。如果主库上由于误操作删除了表数据或删除表时,从库上的这些数据也瞬间被删除了,这时,即使对数据库做了备份,要恢复到删除前的状态也是有难度的,比如,如果使用 pg_dump 做了逻辑备份,通常是按天、按周、按月进行逻辑备份等,也只能恢复到最近逻辑备份时刻的数据,除非是做了基准备份并且开了归档,这时可以利用全量备份和归档恢复到删除前的状态,从而找回被删除的数据,当然这种方法维护成本较高。在这一场景下,延迟的备库在一定程度上缓解了这一问题,因为在设置的延迟时范围内,备库上的数据还没被删除,可以在备库上找回这些数据,这节将详细介绍延迟备库的配置和使用,当然,如果超过了已设置的主备延迟时间才发现主库上的数据被删除了,这些数据在备库也找不回来了。

2 延迟备库部署

测试环境依然为一主一备异步流复制, host1 主库, host2 为备库,延迟备库的配置非常简单,只需要配置 recovery_min_apply_delay 参数, 参数位于 recovery.conf 配置文件,语法如下:

recovery_min_apply_delay (integer)

此参数单位默认为毫秒,目前支持的时间单位如下:

  • ms (毫秒,默认单位)
  • s (秒)
  • min (分钟)
  • h (小时)
  • d (天)

流复制主库提交事务后,主库会将此事务的 WAL 日志流发送给备库,备库接 WAL 日志流后进行重做,这个操作通常瞬间完成,延迟的备库实际上是设置备库延迟重做 WAL 的时间,而备库依然及时接收主库发送的 WAL 日志流 ,只是不是一接收到 WAL 后就立即重做,而是等待设置的时间再重做,假如设设置此参数为一分钟,流复制备库接收到主库发送 WAL 日志流后需等待一分钟才重做。

我们将 host2 上备库的此参数设置1分钟,如下所示:

recovery_min_apply_delay = 1min

以上代码将主库和备库的延迟时间设置为1分钟,之后重启备库使配置生效, 如下所示:

pg_ctl restart 

之后在主库上创建 test_delay 测试表,如下所示:

postgres=# CREATE TABLE test_delay(id int, create_time timestamp(0) without time zone);
CREATE TABLE

这时备库上等了大概一分钟才看到这张表,接着在主库上插入1条数据,如下所示:

postgres=# INSERT INTO test_delay(id,create_time) VALUES (1,now()) returning create_time;
     create_time
---------------------
 2023-02-09 20:25:58
(1 row)

INSERT 0 1

在备库查询表 test_delay 数据, 刚开始查不到,一分钟后可以查出来

postgres=# SELECT now(),create_time FROM test_delay;
              now              |     create_time
-------------------------------+---------------------
 2023-02-09 20:26:58.085587+08 | 2023-02-09 20:25:58
(1 row)

从以上时间看出正好相差一分钟,也就是说主库插人这条数据后,过了1分钟左右备库才能查询到这条数据。

接着模拟数据误删场景,假如由于误删了这张表数据 ,是否能在备库找回数据?主库上删除这张数据,如下所示:

postgres=# delete from test_delay;
DELETE 1

尽管主库删除了此表数据,但从库该表数据还存在,如下所示:

postgres=# SELECT now(),create_time FROM test_delay;
              now              |     create_time
-------------------------------+---------------------
 2023-02-09 20:28:03.173541+08 | 2023-02-09 20:25:58
(1 row)

这样,可以在延迟时间窗口内将表 test_delay 的表数据进行备份,再导人到主库,从而找回误删除的表。recovery_min_apply_delay 参数设置值过大会使备库的 pg_wal 日志因保留过多的WAL 日志文件而占用较大硬盘空间,因此设置此参数时需要考虑 pg_wal 录可用空间大小,当然,如果设置得太小,留给恢复的时间窗口太短可能起不到 数据恢复的用途。

3 recovery_min_apply_delay 参数对同步复制的影响

recovery_min_apply_delay 参数对同步复制影响如何?大家知道同步复制 synchronous_commit 参数需配置成 on 或者 remote_apply, on 选项意思是主库上提交的事务后会等待备库接收 WAL 日志流并写人 WAL 日志文件后再向客户端返回成功, emote_apply 更进一步,

主库上提交的事务后会等待备库接收 WAL 日志流井写入 WAL 日志文件同时应用完成 WAL 日志流后再向客户端返回成功。

这里对延迟备库场景下 synchronous_commit 配置为 on和remote_apply 的差异进行测试:

场景一: synchronous_commit 配置为 on 和 recovery_min_apply_delay 配置成1分钟

synchronous_ commit 参数调整完后需要执行 pg_ct! reload 重新载人配置使参数生效,同时 recovery_min_apply_delay 置调整后需要重启备库使配置生效。

测试前先在主库上清空表 test_delay 数据,之后在主库上插入一条数据,如下所示:

postgres=# INSERT INTO test_delay(id,create_time) VALUES (1,now()) returning create_time;
     create_time
---------------------
 2023-02-09 20:31:29
(1 row)

INSERT 0 1

之后在备库上查询这条记录,依然需要一分钟之后这条数据才能查询到,如下所示:

postgres=# SELECT now(),create_time FROM test_delay;
              now              |     create_time
-------------------------------+---------------------
 2023-02-09 20:32:31.252722+08 | 2023-02-09 20:31:29
(1 row)

也就是说延迟备库场景, synchronous_commit 配置为 on 时和异步流复制一致。

场景二: synchronous_commit 配置为 remote_apply ,同时 recovery_min_apply_delay 配置成1分钟

主库上执行以下 SQL ,向 test_delay 表中插入一条数据,如下所示:

postgres=# INSERT INTO test_delay(id,create_time) VALUES (1,now()) returning create_time;
--注意这条命令被阻塞

这时发现 SQL 处于阻塞状态,我们把 SQL 计时器打开,看看等了多久,主库上再插入一条数据,如下所示:

postgres=# \timing
Timing is on.
postgres=# INSERT INTO test_delay(id,create_time) VALUES (1,now()) returning create_time;
     create_time
---------------------
 2023-02-09 20:34:22
(1 row)

INSERT 0 1
Time: 60018.038 ms (01:00.018)

以上看出, SQL 执行时间为 60 秒,一条普通的 INSERT 语句需要执行 60 秒的原因,根据 synchronous_commit 参见 remote_apply 选项的解释,因为主库提交 INSERT 语句后,会等待同步备库接收这条 INSERT 语句的 WAL 日志流并且写入备库 WAL 日志文件,同时备库完成应用 WAL 使得这条记录在备库可见后主库才向客户端返回成功,而此时同步备库又设置了 WAL 应用延迟一分钟,了解了这些原理之后,对于以上两个测试场景的差异就很好理解了。

根据以上测试,对于延迟备库场景, synchronous_commit 置为 on 时和异步流复制一致, synchronous_commit 置为 remote_apply 时,主库上所有的写操作将被阻塞一定时间,被阻塞的时间正好是同步备库 recovery_min_apply_delay 参数配置值,因此 synchronous_commit 参数配置为 remote_apply 的同步流复制环境应避免使用延迟备库。

标签:主库,postgresql,create,delay,time,备库,apply,延迟
From: https://www.cnblogs.com/jl1771/p/17673051.html

相关文章

  • postgresql流复制四(查询冲突)
    部署流复制环境后,备库可提供只读操作,通常会将一些执行时间较长的分析任务、统计SQL跑在备库上,从而减轻主库压力,在备库上执行一些长时间SQL时,可能会出现以下错误并被中止:FATAL:terminatingconnectionduetoconflictwithrecoveryDETAIL:Userwasholdingarelation......
  • POSTGRESQL中从MD5到SCRAM-SHA-256
    从v10开始,PostgreSQL提供了scram-sha-256对密码哈希和身份验证的支持。本文介绍了如何安全地调整您的应用程序。为什么我们需要scram-sha-256?PostgreSQL使用哈希加密有两个目的:实际的数据库密码是用户输入的明文密码的哈希值。这可以防止小偷在其他系统上使用偷来的密码。......
  • 【MySQL】MySQL主从复制延迟原因及处理思路
     MySQL主从复制延迟原因及处理思路主库DML请求频繁(TPS较大)主库写请求较多,有大量insert、delete、update并发操作,短时间产生了大量的binlog【原因分析】主库并发写入数据,而从库SQLThread为单线程应用日志,很容易造成relaylog堆积,产生延迟。【解决思路】做sharding,通过s......
  • 通过延迟从库来恢复MySQL数据【转】
    在前面,我们讲了,通过创建一个临时从库,再把数据同步到误操作的前一个事务,来恢复误删除的数据,可以点击跳转。但是临时准备一套从库,会多花费很多时间,那有没有更快的办法呢?这一篇文章,就讲一下通过延迟从库,来恢复误删除的数据。比如平时这个从库都是延迟主库1小时,当主库出现误操作,从......
  • postgresql常用命令
    PostgreSQL是一个强大的开源关系型数据库管理系统,它提供了许多用于管理数据库和执行操作的命令。以下是一些常用的PostgreSQL命令:连接到数据库:psql-hhostname-ddbname-Uusername这个命令用于连接到指定的数据库,需要提供主机名、数据库名和用户名。你可以根据需要修......
  • golang 协程、延迟函数调用、以及恐慌和恢复
    此篇文章将介绍协程和延迟函数调用。协程和延迟函数调用是Go中比较独特的两个特性。恐慌和恢复也将在此篇文章中得到简单介绍。本文并非全面地对这些特性进行介绍,后面的其它文章会陆续补全本文的未介绍的内容。协程(goroutine)现代CPU一般含有多个核,并且一个核可能支持多线程。......
  • Linux安装PostgreSql
    1、准备工作Linux、Centos7、PostgreSql142、安装a>进入PostgreSql下载官网(PostgreSql),选装指定的版本编辑b>依次执行网页中的命令编辑3、设置允许远程连接a>进入data目录[root@localhost~]#cd/var/lib/pgsql/14/datab>修改postgresql.conf文件[root@localhostdata]#vimpo......
  • PostgreSQL-可以通过localhost连接,无法通过IP地址连接。
    (1)如果PostgreSQL配置文件中没有允许访问该服务器的IP地址,则需要先添加允许访问的IP地址,并在防火墙中开放相应的端口。(2)在PostgreSQL配置文件postgresql.conf中,找到以下行:listen_addresses='localhost'将localhost改为*,表示允许任何IP地址访问该服务器。如果只允许特定的IP地址......
  • Postgresql-数据库无法停止,报错:pg_ctl server does not shut down
    根据您的查询,pg_ctlserverdoesnotshutdown(pg_ctl服务无法关闭)的原因可能有很多。以下是一些可能的解决方案和代码示例:(1)杀死所有与PostgreSQL相关的进程:使用以下命令尝试停止所有与PostgreSQL相关的进程:pg_ctl-D/path/to/postgresql/data_directorystop-mimmediate这......
  • PostgreSQL 查找当前数据库的所有表、字段
     查所有表SELECT tablenameFROM pg_tablesWHERE tablenameNOTLIKE'pg%' ANDtablenameNOTLIKE'sql_%'ORDERBY tablename;查看当前表的所有字段SELECT C.relname, A.attnameASNAME, A.attnotnullASNOTNULL, format_type(A.atttyp......