做DBA这二十多年里,误删除数据是处理起来最麻烦的事情。早期遇到过一个案例,当时的一个可视化开发工具是把所有代码都保存在一个Oracle数据库里的,而这个数据库放在一台普通的PC机上,并未做任何备份。有一次一不小心,被人把一个用户的数据全删了。这下子这个政府部门的业务系统都跑不起来了。后来我花了几天时间才恢复了大部分数据,凑合让大部分应用都恢复了。
Oracle的各种防误删除的方法已经被国内的第三方服务企业都研究的比较透了,这些年大部分的此类问题,都能够通过一些工具或者特殊的方法实现恢复。不过现在很多企业都在将数据库转移到开源与国产化的环境。在这些新环境下,数据恢复依然是作为刚需存在的。今天我们来简单聊聊PG数据库的误删除恢复问题,因为目前很多国产数据库都与PG同源,或者是基于PG社区版定制的。
防误操作的底线是用备份恢复数据,数据库备份也是数据库运维的底线。如果实在没办法在在线库中恢复数据的时候,使用备份集来恢复数据是十分重要的。可能有朋友会说了,我们有主备库,是不是不需要备份了。这个观点是错误的,主备库只是高可用的方案,不能替代备份。当你误删一张表的时候,备库也会被误删。只有备份才能通过离线恢复来恢复你所需要的所有数据。为了确保备份集的可靠性,至少保留两个全备也是十分必要的。
除了备份之外,我们还可以通过规范一些操作来实现比较方便的误删恢复。与Oracle不同的是,PG的DDL是可以rollback的。在PG数据库中,TRUNCATE、DROP等操作开始的时候,还会保留原有的文件。比如TRUNCATE TABLE的时候,首先会创建一个新文件作为数据存储,原来的文件还保留着。当你执行rollback的时候,原来的数据可以很方便地恢复。不过一旦COMMIT,那么老的数据文件就会被从OS层面删除。
基于此,要想实现PG数据库被DROP/TRUNCATE的数据能够恢复,还需要考虑操作系统的恢复问题。我们在选择文件系统的时候,一定要选择一个可恢复的带日志的文件系统,比如XFS/EXT等。并且要打开并设置好日志。打开文件系统日志,可能会对写操作有一些性能影响,不过对于绝大多数系统来说,这点影响完全是可以接受的,为了确保安全,启用日志十分有必要。
除此之外,我们还要把OS层面的UNDELETE工具准备好,一旦遇到需要恢复数据的事情,立马通过UNDELETE工具恢复被删除的数据文件。一旦数据文件被恢复回来了,那么从文件中导出数据就是十分容易的事情了。目前在GIT上,有大量的开源工具可以用来从PG数据文件中下载数据。因此对于有个企业来说,在部署PG数据库的时候,应该考虑准备好undelete工具,并在有比较靠谱的undelete工具的文件系统上部署PG数据库。
实际上在使用比较复杂的方式恢复数据之前,我们还有更好的解决方法,比如使用psql工具的时候,把自动提交关闭,这样的话在第一时间,我们还可以通过DDL ROLLBACK来实现最简单的恢复。养成好的习惯或者规范化操作行为也是避免出大事的最好的方法。
最后一点,相对于Oracle数据库的段管理的模式,PG的整个元数据相对还是有点绕的。有时候如果我们手头有完整的元数据的历史信息,那么在数据恢复的时候,可以很快的找到需要恢复的文件,从而可以在备份集中快速找到要恢复的数据,并用工具完成快速恢复。因此为了避免恢复数据时过于复杂,定期备份PG的关键元数据也十分重要。