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

pg_rewind时间线修复

作者:杭州美创科技有限公司

pg_rewind是一个用于把一个PostgreSQL数据目录与另一个从该目录中复制出来的数据目录同步,在集簇的时间线分叉以后,同步一个PostgreSQL集簇和同一集簇的另一份拷贝的工具。一种典型的场景是在失效后让一个旧的主服务器重新上线,同时有一个后备机跟随着新的主机。也就是说,在主备不同步后,我们也许不必重建备库以修复流复制环境,使用pg_rewind解决时间分叉就可以修复同步失败的问题。

pg_rewind要求目标服务器在postgresql.conf中启用了wal_log_hints选项,或者在用initdb初始化集簇时启用了数据校验。目前默认情况下这两者都没有被打开。full_page_writes也必须被设置为on,这个是默认的。

以下介绍两个pg_rewind实践方案步骤:

第一部分 回退只读从库

1.1激活从库

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

$ pg_ctl promote -D /pgdata/data

1.2写入从库

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

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

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

从库时间线

$ pg_controldata | grep TimeLineIDLatest checkpoint's TimeLineID:       9Latest checkpoint's PrevTimeLineID:   9

主库时间线

$ pg_controldata | grep TimeLineIDLatest checkpoint's TimeLineID:       8Latest checkpoint's PrevTimeLineID:   8

1.3修复从库

查看切换点

$ ll $PGDATA/pg_wal/*.history

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

$ cat 00000009.history5/5A000060

从00000009000000050000005A开始,所有的wal必须存在从库pg_wal目录中。如果已经覆盖了,必须从归档目录拷贝到从库pg_wal目录中,也可以直接将归档文件全部拷贝到pg_wal目录下

$ cp /mnt/server/archivedir/* /pgdata/data/pg_wal/      #/mnt/server/archivedir/为归档目录

停掉从库

$ pg_ctl stop -m fast -D /pgdata/data

测试修复是否能够成功

$ pg_rewind -n -D /pgdata/data --source-server="hostaddr=192.168.22.128 user=postgres port=5432"pg_rewind: servers diverged at WAL location 5/5A000060 on timeline 8pg_rewind: rewinding from last common checkpoint at 5/59000060 on timeline 8pg_rewind: Done!

可以修复,直接修复

$ pg_rewind -D /pgdata/data --source-server="hostaddr=192.168.22.128 user=postgres port=5432"pg_rewind: servers diverged at WAL location 5/5A000060 on timeline 8pg_rewind: rewinding from last common checkpoint at 5/59000060 on timeline 8pg_rewind: Done!

修改配置文件postgresql.auto.conf

$ vi postgresql.auto.confprimary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=192.168.22.128 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'restore_command = 'cp /mnt/server/archivedir/%f %p'recovery_target_timeline = 'latest'

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

$ mkdir /mnt/server/archivedir/error_tl_9$ mv 00000009* error_tl_9

创建从库标识文件

$ touch /pgdata/data/standby.signal

1.4启动从库

$ pg_ctl start -D /pgdata/data

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

postgres=# select client_addr,sync_state from pg_stat_replication;  client_addr   | sync_state ----------------+------------ 192.168.22.128 | async

第二部分 降级读写主库

2.1激活从库

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

$ pg_ctl promote -D /pgdata/data

2.2写入主、从库

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

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

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

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

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

从库时间线

$ pg_controldata | grep TimeLineIDLatest checkpoint's TimeLineID:       9Latest checkpoint's PrevTimeLineID:   9

主库时间线

$ pg_controldata | grep TimeLineIDLatest checkpoint's TimeLineID:       8Latest checkpoint's PrevTimeLineID:   8

2.3修复老主库

查看切换点

$ ll $PGDATA/pg_wal/*.history

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

$ cat 00000008.history5/37000000

从000000080000000500000037开始,所有的wal必须存在从库pg_wal目录中。如果已经覆盖了,必须从归档目录拷贝到从库pg_wal目录中,也可以直接将归档文件全部拷贝到pg_wal目录下

$ cp /mnt/server/archivedir/* /pgdata/data/pg_wal/      #/mnt/server/archivedir/为归档目录

停掉老主库

$ pg_ctl stop -m fast -D /pgdata/data

测试修复是否能够成功

$ pg_rewind -n -D /pgdata/data --source-server="hostaddr=192.168.22.129 user=postgres port=5432"pg_rewind: servers diverged at WAL location 5/37000000 on timeline 8pg_rewind: rewinding from last common checkpoint at 5/37000000 on timeline 8pg_rewind: Done!

可以修复,直接修复

$ pg_rewind -D /pgdata/data --source-server="hostaddr=192.168.22.129 user=postgres port=5432"pg_rewind: servers diverged at WAL location 5/37000000 on timeline 8pg_rewind: rewinding from last common checkpoint at 5/37000000 on timeline 8pg_rewind: Done!

修改配置文件postgresql.auto.conf

$ vi postgresql.auto.confprimary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=192.168.22.128 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'restore_command = 'cp /mnt/server/archivedir/%f %p'recovery_target_timeline = 'latest'


老主库创建从库标识文件


$ touch /pgdata/data/standby.signal


2.4启动新从库


$ pg_ctl start -D /pgdata/data


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


postgres=# select client_addr,sync_state from pg_stat_replication;
  client_addr   | sync_state 
----------------+------------
 192.168.22.129 | async


注意事项


当使用在线群集作为源执行pg_rewind时,具有充足权限来执行pg_rewind在源群集上使用的函数的角色可以用来代替超级用户。这里介绍如何创建这样的角色,在这里命名rewind_user:


CREATE USER rewind_user LOGIN;
GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;


当使用近期升级的在线群集作为源执行pg_rewind时,必须在升级后执行CHECKPOINT以便其控制文件反映最新的时间线信息,pg_rewind使用这些信息检查目标群集是否可以使用指定的源群集倒回。



规模空前,再创历史 | 2020 PG亚洲大会圆满结束
PG ACE计划的正式发布
三期PostgreSQL国际线上沙龙活动的举办
六期PostgreSQL国内线上沙龙活动的举办

中国PostgreSQL分会与腾讯云战略合作协议签订


PostgreSQL 13.0 正式版发布通告

深度报告:开源协议那些事儿

从“非主流”到“潮流”,开源早已值得拥有

Oracle中国正在进行新一轮裁员,传 N+6 补偿

PostgreSQL与MySQL版权比较

新闻|Babelfish使PostgreSQL直接兼容SQL Server应用程序

四年三冠,PostgreSQL再度荣获“年度数据库”


更多新闻资讯行业动态技术热点,请关注中国PostgreSQL分会官方网站

https://www.postgresqlchina.com

中国PostgreSQL分会生态产品

https://www.pgfans.cn

中国PostgreSQL分会资源下载站

https://www.postgreshub.cn


点赞在看分享收藏

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

评论