后备数据库和恢复不同的所有者?

我对不同服务器上的数据库进行了备份,它的作用与我需要的不同,使用以下命令:

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

我如何指定它,以便它将改变所有者? 或者这是不可能的吗?

97549 次浏览

您应该使用 --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

还原文档

上面的答案是有帮助的,但最终没有让我100% 为我的情况下,所以我想我会分享一个迭代上面的人与我相似的情况。

在我的场景中,我可能有具有不同名称和不同所有者的分段和生产数据库。我可能需要迁移暂存数据库来替换生产数据库,但是要使用不同的名称和不同的所有者。

或者,也许我需要恢复每日备份,但由于某种原因更改了名称或所有者。

我们的权限相当简单,因为每个应用程序都有自己的 db/user,所以这不会帮助复杂的用户/角色/权限设置的人。

我尝试使用 create from template 方法来复制 db,但是如果源 db 上有任何用户/连接处于活动状态,这种方法就会失败,因此这种方法不适用于活动源 dbs。

对于基本的 --no-owner恢复,恢复/新数据库上的 db/表所有者是执行命令的用户(例如 postgres) ... ... 因此您将需要额外的步骤来修复所有的 db 权限。因为我们有一个单独的应用程序特定用户/db 设置,所以我们可以使事情变得更简单。

我希望我的应用程序特定用户拥有 db/tables,即使他们首先没有创建 db 的权限。

基本思想是:

  • --no-owner--no-privileges转储源数据库
    • 不需要 --clean,因为我们将恢复到一个新的/空的数据库。
  • 如果目标数据库已经存在,则删除它。
  • 重新创建目标 DB (空) ,将所有者设置为目标用户(已经存在,如果不需要创建)。
  • 将转储恢复到空目标 < em > 作为目标用户
    • --no-owner --no-privileges确保目标用户拥有所有内容,并且不会从我们创建的转储中继承任何所有权/权限。
    • --no-privileges--no-owner在这里是多余的,因为我们在抛售时已经排除了它们。因此,在下面的示例中有一些多余的标志,如果您对转储是如何产生的有信心,则可能不需要这些标志。

注意,我正在放弃任何权限/所有权,因为每个 db 只有一个用户,这个 db 所有者拥有完整的权限。如果您有更复杂的权限结构,这可能不合适。或者,您可以使用单个用户进行恢复,然后让服务器配置系统向恢复的 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 --no-privileges "$DB_NAME_SRC" > "$DUMP_FILE"


# THE FOLLOWING HAPPENS ON THE PG box where you want to restore


# 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 target user/role
# DB_TARGET_OWNER must already exist in postgres or you need to create it
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 target user.

请注意,在还原部分中,我使用密码而不是本地密码通过网络连接,因此不必将 postgres 本地用户身份验证从对等密码更改为密码。我的数据库应用程序特定用户不是本地用户。

如果你在找 Heroku。 首先创建一个没有所有者的 sql 转储文件,然后将其加载到 heroku。

pg_dump -O target_db -f mydb.sql
heroku pg:psql < mydb.sql

O 在这里是无主人的意思。

吸毒。还原 sql 文件是一个好主意,而不是。转储文件。(.转储文件需要上传到一个下载的网址)