
Global 默认是PG的系统表空间,存储的是共享系统字典表还有控制文件相关信息,此表空间下的文件是整个数据库系统访问控制的核心,一旦损坏数据库访问将会受限,尤其是控制文件受损将会导致系统的不可用,本文通过实际的现场global下文件受损导致数据库不可用案例,来讲述如何重构系统表空间以及控制文件来恢复数据库,从而通过逻辑备份快速导出数据,对以后postgresql 的global下的文件损坏而导致的数据库问题可以尝试使用此方法。
1. 问题的提出
报错信息:

2. 解决思路
无效备份文件:

好消息是数据库可以正常登陆:

2.1. 如何解决问题
1、是否可以尝试别的方式恢复global:有个想法既然global下存储的是共享系统字典表,那么我们是不是就可以通过初始化一个库来重新生成新的global呢?感觉可行,但是这里面有个问题就是需要重建控制文件,ok有思路总比一头雾水强,说干就干.
1):通过物理拷贝的方式备份数据库副本来进行验证操作
2):我通过initdb 初始化一个实例
3):拷贝原备份副本里面的global文件到global_bak
4):拷贝新生成的global表空间目录到原备份副本中
5):尝试重建控制文件
6):尝试拉起数据库
[highgo@localhost highgo]$ ll
总用量 16
drwx------. 21 highgo highgo 4096 12月 25 09:25 9.4 --原数据库数据文件
drwx------. 20 highgo highgo 4096 12月 24 18:06 9.4_bak --备份数据库副本
drwx------. 18 highgo highgo 4096 12月 24 17:27 9.5 --初始化数据库数据文件
[highgo@localhost 9.4_bak]$ ll
总用量 152
drwx------. 7 highgo highgo 4096 12月 24 17:45 base
drwx------. 2 highgo highgo 4096 12月 25 09:26 global --初始化拷贝新global文件
drwx------. 2 highgo highgo 4096 12月 24 18:33 global_bak --原表空间备份副本
drwxr-x---. 2 highgo highgo 4096 12月 24 17:59 hgdb_log
drwx------. 2 highgo highgo 4096 12月 24 18:46 pg_clog
2.2. 计算控制文件信息
1、查看pg_xlog

2、查看pg_clog
-x 参数来自pg_clog

查看pg_multixact
-O参数来自members

-m参数来自offsets

根据以上三个文件的内容我们计算的控制文件信息如下:
pg_resetxlog -l 00000001000000300000003D -x 0x002000000 -m 0x0003,0x0003 -O 0x0006/opt/goldwind/pgdata/data/highgo/9.4_bak -f
2.3. 异常情况
1、 准备好了一切按照我们的设想需要重启库来验证下是否可行。

数据库启动正常,心理安心了不少。

Ok 数据库可以正常访问,心理的一块石头落地了!
2、 高兴的有点早啊,因为发现数据库是正常了,但是我们业务数据库没有想象中一样出现,检查发现数据肯定是存在的。

2.4. 恢复
1、 果然问题并没有想的那么简单,我们忽略了重要的信息,那就是字典表里面有部分对象存储着初始化后新增对象的字典信息,既然这样那么开始尝试查看无效页的对象:

由于对象没有办法确认那么我们只能尝试着去规避这个对象了:
1) 清理此对象涉及的物理文件
2) 拷贝清理后的global所有对象到备份副本下
3) 尝试再次重建控制文件
4) 尝试启动数据库
5) 尝试连接数据库
6) 验证成功后尝试备份数据



3. 实践情况
此文档通过另一种方式恢复了数据库的global表空间,幸运的是没有碰到记录系统对象的表,恢复之后在想如果碰到是类似pg_database数据丢失我们是不是也能通过此方法来处理呢,答案应可以,为什么呢,因为只要知道系统内的数据库信息一样可以人为的补全。
4. 效果评价
此现场没有备份如果恢复不了面临的就是20G生产业务数据的丢失,随时不可估量,但是我们恢复了就说明此方法可行。
5. 推广建议
6. 参考资料
无
――完――





