Postgresql -备份数据库和恢复在不同的所有者



我在不同的服务器上备份了数据库,并且该服务器的角色与我需要的不同,使用以下命令:

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医生

上面的答案很有帮助,但最终并没有让我百分之百地了解我的情况,所以我想我应该分享一下上面的迭代,给有类似情况的人。

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

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

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

我尝试使用create from template的方法来复制db,但是如果源db上有任何用户/连接是活动的,那么这就失败了,所以这不适用于实时源db。

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

我希望我的app-specific-user拥有db/tables,即使他们没有创建db的权限。

基本思路是:

  • --no-owner--no-privileges转储源数据库
    • --clean应该不需要,因为我们将恢复到一个新的/空的DB。
  • 删除已经存在的目标数据库。
  • 重新创建目标DB(空),将所有者设置为我们的目标用户(如果不需要创建,则已经存在)。
  • 将转储恢复到空目标作为目标用户
    • --no-owner --no-privileges确保目标用户拥有所有内容,并且没有所有权/privs从我们所做的转储中转移。
    • --no-privileges--no-owner在这里是多余的,因为我们在转储时已经排除了它们。所以在下面的例子中有一些多余的标志,如果你对你的转储是如何产生的有信心的话,你可能不需要这些标志。

请注意,我放弃了任何privs/所有权,因为我每个数据库都有一个用户作为数据库所有者,拥有完整的权利。如果您有更复杂的权限结构,这可能不合适。或者您可以使用单个用户进行恢复,然后让服务器配置系统将任何丢失的角色/权限添加到恢复的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本地用户身份验证从peer更改为password。我的db应用程序特定的用户不是本地用户。

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

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

-O用于此处的no-owner。

使用。sql文件来恢复是一个好主意,而不是。dump文件。(.转储文件需要上传到下载的url)

相关内容

最新更新