【发布时间】:2011-04-13 13:14:38
【问题描述】:
我经常需要克隆生产数据来调查错误。即使数据库大小很小,heroku db:pull (taps) 也需要 5 分钟以上,而且似乎很有可能失败。 有没有其他方法可以拉取数据库?
另外的流程/文章的库也将不胜感激。
【问题讨论】:
标签: ruby-on-rails heroku
我经常需要克隆生产数据来调查错误。即使数据库大小很小,heroku db:pull (taps) 也需要 5 分钟以上,而且似乎很有可能失败。 有没有其他方法可以拉取数据库?
另外的流程/文章的库也将不胜感激。
【问题讨论】:
标签: ruby-on-rails heroku
查看pgbackups。它已经取代了 Heroku bundle 命令,并且会给你一个相当于 mysqldump 的 postgres。对于大型数据集,这比 Taps 文明得多。
heroku pgbackups:capture
将创建一个转储文件并存储它。要下载转储文件,您需要获得的 url
heroku pgbackups:url b001 (or whatever the id number of the backup is)
这将返回一个 URL,您可以从中下载转储。如果您愿意,可以将其粘贴到 Firefox 中,或者按照他们的建议使用 curl/wget。正如他们在文档中所说,使用 pg_restore 将转储文件加载到您的数据库中:
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U test_user -d myapp_development /home/mike/Downloads/b001.dump
pg_restore:连接数据库进行恢复
【讨论】:
我创建了一个自动执行此过程的 shell 脚本(基于 Mike Williamson 的回答)。
https://gist.github.com/921535
#!/bin/bash
# Best use case is to create a file "update_local_db.sh" in your project folder and then
# call the command with bash update_local_db
# Follow me: @jackkinsella
function LastBackupName () {
heroku pgbackups | tail -n 1 | cut -d"|" -f 1
}
# This part assumes you have a low limit on no. of backups allowed
old_backup=$(LastBackupName)
heroku pgbackups:destroy $old_backup
heroku pgbackups:capture
new_backup=$(LastBackupName)
curl $(heroku pgbackups:url $new_backup) > temporary_backup.dump
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U REPLACE_WITH_YOUR_USER -d REPLACE_WITH_YOUR_DB_NAME temporary_backup.dump
rm -f temporary_backup.dump
【讨论】:
这篇文章现在很老了。
目前最新最简单的方法是使用 Heroku 的 pg:pull/pg:push
【讨论】:
pg:pull 比下载数据库转储和导入要慢得多。
Jack's 脚本的更新,Heroku's recommendation 截至 2015 年 1 月。
第一部分是由于在不同的计算机上运行,因此我的 Postgres dbs 有不同的名称。
#!/bin/bash
# Run the following command: bash update_local_db.sh
# Getting computer name, which is the same as username in Postgres db
echo "Please enter name of Computer"
read input_variable
echo "You entered: $input_variable"
# Make a backup on Heroku
heroku pgbackups:capture --app APP_NAME
echo "== Created a new backup =="
# Download the backup and name it latest.dump
curl -o latest.dump `heroku pgbackups:url --app APP_NAME`
echo "== Downloaded the backup =="
# Restore local db with latest.dump
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U $input_variable -d my_db_name latest.dump
echo "== Replaced db with downloaded =="
# Delete downloaded db latest.dump
rm -f latest.dump
echo "== Deleted downloaded db =="
echo "== Done! :) =="
【讨论】:
这是我编写的一个脚本,它利用 pg:pull(如 Lomefin 所述)从 Heroku 中拉下一个数据库并用它替换一个本地数据库:
#!/bin/bash
export MAIN_DB=NAME_OF_LOCAL_DB
export TMP_DB=NAME_OF_TEMPORARY_DB
function delete_db () {
psql -d ${1} -c "SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '$1'
AND pid <> pg_backend_pid();" || true
dropdb ${1} || true
}
delete_db ${TMP_DB}
heroku pg:pull DATABASE_URL ${TMP_DB} || exit 1
delete_db ${MAIN_DB}
psql -c "ALTER DATABASE $TMP_DB RENAME TO $MAIN_DB;"
由于pg:pull 克隆到新数据库,您的工作不会中断(仅在重命名数据库后,这需要几分之一秒)。当然,可以根据自己的喜好轻松自定义脚本。
【讨论】: