ChatGPT解决这个技术问题 Extra ChatGPT

如何将密码传递给 pg_dump?

我正在尝试创建一个 cronjob 来在每晚发生灾难性事件之前备份我的数据库。看起来这个命令应该满足我的需要:

0 3 * * * pg_dump dbname | gzip > ~/backup/db/$(date +%Y-%m-%d).psql.gz

除了运行之后,它希望我输入密码。如果我从 cron 运行它,我不能这样做。我怎样才能自动传递一个?

我写的关于自动化 pg_restore 的可能有用的帖子! medium.com/@trinity/…
在此处使用连接字符串回答:stackoverflow.com/a/29101292/1579667

C
Community

pg_dump 将作为其运行的帐户的主目录中创建一个 .pgpass 文件。

格式为:

hostname:port:database:username:password

然后,将文件的模式设置为 0600。否则,它将被忽略。

chmod 600 ~/.pgpass

有关更多详细信息,请参阅 Postgresql 文档 libpq-pgpass


使用 localhost:5432:mydbname:postgres:mypass 创建 ~/.pgpass 然后 chmod 600 ~/.pgpass
可能有帮助:在 Ubuntu 上,“sudo su postgres”切换到“postgres”用户,然后创建 .pgpass 文件并执行转储。
我按照您的回答,但仍然无法成功创建我的备份文件。请看我的链接:unix.stackexchange.com/questions/257898/…。谢谢你。
适用于 9.6.2 :o)
关于 sudo su postgres 的注意事项:Unix 用户不一定存在。它不需要。但是数据库用户应该。
M
Max

或者您可以设置 crontab 来运行脚本。在该脚本中,您可以像这样设置环境变量:export PGPASSWORD="$put_here_the_password"

这样,如果您有多个需要密码的命令,您可以将它们全部放入脚本中。如果密码更改,您只需在一处(脚本)进行更改。

我同意 Joshua 的观点,使用 pg_dump -Fc 生成最灵活的导出格式并且已经被压缩。有关详细信息,请参阅:pg_dump documentation

例如

# dump the database in custom-format archive
pg_dump -Fc mydb > db.dump

# restore the database
pg_restore -d newdb db.dump

我明白为什么 .pgpass 文件会是更好的解决方案。我只是给出了一个替代方案,但不确定它是否值得一票否决:)
我没有投反对票。那是别人;我也不认为它值得投反对票。有一个+1来弥补它。
这么多的仇敌。我很欣赏这个答案,并将它用于我自己的应用程序。
文档不建议设置 PGPASSWORD 环境变量 (postgresql.org/docs/current/static/libpq-envars.html):出于安全原因,不建议使用此环境变量,因为某些操作系统允许非 root 用户通过 ps 查看进程环境变量;而是考虑使用 ~/.pgpass 文件
这实际上是 docker 容器的首选方式。
g
gitaarik

如果您想在一个命令中执行此操作:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump

文档 (postgresql.org/docs/current/static/libpq-envars.html) 不建议设置 PGPASSWORD 环境变量出于安全原因,不建议使用此环境变量,因为某些操作系统允许非 root 用户通过 ps 查看进程环境变量;而是考虑使用 ~/.pgpass 文件
这仍然是一个有用的评论。有很多部署案例仍然有用。
我总是收到错误“用户“用户名”的对等身份验证失败”。解决方案是:PGPASSWORD="mypass" pg_dump -U username -h localhost > mydb.dump
我的观点是,在已知的未加密位置设置环境变量(您可以控制的位置、密码的存储位置和方式)要好得多。 postgresql doc 的这一部分有问题,这个答案很好。
我的密码中有一个“@”。这行得通。我不知道如何使它与 postgres:// 语法一起工作。没有尝试 .pgpass,因为我的 postgress 用户没有主目录。
J
Josue Alexander Ibarra

对于单行,如迁移数据库,您可以使用 --dbname 后跟连接字符串(包括密码),如 pg_dump manual 中所述

在本质上。

pg_dump --dbname=postgresql://username:password@127.0.0.1:5432/mydatabase

注意:确保使用选项 --dbname 而不是较短的 -d,并使用有效的 URI 前缀 postgresql://postgres://

一般的URI形式是:

postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]

您的案例中的最佳实践(cron 中的重复任务)由于安全问题,不应该这样做。如果不是 .pgpass 文件,我会将连接字符串保存为环境变量。

export MYDB=postgresql://username:password@127.0.0.1:5432/mydatabase

然后在你的 crontab

0 3 * * * pg_dump --dbname=$MYDB | gzip > ~/backup/db/$(date +%Y-%m-%d).psql.gz


Postgre 9.1 版输出 dbname 的未知选项
这分别在 arch 和 RHEL 上使用 9.4 和 9.3 版本进行了测试。你可以发布你的连接字符串吗?当然是匿名的。
谢谢,@JosueIbarra。在 PostgreSQL 9.3、Ubuntu 14.04 上测试成功。
@EntryLevelR 您需要将输出通过管道传输到文件才能保存。看到这个相关的问题askubuntu.com/questions/420981/…
这应该是公认的答案。一个衬里,清晰。
R
Rajan Verma - Aarvy

在创建单个数据库的转储时,这一班轮可以帮助我。

PGPASSWORD="yourpassword" pg_dump -U postgres -h localhost mydb > mydb.pgsql

帮了很多忙...thnxxx
这应该是公认的答案。谢谢!
谢谢。这是唯一适合我的选择。
F
Francisco Luz
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename

很好,但遗憾的是对我不起作用,我得到“查询失败:错误:关系方向查找权限被拒绝”
@Doc您是否尝试过向 pg 用户授予必要的权限?
D
David Buck

您可以使用以下命令直接将密码传递给 pg_dump:

pg_dump "host=localhost port=5432 dbname=mydb user=myuser password=mypass" > mydb_export.sql

欢迎来到堆栈溢出!虽然您的答案可能有效,但它具有严重的安全隐患。命令的参数在 ps(1) 中是可见的,因此如果一个进程监视 ps(1),那么密码就会被泄露。
是的,@JonathanRosa,你是对的。但拉里·斯宾塞刚刚回答了这个问题。因此,例如,如果在 docker 中完成,则安全问题不是问题。
J
Jauyzed

如果 --dbname 未通过,@Josue Alexander Ibarra 答案适用于 centos 7 和 9.5 版。

pg_dump postgresql://username:password@127.0.0.1:5432/mydatabase 

你是对的,这就是它应该看起来的样子,我认为几年前的问题是我的 shell 配置。这就是为什么我必须使用 --dbname
m
mpen

请注意,在 Windows 中,pgpass.conf 文件必须位于以下文件夹中:

%APPDATA%\postgresql\pgpass.conf

如果 %APPDATA% 文件夹中没有 postgresql 文件夹,请创建它。

pgpass.conf 文件内容类似于:

localhost:5432:dbname:dbusername:dbpassword

干杯


m
manfall19

this blog post 中所述,有两种方法可以非交互式地向 PostgreSQL 实用程序(例如“pg_dump”命令)提供密码:使用 ".pgpass" 文件或使用 "PGPASSWORD " 环境变量。


T
Tobias

如果我错了,请纠正我,但如果系统用户与数据库用户相同,PostgreSQL 不会要求输入密码 - 它依赖于系统进行身份验证。这可能是配置问题。

因此,当我希望数据库所有者 postgres 每晚备份他的数据库时,我可以为其创建一个 crontab:crontab -e -u postgres。当然,需要允许 postgres 执行 cron 作业;因此它必须列在 /etc/cron.allow 中,或者 /etc/cron.deny 必须为空。


你就在这里。默认 Postgres 配置对本地系统帐户使用 TRUST 身份验证。然而,大多数生产设置在安装 RDBMS 后立即摆脱了这个块。
S
StartupGuy

使用临时 .pgpass 凭据通过 ssh 备份并推送到 S3:

#!/usr/bin/env bash
cd "$(dirname "$0")"

DB_HOST="*******.*********.us-west-2.rds.amazonaws.com"
DB_USER="*******"
SSH_HOST="my_user@host.my_domain.com"
BUCKET_PATH="bucket_name/backup"

if [ $# -ne 2 ]; then
    echo "Error: 2 arguments required"
    echo "Usage:"
    echo "  my-backup-script.sh <DB-name> <password>"
    echo "  <DB-name> = The name of the DB to backup"
    echo "  <password> = The DB password, which is also used for GPG encryption of the backup file"
    echo "Example:"
    echo "  my-backup-script.sh my_db my_password"
    exit 1
fi

DATABASE=$1
PASSWORD=$2

echo "set remote PG password .."
echo "$DB_HOST:5432:$DATABASE:$DB_USER:$PASSWORD" | ssh "$SSH_HOST" "cat > ~/.pgpass; chmod 0600 ~/.pgpass"
echo "backup over SSH and gzip the backup .."
ssh "$SSH_HOST" "pg_dump -U $DB_USER -h $DB_HOST -C --column-inserts $DATABASE" | gzip > ./tmp.gz
echo "unset remote PG password .."
echo "*********" | ssh "$SSH_HOST" "cat > ~/.pgpass"
echo "encrypt the backup .."
gpg --batch --passphrase "$PASSWORD" --cipher-algo AES256 --compression-algo BZIP2 -co "$DATABASE.sql.gz.gpg" ./tmp.gz

# Backing up to AWS obviously requires having your credentials to be set locally
# EC2 instances can use instance permissions to push files to S3
DATETIME=`date "+%Y%m%d-%H%M%S"`
aws s3 cp ./"$DATABASE.sql.gz.gpg" s3://"$BUCKET_PATH"/"$DATABASE"/db/"$DATETIME".sql.gz.gpg
# s3 is cheap, so don't worry about a little temporary duplication here
# "latest" is always good to have because it makes it easier for dev-ops to use
aws s3 cp ./"$DATABASE.sql.gz.gpg" s3://"$BUCKET_PATH"/"$DATABASE"/db/latest.sql.gz.gpg

echo "local clean-up .."
rm ./tmp.gz
rm "$DATABASE.sql.gz.gpg"

echo "-----------------------"
echo "To decrypt and extract:"
echo "-----------------------"
echo "gpg -d ./$DATABASE.sql.gz.gpg | gunzip > tmp.sql"
echo

只需用您需要的任何内容替换前几行配置行 - 显然。对于那些对 S3 备份部分不感兴趣的人,把它拿出来——很明显。

此脚本随后会删除 .pgpass 中的凭据,因为在某些环境中,默认 SSH 用户可以在没有密码的情况下执行 sudo,例如具有 ubuntu 用户的 EC2 实例,因此使用具有不同主机帐户的 .pgpass 以保护那些凭证,可能毫无意义。


密码将以这种方式登录到终端 history,不是吗?
@mpen 在本地,是的。远程,没有。在我的情况下,可以在我的本地历史记录中拥有它,因为它是一个不允许远程访问的安全 VM。如果在您的情况下不行,请执行 history -c。与 Jenkins 一起使用时,请使用 Inject passwords to the build as environment variables 选项以隐藏密码
o
ognjenkl

对于 Windows,pgpass.conf 文件应存在于路径中:

%APPDATA%\postgresql\pgpass.conf

在我的 Windows 10 绝对路径上,它是:

C:\Users\Ognjen\AppData\Roaming\postgresql\pgpass.conf

Note: 如果 %APPDATA% 中没有 postgresql 文件夹,请在其中创建一个包含 pgpass.conf 文件的文件夹。

pgpass.conf 的内容可能是:

*:5432:*:*:myDbPassword

或者更具体的内容可能是:

localhost:5432:dbName:username:password

Note: pgpass.conf 的内容不能以空格结尾(密码后),否则会发生错误。


s
saintlyzero

传递密码的一种安全方法是将其存储在 .pgpass 文件中

.pgpass 文件的内容将采用以下格式:

db_host:db_port:db_name:db_user:db_pass

#Eg
localhost:5432:db1:admin:tiger
localhost:5432:db2:admin:tiger

现在,将此文件存储在具有权限 u=rw (0600) or less 的用户的主目录中

要查找用户的主目录,请使用 echo $HOME

限制文件 chmod 0600 /home/ubuntu/.pgpass 的权限


m
mpen

在 windows 中,您可以在使用 pg_dump.exe 之前使用密码设置变量,并且可以在 bat 文件中自动执行所有操作,例如:

C:\>SET PGPASSWORD=dbpass
C:\>"folder_where_is_pg_dump\pg_dump.exe" -f "dump_file" -h "db_host" -U db_usr --schema "db_schema" "db_name"

s
stefanoz

您只需要打开 pg_hba.conf 并设置对所有方法的信任。这对我有用。因此安全性为空。


s
szymond

传递密码的另一种(可能不安全)方法是使用输入重定向,即调用

pg_dump [params] < [path to file containing password]


关于安全性——这个文件只需要被预期的用户读取;但是,任何具有 root 权限的人都可以更改安全设置,从而读取未加密的密码。所以是的,这是不安全的......
@Tobias 还有其他选择吗?似乎任何具有 root 权限的人都可以看到密码,无论使用什么技术,除了交互式输入密码(问题是关于 cron 的)。 postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH 提到 GSSAPI 支持单点登录,但没有提及它是否以非交互方式工作。
任何拥有 root 权限的人也可以阅读 .pgpass,这是推荐的方式。因此,我不会认为 root 访问存在安全风险。
D
Dofri

在我看来,最简单的方法是:你编辑你的主 postgres 配置文件:pg_hba.conf 你必须添加以下行:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

在此之后你需要开始你的cron:

pg_dump -h 127.0.0.1 -U <you_db_user> <you_db_name> | gzip > /backup/db/$(date +%Y-%m-%d).psql.gz

它没有密码就可以工作


而你只是破坏了系统安全。可以用于开发盒,但仅此而已。