Как передать пароль в pg_dump?

218

Я пытаюсь создать cronjob для резервного копирования моей базы данных каждую ночь, прежде чем произойдет что-то катастрофическое. Похоже, эта команда должна соответствовать моим потребностям:

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

За исключением этого, он ожидает, что я наберу пароль. Я не могу этого сделать, если я запустил его из cron. Как я могу передать его автоматически?

  • 0
    возможно полезный пост я написал об автоматизации pg_restore! medium.com/@trinity/...
Теги:
crontab

12 ответов

232
Лучший ответ

Создайте файл .pgpass в домашнем каталоге учетной записи, под которой будет запускаться pg_dump. См. Документацию Postgresql libpq-pgpass для получения подробной информации о формате (включая последний абзац, где объясняется, что он будет игнорироваться, если вы не установите режим в 0600).

  • 79
    Создайте ~ / .pgpass с localhost: 5432: mydbname: postgres: mypass Затем chmod 600 ~ / .pgpass
  • 5
    Возможно, полезно: в Ubuntu «sudo su postgres» переключиться на пользователя «postgres», затем создать файл .pgpass и выполнить дамп.
Показать ещё 5 комментариев
173

Или вы можете настроить crontab для запуска script. Внутри script вы можете установить переменную среды следующим образом: export PGPASSWORD="$put_here_the_password"

Таким образом, если у вас есть несколько команд, для которых потребуется пароль, вы можете поместить их все в script. Если пароль меняется, вам нужно изменить его только в одном месте (script).

И я согласен с Джошуа, используя pg_dump -Fc создает наиболее гибкий формат экспорта и уже сжимается. Для получения дополнительной информации см.: документация pg_dump

например.

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

# restore the database
pg_restore -d newdb db.dump
  • 3
    это не идеально. бросив его в .pgpass вы сохраните все в одном месте, без добавления дополнительного слоя косвенности. плюс, если бы все, что я хотел сделать с экспортом переменной, я сделал бы это в своем файле .bashrc , или где бы то ни было.
  • 9
    Я понимаю, почему файл .pgpass будет лучшим решением. Я просто давал альтернативу, не уверен, что она заслуживает понижения, хотя :)
Показать ещё 9 комментариев
126

Если вы хотите сделать это с помощью одной команды:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump
  • 18
    Установка переменной среды PGPASSWORD не рекомендуется в документации ( postgresql.org/docs/current/static/libpq-envars.html ): использование этой переменной среды не рекомендуется по соображениям безопасности, поскольку некоторые операционные системы допускают пользователи root могут видеть переменные среды процесса через ps; вместо этого рассмотрите возможность использования файла ~ / .pgpass
  • 8
    Это все еще полезный комментарий. Есть много случаев развертывания, где это все еще полезно.
Показать ещё 3 комментария
95

Для однострочного интерфейса, например, для миграции базы данных, вы можете использовать --dbname, за которой следует строка подключения (включая пароль), как указано в pg_dump manual

В сущности.

pg_dump --dbname=postgresql://username:[email protected]:5432/mydatabase

Примечание. Убедитесь, что вы используете опцию --dbname вместо более короткой -d и используйте допустимый префикс URI, postgresql:// или postgres://.

Общая форма URI:

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

Лучшая практика в вашем случае (повторяющаяся задача в cron), это не должно быть сделано из-за проблем с безопасностью. Если бы не файл .pgpass, я бы сохранил строку подключения как переменную среды.

export MYDB=postgresql://username:[email protected]:5432/mydatabase

то в вашем crontab

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

  • 0
    Версия 9.1 Postgre выводит неизвестную опцию для dbname
  • 0
    Это было проверено с версиями 9.4 и 9.3 на арке и RHEL соответственно. Вы можете опубликовать свою строку подключения? анонимно конечно.
Показать ещё 10 комментариев
40
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename
  • 0
    Хорошо, но, к сожалению, не работает для меня, я получаю "запрос не выполнен: ОШИБКА: разрешение отклонено для отношения direction_lookup"
  • 0
    @ Док вы пытались дать необходимые разрешения пользователю pg?
12

@Josue Александр Ибарра отвечает на работы centos 7 и версии 9.5 если --dbname не передается.

pg_dump postgresql://username:[email protected]:5432/mydatabase 
  • 0
    Вы правы, вот как это должно выглядеть, я думаю, что несколько лет назад было ошибкой конфигурация моей оболочки. Вот почему мне было важно использовать --dbname
4

Исправьте меня, если я ошибаюсь, но если системный пользователь совпадает с пользователем базы данных, PostgreSQL не будет запрашивать пароль - он полагается на систему для аутентификации. Это может быть вопросом конфигурации.

Таким образом, когда я хотел, чтобы владелец базы данных postgres резервировал свои базы данных каждую ночь, я мог бы создать для него crontab: crontab -e -u postgres. Конечно, postgres должно быть разрешено выполнять задания cron; поэтому он должен быть указан в /etc/cron.allow, или /etc/cron.deny должен быть пустым.

  • 0
    Вы вроде как здесь. Конфигурация Postgres по умолчанию использует аутентификацию TRUST для локальных системных учетных записей. Однако большинство производственных установок избавляются от этого блока сразу после установки СУБД.
2

Сделайте резервную копию через ssh с паролем, используя временные учетные данные.pgpass и отправьте на S3:

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

DB_HOST="*******.*********.us-west-2.rds.amazonaws.com"
DB_USER="*******"
SSH_HOST="[email protected]_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 без пароля, например, экземпляр EC2 с пользователем ubuntu, поэтому для защиты этих учетных данных используется .pgpass с другой учетной записью хоста, может быть бессмысленным.

  • 0
    Протестировано и работает с PG 9.6
  • 0
    Таким образом, пароль будет зарегистрирован в history терминала, не так ли?
Показать ещё 1 комментарий
0

Как подробно описано в этом сообщении, есть два способа неинтерактивно предоставлять пароль для утилит PostgreSQL, таких как команда "pg_dump": с помощью файла ".pgpass" или с помощью переменной среды "PGPASSWORD".

0

Этот лайнер помогает мне при создании дампа одной базы данных.

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

Другой (возможно, не безопасный) способ передачи пароля - использование перенаправления ввода, то есть вызов

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

  • 0
    Что касается безопасности - этот файл должен быть доступен для чтения только предполагаемым пользователям; однако любой пользователь с правами root сможет изменить настройки безопасности и, следовательно, прочитать незашифрованный пароль. Так что да, это небезопасно ...
  • 3
    @Tobias есть ли альтернатива? Казалось бы, любой пользователь с правами root всегда может увидеть пароль независимо от того, какой метод, кроме как ввод пароля в интерактивном режиме (а вопрос о cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH упоминает GSSAPI, поддерживающий единый вход, но не упоминает, работает ли он не в интерактивном режиме.
Показать ещё 1 комментарий
-4

Самый простой способ, на мой взгляд, это: вы редактируете основной файл настроек 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

и он работал без пароля

  • 0
    И вы просто разрушили систему безопасности. ОК для коробки разработчика, но больше ничего.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню