plsql查看表空间_最佳实践—PG数据库系统表空间重建

a439182bab05a73fcc70f3ac766c531c.png

马晓亮 中国PG分会认证专家 金风科技DBA,恩墨学院PostgreSQL金牌讲师,从事10余年的数据库相关工作,对通讯信息化、电网安全改造有丰富经验,为公司主要产品的国产化技术转型做了很多工作,未来主要基于开源构建公司相关业务支撑。 【摘要】

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

1. 问题的提出

接到客户现场反馈说业务应用连接数据库异常,提示global目录下对象存在无效的页,通过远程过去查看日志发现确实pg数据库的核心表空间下的对象出问题,详细的跟现场了解下情况,现场反馈说服务器硬盘坏了(服务器有raid 磁盘冗余保护),很难理解怎么会影响上层的业务应用,原来是客户要定期的从服务器上要拷贝生产业务报告(电网内有隔离),当时U盘不可用服务器厂商让客户重启服务器试试,谁知道起不来了,据说服务器厂商让客户又做了拔掉电源等系列匪夷所思的操作后系统能够正常登陆了,但是此时数据库就挂了,从整体的描述来看初步判断是服务器的raid卡出问题了导致系统登录问题以及识别不到U盘。

报错信息:

960769a46aa15d91f39138aa6adc28e3.png

2. 解决思路

根据以上的信息联想到是否可以通过跳过无效的页来解决问题,仔细分析后发现此问题跟我们实际当中碰到的数据页损坏还是有区别的,因为数据页损坏我们跳过数据不访问便是,但是系统表空间下对象信息是一点也不能被忽视,也想过是否可以向oracle那样重建系统表空间呢,可是并找到pg相关重建系统表空间的方法,那怎么办呢? 比较惨的事情远远没有结束,检查备份发现近一年的备份都是无效备份,看来通过备份的方式是没戏了,当时感觉天是黑黑的!

无效备份文件:

77b32c1f1a55767f025a279cc90081be.png

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

eade1a3a7c174510567243efa0d21133.png

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

f814aadfb3e0c6d8b2fab49fe3048a9e.png

按照早期9.2的版本pg_resetxlog –l 参数需要-l timelineid,fileid,seg三个参数现场是9.4的版本 只 需要一 个参数指定下一个事务日志号即可。

2、查看pg_clog   

-x 参数来自pg_clog

c29c58f8d375cc4ac8ac61069b3e3e5b.png

查看pg_multixact

-O参数来自members

8bbbcc627c1be085b7013b0727e33f0a.png

-m参数来自offsets

cf91688cb4ba10442926457aeccb9748.png

根据以上三个文件的内容我们计算的控制文件信息如下:

pg_resetxlog -l 00000001000000300000003D -x 0x002000000 -m 0x0003,0x0003 -O 0x0006 /opt/goldwind/pgdata/data/highgo/9.4_bak  -f

2.3. 异常情况

1、 准备好了一切按照我们的设想需要重启库来验证下是否可行。

90db07f05feb6c2feb0cdb19d534e2c6.png

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

3bff15acb48e51f5e9a44d6792896b85.png

Ok 数据库可以正常访问,心理的一块石头落地了!

2、 高兴的有点早啊,因为发现数据库是正常了,但是我们业务数据库没有想象中一样出现,检查发现数据肯定是存在的。

5617b0a17fcc62d1b35951723faf8ba3.png

2.4. 恢复

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

5f1c2f77316c7ee939d3053ee7d67aca.png

由于对象没有办法确认那么我们只能尝试着去规避这个对象了:

1) 清理此对象涉及的物理文件

2) 拷贝清理后的global所有对象到备份副本下

3) 尝试再次重建控制文件

4) 尝试启动数据库

5) 尝试连接数据库

6) 验证成功后尝试备份数据

645e026cb4fe2728b98359a79b7f2fd9.png

5b448aeec1f17ce0431f482d4389668a.png

3d0299c868843bd3861dd4ca0fff3969.png

3. 实践情况

此文档通过另一种方式恢复了数据库的global表空间,幸运的是没有碰到记录系统对象的表,恢复之后在想如果碰到是类似pg_database数据丢失我们是不是也能通过此方法来处理呢,答案应可以,为什么呢,因为只要知道系统内的数据库信息一样可以人为的补全。

4. 效果评价

此现场没有备份如果恢复不了面临的就是20G生产业务数据的丢失,随时不可估量,但是我们恢复了就说明此方法可行。

5. 推广建议

建议极端情况下可以尝试此方法,一般恢复后建议立即备份。

6. 参考资料

 ――完――

欢迎投稿

        中国开源软件推进联盟PostgreSQL分会,欢迎大家积极投稿,向PGer分享自己的实践经验、心得体会,共建PG中国生态。

投稿邮箱:

partner@postgresqlchina.com

bc5c9724c9f540727b4d943ffda95d31.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值