Postgresql - 备份数据库并恢复不同的所有者?
Posted
技术标签:
【中文标题】Postgresql - 备份数据库并恢复不同的所有者?【英文标题】:Postgresql - backup database and restore on different owner? 【发布时间】:2015-10-06 18:32:29 【问题描述】:我使用以下命令在不同服务器上的数据库上进行了备份,并且该数据库的角色与我需要的不同:
pg_dump -Fc db_name -f db_name.dump
然后我将备份复制到需要恢复数据库的另一台服务器,但没有用于该数据库的所有者。假设数据库有所有者owner1
,但在不同的服务器上我只有owner2
,我需要恢复该数据库并更改所有者。
还原时我在另一台服务器上做了什么:
createdb -p 5433 -T template0 db_name
pg_restore -p 5433 --role=owner2 -d db_name db_name.dump
但是当恢复运行时我得到这些错误:
pg_restore: [archiver (db)] could not execute query: ERROR: role "owner1" does not exist
如何指定它以便它更改所有者?还是不可能?
【问题讨论】:
除了接受答案中建议的--no-owner
,您可能还需要--no-privileges
。见this answer
【参考方案1】:
您应该使用--no-owner
选项,这会阻止pg_restore
尝试将对象的所有权设置为原始所有者。相反,这些对象将由--role
指定的用户拥有
createdb -p 5433 -T template0 db_name
pg_restore -p 5433 --no-owner --role=owner2 -d db_name db_name.dump
pg_restore doc
【讨论】:
pg_dump --no-owner
也应该这样做
我的偏好是将此类决定推迟到恢复。如果您在转储阶段执行此操作,则意味着您无法在不执行导出的情况下改变主意。在还原时执行此操作意味着选项保持打开状态,以防您决定确实应该创建缺少的角色等。
所以如果我想更换所有者,我必须在没有所有者的情况下进行备份?因为我认为我可以在恢复时更改所有者。但是即使将--role
设置为不同的所有者,它仍然试图使用原始所有者(但后来我没有使用--no-owner
。
@Andrius:您不需要更改备份,Gary 的回答应该可以解决您的问题
浏览所有关于这个主题的帖子,他们似乎也忽略了这样一个事实,即这种方法要求新角色所有者是超级用户,至少在恢复期间是这样。然后一切正常【参考方案2】:
上面的答案很有帮助,但最终并没有让我 100% 了解我的情况,所以我想我会为与我自己有类似情况的人分享上面的迭代。
在我的场景中,我可能有具有不同名称和不同所有者的登台和生产数据库。我可能需要迁移临时数据库以替换生产数据库,但名称和所有者不同。
或者我可能需要恢复每日备份,但出于某种原因更改了名称或所有者。
我们的权限相当简单,因为每个应用程序都有自己的数据库/用户,因此这不会帮助具有复杂用户/角色/权限设置的人。
我尝试使用从模板创建方法来复制数据库,但如果源数据库上的任何用户/连接处于活动状态,这将失败,因此这不适用于实时源数据库。
使用基本的--no-owner
还原,还原/新数据库上的数据库/表所有者是执行命令的用户(例如 postgres)...因此您将有一个额外的步骤来修复所有数据库权限。由于我们有一个简单的单个应用程序特定用户每 db 设置,我们可以让事情变得更容易。
我希望我的应用程序特定用户拥有数据库/表,即使他们一开始没有创建数据库的权限。
设置一些变量...
DB_NAME_SRC="app_staging"
DB_NAME_TARGET="app_production"
DB_TARGET_OWNER="app_production_user"
DUMP_FILE="/tmp/$DB_NAME_SRC"
然后做备份/恢复
# backup clean/no-owner
sudo -i -u postgres pg_dump --format custom --clean --no-owner "$DB_NAME_SRC" > "$DUMP_FILE"
# drop target if exists - doesn't work for db with active users/connections
sudo -i -u postgres dropdb -U postgres --if-exists "$DB_NAME_TARGET"
# recreate target db, specifying owner to be the new owner/user (user must already exist in postgres, presumably setup by your app deploy/provisioning)
sudo -i -u postgres createdb -U postgres --owner "$DB_TARGET_OWNER" -T template0 "$DB_NAME_TARGET"
# do the restore to the target db as the target user so any created objects will be owned by our target user.
sudo -i -u postgres pg_restore --host localhost --port 5432 --username "$DB_TARGET_OWNER" --password --dbname "$DB_NAME_TARGET" --no-owner --no-privileges "$DUMP_FILE"
# now in this simple case I don't need an additional step of fixing all the owners/permissions because the db and everything in it will be owned by the specified user.
请注意,在恢复部分中,我使用密码而不是本地连接通过网络连接,因此我不必将 postgres 本地用户身份验证从对等更改为密码。无论如何,我的 db 应用程序特定用户都不是本地用户。
【讨论】:
【参考方案3】:如果您正在寻找heroku。 首先创建一个没有所有者的 sql 转储文件。然后将其加载到heroku。
pg_dump -O target_db -f mydb.sql
heroku pg:psql < mydb.sql
-O 在这里用于 no-owner。
使用 .sql 文件而不是 .dump 文件来恢复是个好主意。 (.dump 文件需要在下载的 url 上上传)
【讨论】:
以上是关于Postgresql - 备份数据库并恢复不同的所有者?的主要内容,如果未能解决你的问题,请参考以下文章