天天看点

PostgreSQL 数据文件灾难恢复 - 解析与数据dump

postgresql , 数据文件 , pg_filedump , 安全 , tde

俗话说常在河边站哪有不湿鞋,作为一名战斗在一线的dba或者开发者,可能有遇到过磁盘损坏,磁盘阵列损坏,如果有备份或者备库的话,还好。

如果没有备份,或者没有备库(通常有一些小型或者创业型的企业),那么遇到磁盘损坏或者其他原因(比如掉电文件系统损坏),导致数据库的数据文件并不完整时,如何从有限的资料中找出数据呢?

比如postgresql,如果读到坏块,会报块不可读的错误,这种情况下通过设置zero_damaged_pages=on可以跳过损坏的数据块。

如果连元数据都损坏了,又或者坏了一些磁盘,只有某些表空间被幸免于难,这些情况下你的数据库都已经无法启动时,如何能从有限的数据文件中找回数据呢?

pg_filedump是postgresql社区托管的一个项目,类似于pg_xlogdump,不需要开启数据库,可以直接从数据文件中将数据dump出来。

pg_filedump实际上可以dump 堆表、索引数据文件,控制文件的内容。(从pg_filedump引用的头文件也能看出端倪)

安装很简单

命令帮助如下,通常来说,你只需要指定需要dump的文件即可。

如果文件的块头损坏了,那么你可以手工指定一些信息,包括块大小,段大小,解析哪个块,根据什么格式解析(字段类型列表)等。

1. 创建测试表

2. 插入测试数据

3. 找出表对应的数据文件

4. 调用checkpoint,把数据刷盘,便于我们接下来的观察

5. 使用pg_filedump直接读取数据文件,导出数据

为了得到记录,需要提供一下字段类型list,必须保证与表结构一致

copy得到的就是使用-d提供的类型列表decode拼装的记录。

是不是可以从文件中dump数据了呢?莫急,还要看看掩码哦,否则你不知道这条记录是否为你需要的,因为它可能是dead tuple。

例子

每条记录,头部都有infomask, infomask2掩码,掩码表示的意思,可以参考头文件

比如什么是dead tuple呢?

观察

查看新版本(编号为9345数据块,第86条记录)

对于数据文件的组织形式,可以参考头文件

src/include/storage

每个块内的组织,与对象类型有关,比如堆表,b-tree,hash等索引,toast, fsm等。

可以参考数据layout介绍

<a href="https://www.postgresql.org/docs/9.6/static/storage.html">https://www.postgresql.org/docs/9.6/static/storage.html</a>

也可以参考对应类型的头文件

阅读pg_filedump的源码,也有助于你对postgresql存储构造的理解

不妨仔细阅读以下头文件

我们已经看到,使用pg_filedump可直接decode数据文件的内容,因此泄露数据文件其实是比较危险的。

那么如何防止脱裤呢?tde是一个很好的手段,即数据文件透明加密。你可以参考我末尾的文章。

另外还有加密方法,比如对敏感数据,使用加密字段存储。加解密交给程序完成。彻底杜绝因泄露文件导致的数据泄露。

<a href="https://github.com/digoal/blog/blob/master/201506/20150601_01.md">《postgresql 数据库安全指南》</a>

<a href="https://github.com/digoal/blog/blob/master/201610/20161031_01.md">《postgresql 透明加密(tde,fde) - 块级加密》</a>