bash - pg_dumpall - pg_restore
¿Cómo pasar la contraseña a pg_dump? (10)
Corríjame si me equivoco, pero si el usuario del sistema es el mismo que el usuario de la base de datos, PostgreSQL no solicitará la contraseña; depende del sistema para la autenticación. Esto podría ser una cuestión de configuración.
Por lo tanto, cuando quería que el propietario de la postgres
datos postgres
una copia de seguridad de sus bases de datos cada noche, podía crear un crontab para ello: crontab -e -u postgres
. Por supuesto, a los postgres
les debería permitir ejecutar trabajos cron; por lo tanto, debe estar listado en /etc/cron.allow
, o /etc/cron.deny
debe estar vacío.
Estoy tratando de crear un cronjob para hacer una copia de seguridad de mi base de datos cada noche antes de que ocurra algo catastrófico. Parece que este comando debe satisfacer mis necesidades:
0 3 * * * pg_dump dbname | gzip > ~/backup/db/$(date +%Y-%m-%d).psql.gz
Excepto después de ejecutar eso, espera que escriba una contraseña. No puedo hacer eso si lo ejecuto desde cron. ¿Cómo puedo pasar uno automáticamente?
Cree un archivo .pgpass
en el directorio de inicio de la cuenta con la que se ejecutará pg_dump
. Consulte la documentación de Postgresql libpq-pgpass para obtener detalles del formato (incluido el último párrafo donde se explica que se ignorará si no configura el modo en 0600
).
La respuesta de @Josue Alexander Ibarra funciona en centos 7 y versión 9.5 si --dbname no se pasa.
pg_dump postgresql://username:[email protected]:5432/mydatabase
O puede configurar crontab para ejecutar un script. Dentro de ese script puede establecer una variable de entorno como esta: export PGPASSWORD="$put_here_the_password"
De esta manera, si tiene varios comandos que requieren contraseña, puede ponerlos todos en el script. Si la contraseña cambia, solo tiene que cambiarla en un lugar (el script).
Y estoy de acuerdo con Joshua, usar pg_dump -Fc
genera el formato de exportación más flexible y ya está comprimido. Para más información ver: documentación pg_dump
P.ej
# dump the database in custom-format archive
pg_dump -Fc mydb > db.dump
# restore the database
pg_restore -d newdb db.dump
Otra forma (probablemente no segura) de pasar la contraseña es usar la redirección de entrada, es decir, llamar
pg_dump [params] < [path to file containing password]
Para una sola línea, como migrar una base de datos, puede usar --dbname
seguido de una cadena de conexión (incluida la contraseña) como se indica en el manual pg_dump
En esencia.
pg_dump --dbname=postgresql://username:[email protected]:5432/mydatabase
Nota: asegúrese de usar la opción --dbname
lugar de la más corta -d
y use un prefijo URI válido, postgresql://
o postgres://
.
La forma general de URI es:
postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
Las mejores prácticas en su caso (tarea repetitiva en cron) no se deben realizar debido a problemas de seguridad. Si no fuera por el archivo .pgpass
, guardaría la cadena de conexión como una variable de entorno.
export MYDB=postgresql://username:[email protected]:5432/mydatabase
luego tener en tu crontab
0 3 * * * pg_dump --dbname=$MYDB | gzip > ~/backup/db/$(date +%Y-%m-%d).psql.gz
Realice una copia de seguridad a través de ssh con una contraseña utilizando credenciales temporales .pgpass y presione para 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
Simplemente sustituye las primeras líneas de configuración con lo que necesites, obviamente. Para aquellos que no estén interesados en la parte de respaldo del S3, sáquenlo, obviamente.
Esta secuencia de comandos elimina las credenciales en .pgpass
posteriormente porque en algunos entornos, el usuario SSH predeterminado puede sudo sin una contraseña, por ejemplo, una instancia de EC2 con el usuario de ubuntu
, por lo tanto, usar .pgpass
con una cuenta de host diferente para asegurar esas credenciales. podría ser inútil
Si quieres hacerlo en un solo comando:
PGPASSWORD="mypass" pg_dump mydb > mydb.dump
la forma más fácil en mi opinión, esto: edita el archivo de configuración principal de postgres: pg_hba.conf, allí tiene que agregar la siguiente línea:
host <you_db_name> <you_db_owner> 127.0.0.1/32 trust
y después de esto necesitas iniciar tu cron así:
pg_dump -h 127.0.0.1 -U <you_db_user> <you_db_name> | gzip > /backup/db/$(date +%Y-%m-%d).psql.gz
y funcionó sin contraseña
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename