Как мне создать резервную копию моей базы данных PostgreSQL с помощью Cron?

Я могу запускать команды, такие как vacuumdb, pg_dump и psql, просто отлично в script, если я их предикатно:

/usr/bin/sudo -u postgres /usr/bin/pg_dump -Fc mydatabase > /opt/postgresql/prevac.gz
/usr/bin/sudo -u postgres /usr/bin/vacuumdb --analyze mydatabase
/usr/bin/sudo -u postgres /usr/bin/pg_dump -Fc mydatabase > /opt/postgresql/postvac.gz
SCHEMA_BACKUP="/opt/postgresql/$(date +%w).db.schema"
sudo -u postgres /usr/bin/pg_dump -C -s mydatabase > $SCHEMA_BACKUP

Они запускаются в командной строке на Redhat, когда я sudo для root, а затем, как вы видите в приведенных выше командах, я делаю sudo -u для postgres.

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

Мой файл /etc/crontab имеет эту запись внизу

00 23 * * * root /etc/db_backup.cron

И да, /etc/db _backup.cron - это chmod ug + x, принадлежащий root, а в верхней части файла указано "#!/bin/ bash" (минус doublequotes).

Кто-нибудь знает, что дает?

Ответ 1

Так как у вас, похоже, есть права суперпользователя, вы можете поместить эти команды в crontab пользователя postgres следующим образом:

sudo su postgres
crontab -e

а затем введите команды pg_dump/vacuumdb.

Ответ 2

У меня есть динамический bash script, который поддерживает все базы данных на сервере. Он получает список всех баз данных и затем вакуумирует каждую БД перед выполнением резервного копирования. Все журналы записываются в файл, а затем этот журнал отправляется мне по электронной почте. Это то, что вы могли бы использовать, если хотите.

Скопируйте приведенный ниже код в файл и добавьте файл в свой crontab. Я установил pg_hba.conf, чтобы доверять локальным соединениям.

#!/bin/bash
logfile="/backup/pgsql.log"
backup_dir="/backup"
touch $logfile
databases=`psql -h localhost -U postgres -q -c "\l" | sed -n 4,/\eof/p | grep -v rows\) | grep -v template0 | grep -v template1 | awk {'print $1'}`

echo "Starting backup of databases " >> $logfile
for i in $databases; do
        dateinfo=`date '+%Y-%m-%d %H:%M:%S'`
        timeslot=`date '+%Y%m%d%H%M'`
        /usr/bin/vacuumdb -z -h localhost -U postgres $i >/dev/null 2>&1
        /usr/bin/pg_dump -U postgres -i -F c -b $i -h 127.0.0.1 -f $backup_dir/$i-database-$timeslot.backup
        echo "Backup and Vacuum complete on $dateinfo for database: $i " >> $logfile
done
echo "Done backup of databases " >> $logfile

tail -15 /backup/pgsql.log | mailx [email protected]

Ответ 3

Возможно, ваша переменная окружения не установлена ​​в cron.

В вашем обычном сеансе вы, вероятно, определили следующие переменные:

PG_PORT
PG_HOST
PG_DATABASE
PG_USERNAME
PG_PASSWORD

Добавьте "env" в yout script.

Ответ 4

Я установил свой cron вот так. Каждые 59 минут с понедельника по пятницу

*/59 * * * 1-5 sh /home/my_user/scripts/back_my_bd.sh 

script для запуска резервного копирования находится внутри файла back_my_bd.sh, а содержимое:

pg_dump -U USERDATABASE DATABASENAME > /home/my_user/sql/mybackup.sql

И я создал файл .pgpass внутри домашнего каталога, чтобы разрешить резервное копирование без указания пользователя и пароля

localhost:5432:DATABASENAME:USER:PASSWORD

Извините, мой английский не очень хорош!

Ответ 5

у вас, вероятно, есть идентификация "ident" в вашем pg_hba.conf для вашего пользователя postgres. Опция "-u postgres" терпит неудачу, если это так. либо изменить пользователя на postgres в резервной копии script, либо настроить другой метод проверки подлинности.

Ответ 6

Вместо следующей команды: базы данных = psql -h localhost -U postgres -q -c "\l" | sed -n 4,/\eof/p | grep -v rows\) | grep -v template0 | grep -v template1 | awk {'print $1'}

Вы можете использовать ниже: базы данных = psql -t -c "select datname from pg_database where datname not like 'template%';" | grep -v '^$'

Первый возвращает '|' для баз данных шаблонов и пустой строки.

Второй - более чистый.

Ответ 7

базы данных = psql -h localhost -U postgres -q -x -t -c "\l" | grep 'Name' | sed 's/ //g' | sed 's/Name|//g'

Ответ 8

Другая версия для получения списка баз данных:
psql -lqt | grep -vE '^ +(template[0-9]+|postgres)? *\|' | cut -d'|' -f1| sed -e 's/ //g' -e '/^$/d'

Как мой вывод psql -lqt:

 abcdefghij         | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres           | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0          | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
                    |          |          |             |             | postgres=CTc/postgres
 template1          | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
                    |          |          |             |             | postgres=CTc/postgres
 abc                | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |