有一个 PostgreSQL PITR 系统运行在一个相当大的系统上,有数百个数据库,每个数据库有数百个表,当我们试图从单个数据库或一组数据库恢复单个表时,我们遇到了基于时间限制的问题. PITR 由 Barman 管理。
使用此设置,我们需要恢复整个集群(可能包含数十个数据库),然后提取单个表,然后恢复数据——这可能需要数小时。
从统计上讲,由于涉及的数据库数量和涉及的人员数量,这种情况经常发生,以至于成为一个问题。
是否有更快的解决方案可以为我们提供类似 PITR 的功能?我想过pg_dump
每小时对每个表单独进行一次手动备份,但也许有更好的解决方案?
我假设您已经尝试过“羞辱人们变得更加小心”的方法但没有成功。
我想我会尝试一个数据库内解决方案,比如向表中添加时间戳列并为“软删除”添加列而不是进行硬删除,这样您就可以运行查询将表恢复到以前的状态。如果禁止用户级硬删除不是一个选项,那么您可以保留一些日志表,以允许您制作此类恢复性查询。为此,我广泛使用了这个模块,尽管如果我是从头开始,我可能会考虑像这样更现代的东西。执行此日志记录所需的触发器确实会对任何 DML 操作造成相当大的开销,因此您将评估您是否可以容忍这种情况。
这种方法的一个好处是,您通常可以提出可以修复一个人的错误的查询,而无需在该错误丢失后进行所有更改。当然,如果oopsie的坏数据导致级联错误,因为后面的工作依赖于坏数据,这可能是不可能的。
如果那行不通,也许混合方法是个好主意。您可以每小时保存一次 pg_dump 快照,并将它们保存 12 小时(或您愿意为此目的投入的任何存储量)。如果您很少需要返回超过 12 小时,则改为回退到 PITR 恢复方法。如果你走这条路,你可能想使用 pg_dump 的
-Fc
或-Fd
选项。这样一来,您每小时只需转储一次数据库,但可以在恢复时选择要恢复的表,而不是转储时间。如果你想保持你目前的做法,有很多方法可以让它更快,但这取决于当前的瓶颈是什么。如果瓶颈是在开始恢复之前从存档恢复基本备份,那么您可以只保留一些已经恢复的副本,以便您可以使用预备份快速启动恢复,只需编辑 pg_restore.conf 文件,然后开始。一旦使用过,您就必须将其丢弃并在后台重新创建它,以便下次使用。如果瓶颈是执行 PITR 本身所花费的时间,那么您可以更频繁地进行基础备份并使用最新的备份,该备份足够旧,可用于您所需的恢复时间。这样就可以减少恢复工作。比如每天做一个base backup,但只保留一个从时间开始的,一个从今天开始的,一个从昨天开始的。每次成功完成基本备份后,删除两天前的备份。
您还可以使用“recovery_min_apply_delay”保持滞后的热备用,它总是落后 12 小时左右,但是当您停止该服务器时,更改配置以将其快进到您需要的时间,完成后将其丢弃并重新创建下一次,它可能不会比只保留最近的基本备份快多少,但会增加一些复杂性。