ITPub博客

首页 > 数据库 > 数据库开发技术 > PostgreSQL时间线修复

PostgreSQL时间线修复

原创 数据库开发技术 作者:sjw1933 时间:2024-05-21 21:46:55 0 删除 编辑
「点击蓝字,关注我吧 」

作者:Digital Observer(施嘉伟)

Oracle ACE Associate: Database

PostgreSQL ACE Partner

11年数据库行业经验,现主要从事数据库服务工作

拥有Oracle OCM、DB2 10.1 Fundamentals、MySQL 8.0 OCP、WebLogic 12c OCA、KCP、PCTP、PCSD、OCI、PolarDB技术专家、达梦师资认证、数据安全咨询高级等认证

ITPUB认证专家、PolarDB开源社区技术顾问

国内某高校企业实践指导教师

公众号:Digital Observer;CSDN:施嘉伟;ITPUB:sjw1933;PGFans:施嘉伟。

在PostgreSQL中,时间线修复通常涉及到pg_rewind工具的使用,它可以在主从切换或故障恢复后,帮助将一个已经激活为主库的从库回退为只读从库,而不需要重建整个从库。这是通过回退那些在故障发生后已经改变的数据块来实现的。接下来我带大家了解如何修复!


说明



01
pg_rewind工具说明

在PostgreSQL的物理流复制中,备用服务器在被激活为主服务器后,可以进行读写操作。通过使用pg_rewind,可以将这个已激活的备用服务器恢复为只读模式的备用服务器,而无需重新初始化备用服务器。在异步复制模式下,如果主备服务器之间发生了角色互换,原主服务器的WAL日志目录可能包含未完全同步到备用服务器的数据。因此,原主服务器不能立即成为新主服务器的备用服务器。此时,pg_rewind可以用来修复原主服务器,将其转换为新主服务器的只读备用服务器,免去了重新初始化备用服务器的需要。


02
环境说明

本次实践是在流复制环境下,主备库都设置开启归档,要使用pg_rewind功能,必须开启full_page_writes,必须开启data_checksums或wal_log_hints。


回退只读从库



01
激活从库

激活只读从库,使从库能够读写

$ pg_ctl promote -D /pgdata/data

02
写入从库

在从库中写入数据,生成wal日志

$ pgbench -M prepared -v -r -P 1 -c 4 -j 4 -T 120 -p 5432
starting vacuum...end.
starting vacuum pgbench_accounts...end.

此时从库和主库已不在同一个时间线上。

从库时间线

$ pg_controldata | grep TimeLineID
Latest checkpoint's TimeLineID: 6
Latest checkpoint'
s PrevTimeLineID: 6

主库时间线

$ pg_controldata | grep TimeLineID
Latest checkpoint's TimeLineID: 5
Latest checkpoint'
s PrevTimeLineID: 5



03
修复从库

查看切换点

$ ll /pgdata/data/pg_wal/*.history


查看最新时间线的.history文件

$ cat 00000006.history
#输出结果:
1 6/44046B00 no recovery target specified
2 6/4C015A18 no recovery target specified
3 A/4C00B160 no recovery target specified
4 A/7000A070 no recovery target specified
5 A/840013A8 no recovery target specifie

查看wal文件名

$ psql -p 5432 -U postgres postgres
postgres=# select pg_walfile_name('A/840013A8');
pg_walfile_name
-------------------------
000000060000000A00000021
(1 row)

从库从000000060000000A00000021开始,所有的wal必须存在从库pg_wal目录中。如果已经覆盖了,必须从归档目录拷贝到从库pg_wal目录中。

$ cp /mnt/server/archivedir/000000060000000A00000021开始之后的WAL文件 /pgdata/data/pg_wal/
主库从000000050000000A00000021开始,所有的wal必须存在主库pg_wal目录中。如果已经覆盖了,必须从归档目录拷贝到主库pg_wal目录中。其中000000050000000A00000021只需把000000060000000A00000021文件名中的00000006改成00000005即可。
$ cp /mnt/server/archivedir/000000050000000A00000021开始之后的WAL文件 /pgdata/data/pg_wal/
关闭从库
$ pg_ctl stop -D /pgdata/data

测试修复是否能够成功

$ pg_rewind -n -D /pgdata/data --source-server="hostaddr=192.168.0.1 user=postgres port=5432"
#输出结果:
pg_rewind: servers diverged at WAL location A/840013A8 on timeline 5
pg_rewind: rewinding from last common checkpoint at A/840012F8 on timeline 5
pg_rewind: Done!

开始修复

$ pg_rewind -D /pgdata/data --source-server="hostaddr=192.168.0.1 user=postgres port=5432"

修复完成后修改配置文件postgresql.auto.conf

$ vi /pgdata/data/postgresql.auto.conf
primary_conninfo = 'host=192.168.0.1 port=5432 user=repl password=repl@321'

删除错误时间线上产生的归档,即走到时间线00000006上的归档

$ mkdir -p /mnt/server/archivedir/error_tl_6
$ mv /mnt/server/archivedir/00000006* /mnt/server/archivedir/error_tl_6

创建从库标识文件

$ touch /pgdata/data/standby.signal



04
启动从库
$ pg_ctl start -D /pgdata/data

在主库上查看流复制同步状态

$ psql -p 5432 -U postgres postgres
postgres=# select * from pg_stat_replication;

降级读写主库



01
激活从库


激活只读从库,使从库能够读写

$ pg_ctl promote -D /pgdata/data

02
写入主、从库

在从库中写入数据,生成wal日志

$ pgbench -M prepared -v -r -P 1 -c 4 -j 4 -T 120 -p 5432

starting vacuum...end.

starting vacuum pgbench_accounts...end.

在主库中写入数据,生成wal日志

$ pgbench -M prepared -v -r -P 1 -c 4 -j 4 -T 120 -p 5432

starting vacuum...end.

starting vacuum pgbench_accounts...end.

此时从库和主库已不在同一个时间线上。

从库时间线

$ pg_controldata | grep TimeLineID

Latest checkpoint's TimeLineID: 6

Latest checkpoint'
s PrevTimeLineID: 6

主库时间线

$ pg_controldata | grep TimeLineID

Latest checkpoint's TimeLineID: 5

Latest checkpoint'
s PrevTimeLineID: 5

03
修复老主库

在从库查看切换点

$ ll /pgdata/data/pg_wal/*.history

在从库查看最新时间线的.history文件

$ cat 00000006.history

1 6/44046B00 no recovery target specified

2 6/4C015A18 no recovery target specified

3 A/4C00B160 no recovery target specified

4 A/7000A070 no recovery target specified

5 A/880012D0 no recovery target specified

在从库查看wal文件名

$ psql -p 5432 -U postgres postgres

postgres=# select pg_walfile_name('A/880012D0');

pg_walfile_name

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

000000060000000A00000022

(1 row)

从库从000000060000000A00000022开始,所有的wal必须存在从库pg_wal目录中。如果已经覆盖了,必须从归档目录拷贝到从库pg_wal目录中。

$ cp /mnt/server/archivedir/000000060000000A00000022开始之后的WAL文件 /pgdata/data/pg_wal/

老主库从000000050000000A00000022开始,所有的wal必须存在老主库pg_wal目录中。如果已经覆盖了,必须从归档目录拷贝到老主库pg_wal目录中。其中000000050000000A00000022只需把000000060000000A00000022文件名中的00000006改成00000005即可。

$ cp /mnt/server/archivedir/000000050000000A00000022开始之后的WAL文件 /pgdata/data/pg_wal/

关闭老主库

$ pg_ctl stop -D /pgdata/data

测试修复是否能够成功

$ pg_rewind -n -D /pgdata/data --source-server="hostaddr=192.168.0.2 user=postgres port=5432"

输出结果:

pg_rewind: servers diverged at WAL location A/880012D0 on timeline 5

pg_rewind: rewinding from last common checkpoint at A/88000060 on timeline 5

pg_rewind: Done!

开始修复

$ pg_rewind -D /pgdata/data --source-server="hostaddr=192.168.0.2 user=postgres port=5432"

修复完成后修改配置文件postgresql.auto.conf

$ vi /pgdata/data/postgresql.auto.conf

primary_conninfo = 'host=192.168.0.2 port=5432 user=repl password=repl@321'

老主库创建从库标识文件

$ touch /pgdata/data/standby.signal

04
启动新从库


$ pg_ctl start -D /pgdata/data

在新主库上查看流复制同步状态

$ psql -p 5432 -U postgres postgres
postgres=# select * from pg_stat_replication;

总结

在PostgreSQL的时间线修复过程中,pg_rewind是一项至关重要的工具。它允许数据库管理员在主从切换后,无需重建整个从库即可将其恢复为只读状态。这一过程要求对PostgreSQL的工作原理有深入的理解,并且需要确保所有相关的WAL日志都得到妥善保管。经验告诉我们,细节决定成败,因此在执行pg_rewind之前,务必仔细检查配置设置,并验证所有必要的WAL日志都在适当的位置。这样做可以确保时间线修复的过程既高效又无缝。



END


往期推荐:





PostgreSQL数据危机——恢复指南


如何处置PostgreSQL WAL日志膨胀


什么?PGSQL执行突然变慢


分类分级在Oracle 23ai中的应用


高可用性对决:Oracle & SQL Server




在看点这里

点击"阅读原文"


原文作者:Digital Observer;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论
11年数据库行业经验,Oracle ACE、PG ACE、OCM、IBM Certified DBA、MySQL OCP、PolarDB技术专家、KCP、PCTP、PCSD、达梦师资认证、PolarDB开源社区技术顾问、ITPUB认证专家、某高校外聘教师

注册时间:2019-05-05

  • 博文量
    295
  • 访问量
    300730