如何从 Postgres Heroku 上的先前备份中恢复特定数据? (例如,意外删除的行)

Posted

技术标签:

【中文标题】如何从 Postgres Heroku 上的先前备份中恢复特定数据? (例如,意外删除的行)【英文标题】:How to restore specific data from previous backup on Postgres Heroku? (Eg. Accidentally deleted rows) 【发布时间】:2014-11-02 16:25:43 【问题描述】:

情况如下:使用 Heroku 和 Postgres,您可以自动生成备份转储文件。 但是你能用它做什么呢?

    如果您想完全恢复到备份状态,请将其转储到您的数据库中 将其转储到本地以“查看”,或在开发环境中使用生产数据 将数据库的特定行恢复到以前的状态(例如,恢复意外删除的行)

我发现自己对于后一点非常挣扎,我想分享我是如何做到的。

如何从 Postgres Heroku 上的先前备份中恢复特定数据?

【问题讨论】:

【参考方案1】:

总结/TL;DR

只需 3 个步骤,您就可以非常简单地执行:

INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name -- backup_db being remote

首先在本地安装备份,其次获取 SQL 脚本,然后使用 ngrok 向外部世界打开您的 localhost。

我们走吧?

1。在Heroku 上下载您的转储文件并将其转储到某处:

如果您有一些可用的服务器,您可以在远程数据库上执行此操作。但是,如果您像我一样不想在 Heroku 或其他地方配置另一个生产数据库,那么本地完全可以。 我喜欢使用PGAdmin(在Linux、Mac 和Windows 上可用),但也可以使用命令行和psql(通过阅读此post 示例) 在 PGAdmin 中,您可以使用 Create a database。然后右键单击它并使用restore 功能。选择您的转储文件,点击Restore,一切就绪:您的备份数据在本地可用!干得好!

2。从远程数据库访问它

我想做以下事情:

SELECT * FROM backup_db.table_name
-- So I could then do
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name

我会准备好的。超级容易,对吧?很明显?这一定已经做了数百次了。好吧,不!

在 Postgres 9.1+ 中有一个名为 db_link 的实用程序,但它非常受限制,因为适用以下语法:

SELECT fname, lname FROM db_link('host=localhost dbname=backup-28-08', 'SELECT fname, lname FROM users') AS remote (varchar255 fname varchar255 lname)

每个列名都需要重复两次,包括其类型。相当沉重,我们远不是简单的SELECT * FROM backup_db.table_name

所以这里的想法是使用information_schema 表内容,它用列名、类型等描述每个表。我在 SO:Specify dblink column definition list from a local existing type 上发现了这个问题,这对我有很大帮助强>(感谢bentrm)。

但它的解决方案是一个两步过程,首先生成一个函数,然后查询它:

SELECT dblink_star_func('dbname=ben', 'public', 'test');
SELECT * FROM star_test() WHERE data = 'success';

我仍然瞄准 1 班轮。经过一些小小的痛苦(不是 SQL 大师),这里是要点:https://gist.github.com/augnustin/d30973ea8b5bf0067841

我现在可以做:

SELECT * FROM remote_db(NULL::users) -- (Still not 100% about why I need the NULL::)
-- And also
INSERT INTO users
SELECT * FROM remote_db(NULL::users)

太棒了,对吧?

3。远程访问本地主机

如果您的远程数据库已经可以从 Internet 获得(=有一个 IP 地址,一个域名,例如 Heroku,它看起来像:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p您可以跳过这一步。但是,如果您使用本地数据库,则需要使其可从外部世界访问(以便 Heroku 数据库可以访问它)。

为此,我使用精彩的ngrok

安装后我只需要输入以下命令:

ngrok -proto=tcp 5432 #5432 being the default port for Postgresql. (Adapt if necessary)
                                                                                                                                                                                                    
Tunnel Status                 online                                                                                                                                                                
Version                       1.7/1.6                                                                                                                                                               
Forwarding                    tcp://ngrok.com:51727 -> 127.0.0.1:5432                                                                                                                               
Web Interface                 127.0.0.1:4040                                                                                                                                                        
# Conn                        0                                                                                                                                                                     
Avg Conn Time                 0.00ms    

您只需将db_link(在要点中)插入host=ngrock.com port=51727,您就可以开始了

4。更进一步

对此有许多可能的改进。以下是我已经看到的一些:

将脚本视为db_link 函数的默认功能 如果数据库结构在备份和生产中不同,则更加防错 在数据库结果和备份结果之间制作比较工具(仅返回差异行) 处理简单的连接 更进一步的是拥有一个应用程序级适配器(例如 Rails 中的 ActiveRecord),它可以允许操作后端对象而不是像现在这样的原始 SQL

希望我是清楚的!否则请询问更多详情

【讨论】:

我注意到你的 Gist 似乎已经不存在了——你有镜子吗? 回答我自己的问题:aug-riedinger 似乎已将他的 Github 用户名更改为 augnustin,因此新 URL 为 gist.github.com/augnustin/d30973ea8b5bf0067841。 确实如此。很好的收获。

以上是关于如何从 Postgres Heroku 上的先前备份中恢复特定数据? (例如,意外删除的行)的主要内容,如果未能解决你的问题,请参考以下文章