Postgresql - 备份数据库并在不同所有者上恢复?

Postgresql - backup database and restore on different owner?

我在不同服务器上的数据库上做了备份,它的角色与我需要的不同,使用这个命令:

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 选项,这会阻止 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

以上答案很有帮助,但最终并没有让我 100% 了解我的情况,所以我想我会针对与我有类似情况的人分享上述内容的迭代。

在我的场景中,我可能有不同名称和不同所有者的登台和生产数据库。我可能需要迁移暂存数据库以替换生产数据库,但名称和所有者不同。

或者我可能需要恢复每日备份但出于某种原因更改了名称或所有者。

我们的权限相当简单,因为每个应用程序都有自己的权限 db/user,所以这对需要复杂 user/role/permissions 设置的人没有帮助。

我尝试使用从模板创建的方法来复制数据库,但是如果任何 users/connections 在源数据库上处于活动状态,这将失败,因此这不适用于实时源数据库。

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

我希望我的特定应用用户拥有 db/table,即使他们一开始没有创建数据库的权限。

设置一些变量...

DB_NAME_SRC="app_staging"
DB_NAME_TARGET="app_production"
DB_TARGET_OWNER="app_production_user"
DUMP_FILE="/tmp/$DB_NAME_SRC"

然后backup/restore

# 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 app-specific 用户无论如何都不是本地用户。

如果您正在寻找 heroku。 首先创建一个没有所有者的 sql 转储文件。然后加载到heroku.

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

这里用-O表示无主

使用 .sql 文件而不是 .dump 文件来恢复是个好主意。 (.dump文件需要在下载后上传url)