我正在处理一个应用程序工作流,其中一个用户操作将触发数据库中的复杂更改-在某些表中创建数百条记录,在其他表中更新数百条记录,等等总共,此动作触及了大约12张桌子(约100张桌子)。由于复杂性,在运行另一个测试之前,我很难手动还原所有更改。在开发的大部分时间里,我可以简单地在工作流的末尾插入“ ROLLBACK”语句,但是当我即将提交更改时,我需要测试真实的东西。
我具有要使用的生产数据库的本地副本。就我而言,测试之间的转储和还原比编写脚本撤消所有更改要快。它的速度更快,但仍然让我放慢了速度(在老化的笔记本电脑上,还原大约需要20分钟)。有什么方法可以保存数据库当前状态的快照,然后快速还原它?
我保证是系统上唯一的用户,并且我具有root访问权限。 tar和gzip压缩后,数据库转储约为100MB。 PostgreSQL版本是8.3。
感谢您提供任何有用的想法。
#1 楼
您可以使用文件系统级快照,但这通常很麻烦,需要特殊的文件系统,并且并不总是可用,尤其是在老化的笔记本电脑上。 ;-)如何使用
CREATE DATABASE ... TEMPLATE
功能将基本状态创建为数据库,然后从中创建一个新数据库进行测试运行。测试后,您将该数据库扔掉了。那么,您的速度限制实际上仅是进入数据库目录的时间。这与没有文件系统快照魔术一样快。评论
那是个好主意。我根本没有想到数据库模板。谢谢!
–Zilk
2011年6月22日22:38
这是一个很棒的解决方案,比drop-restore快5倍,但有一个缺点:您需要先删除当前连接,然后再执行此操作,否则它将无法运行。
–索林
13-10-8在14:04
更新:这将无法在生产环境中使用,因为源数据库将与其建立连接。我们需要另一个解决方案。
–索林
2014年4月4日21:51
#2 楼
使用Stellar,就像对数据库使用git一样:Stellar允许您在例如编写数据库迁移,切换分支或使用SQL混乱时快速恢复数据库。 >支持PostgreSQL和MySQL(部分)。
评论
或liquibase.org
–大卫·波塔贝拉(David Portabella)
16年6月12日在17:12
liquibase不像Stellar那样支持它,您可能在其中使用数据库(例如在单元测试中),并且可能必须回滚到以前的某些标记状态或时间。
– Andreas Covidiot
18年1月16日在9:15
恒星听起来像个好主意,但对我不起作用
–奥兰多
18年5月2日在19:46
#3 楼
如果您的数据库在Virtualbox中运行,则您可以轻松地保存快照,并在几秒钟(或1-2分钟,如果您确实在数据库或操作系统中拥有大量数据,或者非常少)恢复数据库状态和操作系统本身的快照在大多数情况下,最好安装一个轻量级的linux(而不是Windows服务器)来运行托管数据库的虚拟机。提起您,您的笔记本电脑上几乎没有可用的资源。
在生产站点上,我使用MediaTemple的快照备份来达到相同的结果(但每个备份插槽20美元,具体取决于该网络托管服务,因此可能不适合您)。
评论
没关系,我没有看到您的评论提到您已经对virtualbox有所了解。
–狂话
2011年7月1日在12:48
#4 楼
也许不是您想要的答案,但是您是否考虑过较低级别的快照-例如LVM?
评论
是的,确实想到了。不幸的是,我当前正在使用的FS(ext3)不支持文件系统快照。另一个选择是为测试运行设置虚拟机(如Virtualbox)。
–Zilk
11年6月22日在22:37
#5 楼
尝试执行相同操作时发现了此问题,并最终在postgresql数据目录上使用了git。放弃更改很容易:git reset --hard
评论
这对于大型数据库没有用。另外,为什么要用大小不同的二进制文件拷打git?
– RolandoMySQLDBA
16-4-22在17:14
#6 楼
尽管我不得不说Stellar
和git reset --hard
是一个有趣的解决方案,但是对于较大的数据库和测试,我会遇到问题,并且我会使用Virtualbox
等解决方案。但是,在更大的测试中,这些解决方案变得更加“有问题“当您使用裸机等解决方案时。由于@Peter Eisentraut也提到了以下原因,因此我不得不提及
ZFS
作为将来要考虑的文件系统:<快照-特别是当您从Prod复制到QA / DR时,可以使用相同的“文件系统”进行测试:
#On a replication node, rather stop, snap, restore for a "consistent" backup ;)
su -l -c "/usr/bin/m2ee stop" acw_qa
pg_ctlcluster ${=QA} stop --force
zfs destroy -R $SNAPSHOT
pg_ctlcluster ${=REPLICATION} stop --force
zfs snapshot $SNAPSHOT
pg_ctlcluster ${=REPLICATION} start
zfs destroy $CLONE
zfs clone -o mountpoint=$CLONEDIR $SNAPSHOT $CLONE
rm $CLONEDIR/$CLUSTER/recovery.conf
pg_ctlcluster ${=QA} start
su -l -c "/usr/bin/m2ee start" acw_qa
做一个测试,就在测试之前按照上面的步骤停止一个postgresql,
zfs snapshot $SNAPSHOT
启动postgresql,然后回滚,停止postgresql,然后zfs rollback $SNAPSHOT
压缩-Postgresql得到典型的3:1压缩在我的数据库中,因此您可以做更多的测试;)
#7 楼
可以尝试的另一种选择是实际保存postgresql数据目录的副本,然后在要还原时使用该副本重写现有目录。它将需要更多的磁盘空间,但是肯定比从备份还原要快。我不确定这是否比模板方法要快,所以首先进行一些测试是个好主意。评论
如果仅在服务器运行时从目录中复制数据文件,那么是否存在正在进行DB写操作进行备份的危险?还是这种方法假设您在执行备份或还原之前已关闭Postgresql?
–亚当·帕金(Adam Parkin)
20年1月28日在21:44
假设Postgresql在操作过程中被关闭了。
– Haroldo_OK
20年1月29日在10:24
评论
您说您有数据库转储,这还不够吗?测试您的系统,如果异常错误,请使用转储将数据库恢复到原始状态并继续开发。您是否仅还原已更改的表?
@Jack Douglas:我正在从转储中恢复整个数据库。有问题的表约占数据的2/3,我仍然要担心正确的还原顺序和外键约束。
@DrColossus:是的,转储足以恢复以前的状态,但是创建和应用它们非常慢。