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

Halo数据库pg_rewind使用

原创 Halo Tech 2024-03-18
394

Halo数据库pg_rewind使用

一、pg_rewind 介绍

pg_rewind工具,能够调整并重新对齐一个已经与原始数据目录不同步的副本目录。它在故障后快速恢复复制状态的情况下特别有用,避免了整体数据库备份和恢复所需的更多时间。


二、pg_rewind 参数

pg_rewind 的关键参数包括:

--target-pgdata:指定目标数据库的数据目录。

--source-server:提供当前主数据库的连接信息,格式为连接字符串。

-P 或 --progress:显示进度信息。

例如,命令如下:

pg_rewind --target-pgdata=/data/oldmaster --source-server='host=newmaster port=1921 user=replica password=secret dbname=postgres' -P


、pg_rewind 如何工作

pg_rewind 的工作流程包括以下几个步骤:

1.从源集群和目标集群时间线分叉点之前的最近一个检查点开始,扫描目标集群的 WAL 日志。为了生成目标集群中所有已更改数据块的列表。时间线分叉点是指源集群和目标集群开始出现数据不一致的那个时间点。通过扫描从这个检查点开始到当前的所有 WAL 记录,可以确定哪些数据块在目标集群中已经发生了更改。

2.将所有这些更改的块复制到目标集群。确保了目标集群中的关系文件(数据文件)被更新到与源集群时间线分叉点之前的最后一个完成的检查点相同的状态。此时,目标集群已经包含了源集群所有块更改到分叉点的数据。

3.从源集群拷贝所有其他文件,包括新的关系文件(new relation files)、WAL 段(WAL segments)、事务状态文件(pg_xact)和配置文件(configuration files)。这些文件对于数据库的运行和数据一致性至关重要。通过拷贝这些文件,确保目标集群拥有源集群在故障转移时刻的完整数据和配置。

4.创建一个 backup_label 文件,从故障转移时的检查点开始,重放 WAL 日志并更新 pg_control 文件中的 LSN(Log Sequence Number)信息。这个步骤是为了标记恢复过程的开始点,并确保在接下来的恢复过程中,所有必要的 WAL 记录都会被应用到数据库中,以此来更新数据到最新的状态。

5.应用所有需要的 WAL 日志,使数据库恢复到一致状态。在完成前四步后,最后一步是通过重放剩余的 WAL 日志来完成数据库的恢复。这包括从故障转移时刻开始到最新的所有 WAL 记录。应用这些 WAL 记录确保了数据库中的数据能够反映源集群在最后一刻的状态,从而实现数据的完整性和一致性。


、测试

要测试 pg_rewind,模拟主库故障和恢复的场景:

主备切换步骤:

1. 在主库上操作:

创建一个测试表并插入一条记录: 

-- 在192.168.11.26执行

CREATE EXTENSION aux_oracle CASCADE;
CREATE TABLE t1(id INT, name TEXT);
INSERT INTO t1 VALUES (1, 'p1');


确认备库同步数据:


-- 在192.168.11.27查看

halo0root=# select * from t1;
id | name
----+------
1 | p1
(1 行记录)

2. 提升备库为新主库:

使用 pg_ctl promote 命令将备库 192.168.11.27 提升为主库。

验证提升是否成功并创建复制槽:


-- 在192.168.11.27执行

halo0root=# SELECT pg_is_in_recovery();
pg_is_in_recovery
-------------------
f
(1 行记录)

halo0root=# SELECT pg_create_physical_replication_slot('pg26');
pg_create_physical_replication_slot
-------------------------------------
(pg26,)
(1 行记录)

3. 在原主库和新主库上插入不同记录:

在 192.168.11.26 插入一条记录,并执行一个检查点:

halo0root=# INSERT INTO t1 VALUES (2, 'p26');
INSERT 0 1
halo0root=# CHECKPOINT;
CHECKPOINT

在 192.168.11.27 插入另一条记录,并同样执行检查点:


halo0root=# INSERT INTO t1 VALUES (3, 'p27');
INSERT 0 1

halo0root=# CHECKPOINT;
CHECKPOINT

4. 停止原主库:

在 192.168.11.26 上停止 PostgreSQL 服务以准备 pg_rewind 执行:

pg_ctl stop

5. 执行 pg_rewind 命令:

在 192.168.11.26 上使用 pg_rewind 与新主库同步:

[halo@halo26 halo]$ pg_rewind --target-pgdata=/data/halo --source-server='host=192.168.11.27 port=1921 user=pgrewind password=123456 dbname=halo0root' -P

pg_rewind: 已连接服务器
pg_rewind: 服务器在时间线1上的WAL位置0/379A4A0处发生了分歧
pg_rewind: 从时间线1上0/30211A8处的最后一个普通检查点倒带
pg_rewind: 读取源文件列表
pg_rewind: 读取目标文件列表
pg_rewind: 读取目标中的WAL
pg_rewind: 需要复制 74 MB(整个源目录的大小是 107 MB)
已复制76524/76524 kB (100%)
pg_rewind: 正在创建备份标签并且更新控制文件
pg_rewind: 正在同步目标数据目录
pg_rewind: 完成!

6. 配置原主库为备库:

更新原主库的连接信息以指向新主库,并标记为备库:

vi /data/halo/postgresql.auto.conf
# 更新为新主库的连接信息
primary_conninfo = 'user=replica password=123456 host=192.168.11.27'
primary_slot_name = 'pg26'

在原主库上创建 standby.signal 文件以启用备库模式:

touch /data/halo/standby.signal

7. 重启原主库并验证:

重启 192.168.11.26 并验证是否以备库模式运行:

pg_ctl start

halo0root=# SELECT pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 行记录)

检查 t1 表在两个服务器上是否一致。

halo0root=# select * from t1;

id | name
----+------
1 | p1
3 | p27
(2 行记录)

halo0root=#

总结:主备数据一致,并建立流复制。

8. 原主库执行pg_rewind前后pg_control文件信息变化

执行pg_rewind前:
[halo@halo26 ~]$ pg_controldata /data/halo
pg_control 版本: 1300
Catalog 版本: 202107181
数据库系统标识符: 7345824712687714140
数据库簇状态: 关闭
pg_control 最后修改: 2024年03月14日 星期四 16时53分22秒
最新检查点位置: 0/4000028
最新检查点的 REDO 位置: 0/4000028
最新检查点的重做日志文件: 000000010000000000000004
最新检查点的 TimeLineID: 1

执行pg_rewind后:
[halo@halo26 ~]$ pg_controldata /data/halo
pg_control 版本: 1300
Catalog 版本: 202107181
数据库系统标识符: 7345824712687714140
数据库簇状态: 正在归档恢复
pg_control 最后修改: 2024年03月14日 星期四 16时50分39秒
最新检查点位置: 0/37A5888
最新检查点的 REDO 位置:  0/37A5850
最新检查点的重做日志文件: 000000020000000000000003
最新检查点的 TimeLineID: 2

TimeLineID 每当提升一个备库来成为新的主库时,它会开始一个新的时间线。这是为了确保在故障转移或恢复后,WAL 日志可以正确地继续在新的线性历史中追加。所以原主库运行在时间线 1 ,将一个备库提升为新的主库。这个提升过程实际上是创建了一个新的恢复点,因为新的主库必须开始记录它自己的WAL日志,以便可以接受新的事务。为了区分新旧主库的WAL日志,备库提升后将开始一个新的时间线,也就是时间线 2。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论