如何从 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 上的先前备份中恢复特定数据? (例如,意外删除的行)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Heroku 中将 Kafka 连接到 Postgres

如何仅使用 heroku 上的 postgres 转储来恢复我的数据库数据

如何从 Nest.js 连接到 Heroku Postgres?

我的新迁移将破坏我在 heroku (postgres) 上的数据库

如何使用 Python 迁移将 Heroku Django 应用程序的新模型表添加到远程 Heroku Postgres?

无法使用 Heroku postgres 将数据添加到 Spring Boot 上的数据库