如何使用pgbackups将生产数据库转移到Heroku上的暂存环境?出现错误。

62
在Heroku上,我正在尝试使用pgbackups插件将生产数据库复制到我的暂存应用程序。我按照插件页面上的说明进行操作:https://devcenter.heroku.com/articles/pgbackups 首先,我捕获了数据库:
heroku pgbackups:capture --app production-app 

可以了:

HEROKU_POSTGRESQL_PURPLE (DATABASE_URL)  ----backup--->  b238

Capturing... done
Storing... done

但是当我尝试在暂存应用程序上还原它时:

heroku pgbackups:restore DATABASE `heroku pgbackups:url --app production-app` --remote staging

我收到了以下错误信息:

DATABASE_URL does not match any of your databases
 !    Could not resolve database DATABASE
 !    
 !    Available databases: 

我也尝试输入完整的URL:

 heroku pgbackups:url b238 --app production-app
 heroku pgbackups:restore DATABASE "https://s3.amazonaws.com/..." --remote staging

我也尝试过给应用程序命名(而不是使用--remote staging):

heroku pgbackups:restore DATABASE `heroku pgbackups:url --app production-app` --app staging-app

这些都没有起作用。有趣的是错误信息中说没有“可用数据库”。我猜它指的是暂存应用程序,确实是空的。如果我键入:

heroku pgbackups

我得到:

 !    No backups. Capture one with `heroku pgbackups:capture`.

我需要输入以下命令才能找到可用的备份(生产环境):

heroku pgbackups --app production-app

我得到了当前备份列表,我不知道这是否正常,甚至不知道它是否与问题相关,但我认为我应该提一下。

我已经阅读并尝试了SO上的每一个答案,但都没有起作用。有什么想法吗?

13个回答

100

2017年中期更新(从Takehiro Mouri的答案中借鉴-简化DATABSE_NAME部分)

2015年中期更新...

pgbackups插件已被弃用。不再支持pgbackups:transfer

要将数据库从yourapp复制到yourapp_staging

# turn off the web dynos in staging
heroku maintenance:on -a yourapp-staging

# if you have non-web-dynos, do them too
heroku ps:scale worker=0 -a yourapp-staging

# backup the staging database if you are paranoid like me (optional)
heroku pg:backups capture -a yourapp-staging

# execute the copy
heroku pg:copy your-app::DATABASE_URL DATABASE_URL -a yourapp-staging

完成后,重新开启暂存环境:

# this is if you have workers, change '1' to whatever
heroku ps:scale worker=1 -a yourapp-staging

heroku maintenance:off -a yourapp-staging

(来源:https://devcenter.heroku.com/articles/upgrading-heroku-postgres-databases#upgrade-with-pg-copy-default)


这个新的过程(与从生产环境到暂存环境应用已生成的备份相反)在 heroku pg:copy 过程中是否会对主数据库造成额外的压力? - imderek
1
我的使用情况不足以确定这一点。我在他们的文档中没有看到任何关于此的内容(除了估计每GB数据处理需要3分钟)。考虑到不需要现有备份,你必须假设该过程在大部分复制期间会对源数据库产生读取IO负载。 - Lucas Nelson
1
回答:是的。数据库名称不再像那些颜色,它们有很长的小写单词和数字。 - GreenAsJade
2
@LucasNelson 有没有办法自动化这个过程并按计划运行?我无法在Heroku dyno内部执行此操作,因为那里无法访问heroku CLI! - Eli Rose
它运行得很好,但不幸的是,该过程失败了。我想在它失败时恢复,有其他命令可以继续传输吗? - Giridharan
显示剩余4条评论

29

更新:

你可以运行以下命令将数据库从生产环境转移到暂存环境:

heroku pg:copy your-app::DATABASE_URL DATABASE_URL -a yourapp-staging

它会提示你确认此操作,一旦确认后,所有数据将迁移。


1
这是否意味着数据库结构将与生产环境中的结构相同?换句话说,它只会复制数据还是会从头重新创建数据库、表和字段? - rmagnum2002
看起来它会对所有表和数据进行完整的迁移,首先删除暂存数据库中的所有数据。 - Shadoath

17
这里有一个简单而安全的解决方案,使用Heroku的附加组件和forking。它不需要备份,没有停机时间,并且不会覆盖任何数据库。 首先需要将生产数据库附加到staging应用程序上,然后在staging应用程序上fork。如果您在生产应用程序上fork,然后附加到staging应用程序上,计费应用程序将是生产应用程序,您将无法将fork从中分离出来。 1. 首先找到生产数据库的附加组件名称(这里是postgres-prod-123):
$ heroku addons --app myapp-production
heroku-postgresql (postgresql-prod-123)  standard-0  $50/month
 └─ as DATABASE

2. 接下来attach生产数据库插件到您的暂存应用程序。给它一个名字,比如PRODUCTION_DB,以便更容易识别:

$ heroku addons:attach postgresql-prod-123 --app myapp-staging --as PRODUCTION_DB

3. 接下来在测试应用程序上 创建一个生产数据库的分支

$ heroku addons:create heroku-postgresql:standard-0 --fork PRODUCTION_DB_URL --as STAGING_DB --app myapp-staging

4. 最后,将分支推广为您的暂存应用程序的主要数据库:

$ heroku pg:promote STAGING_DB --app myapp-staging
完成!您的暂存应用现在正在使用生产数据库的副本。请注意,您之前的暂存数据库仍然存在,您可能希望在确保一切正常后销毁它。

要进行清理,请将生产数据库从暂存应用中分离:

$ heroku addons:detach postgresql-prod-123 --app myapp-staging

1
在我看来,最好的方法是这样做。 - MrE
这非常有帮助。看起来现在您也可以在UI中进行Fork(在资源的Heroku数据库页面中)。 - BradByte
1
@BradBumbalough 是的,你可以在用户界面中进行fork操作,但是当我尝试这样做时,它会fork,但是将计费应用程序保留在原始应用程序上,所以那样行不通。大多数步骤都可以在用户界面中完成,但fork步骤似乎需要在CLI中完成。 - MrE
1
分叉(Forking)仅适用于生产级别的服务器。爱好者们,你们要小心了。 - Mirror318

15

根据https://dev59.com/Cm865IYBdhLWcg3wYNZS#U6ugEYcBWogLw_1bRpyU的说法,这会破坏原始数据库,不是吗? - Pahlevi Fikri Auliya
文档没有明确说明它是否会破坏目标数据库中的一些或所有数据。对我来说,它足够快,所以我进行了另一种实现。 - Kevin Davis
这个已经不再适用,请给@lucas-nelson下面的答案点赞。 - borfast

9
这对我有用: heroku pg:copy you-app-production::DATABASE DATABASE -a you-app-staging

4
只需澄清一下,只需要替换 you-app-productionyou-app-staging。 "DATABASE" 不需要替换为任何内容。 - John Pang

6
您可以使用以下命令来实现此操作。
heroku pg:copy <production_app_name>::HEROKU_POSTGRESQL_BLACK_URL OLIVE -a <staging_app_name> --confirm <staging_app_name>

1

要将生产数据库(数据库)复制到暂存数据库(目标数据库),您需要从目标应用程序调用pg:copy,引用一个数据库。

heroku pg:copy source-application::OLIVE HEROKU_POSTGRESQL_PINK -a target-application

另一个例子:

heroku pg:copy my-production-app::HEROKU_POSTGRESQL_OLIVE HEROKU_POSTGRESQL_PINK --app my-staging-app

要获取您数据库的颜色名称,请使用:

heroku pg --app my-production-app
heroku pg --app my-staging-app

查看 pg:copy


1
首先创建一个最新的生产备份:
heroku pgbackups:capture -a productionappslug --expire

了解Heroku为您的数据库命名的颜色。

https://postgres.heroku.com/databaseshttps://dashboard.heroku.com/apps/STAGINGAPPSLUG/resources

然后将生产数据库备份加载到暂存环境中(将RED更改为您的颜色):

heroku pgbackups:restore HEROKU_POSTGRESQL_RED -a stagingappslug `heroku pgbackups:url -a productionappslug`

stagingappslugliveappslug是你的Heroku应用程序的任何简称。


1

我曾经也遇到过同样的问题。根据这个问题的答案,问题可能出在你的heroku gem版本上。我刚刚升级了我的版本(从2.26.2到2.26.6),现在它可以正常工作了。


1
我通过升级数据库成功解决了这个问题。看起来默认的5MB不够用。 - Luciano

0

我认为不是--remote而是--app,请尝试这样做:

heroku pgbackups:restore DATABASE `heroku pgbackups:url --app production-app` --app staging-app

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接