PostgreSQL - фильтровать список баз данных

У меня есть этот скрипт (который ежедневно создает резервные копии баз данных):

#!/bin/bash
# Location to place backups.
backup_dir="/home/user/openerp/7.0/backup/"
#String to append to the name of the backup files
backup_date=`date +%Y-%m-%d`
#Numbers of days you want to keep copie of your databases
number_of_days=7
databases=`psql -l -t | cut -d'|' -f1 | sed -e 's/ //g' -e '/^$/d'`
for i in $databases; do
  if [ "$i" != "template0" ] && [ "$i" != "template1" ]; then
    echo Dumping $i to $backup_dir$i\_$backup_date
    pg_dump -Fc $i > $backup_dir$i\_$backup_date
  fi
done
find $backup_dir -type f -prune -mtime +$number_of_days -exec rm -f {} \;

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

Я думаю, это потому, что он пытается сделать резервную копию баз данных, таких как template0 и template1. Я попытался посмотреть в документации, как работает эта фильтрация баз данных, но не нашел никакой информации.

Может ли кто-нибудь сказать мне, как фильтровать все мои базы данных, кроме баз данных, таких как template0, template1, postgres. Также было бы здорово, если бы кто-нибудь мог дать ссылку на документацию, где говорится о такой фильтрации:

`psql -l -t | cut -d'|' -f1 | sed -e 's/ //g' -e '/^$/d'`

Вывод по запросу:

demo
demo_empty1
dn1
dn2
dn3
da21
da22
nbb323
nd
nd2
pf12
postgres
rub_demo1
template0
template1
test
test3
testas_3

Итак, все базы данных, кроме postgres, template0 и template1


person Andrius    schedule 18.04.2013    source источник
comment
Я думаю, было бы полезно иметь вывод вашего psql -l -t. Из этого укажите, какие вы хотите иметь, а какие нет.   -  person fedorqui 'SO stop harming'    schedule 18.04.2013
comment
добавьте строку echo "$i" внутри цикла, чтобы вы могли видеть, какая база данных обрабатывается.   -  person Ansgar Wiechers    schedule 18.04.2013


Ответы (1)


Я подозреваю, что ваша догадка о шаблонных базах данных неверна. pg_dump сбросит их почти мгновенно.

Скорее всего, ваша проблема заключается в том, что pg_dump ожидает попытки получить блокировку таблицы, на которую кто-то еще удерживает блокировку ACCESS EXCLUSIVE. Вам нужно будет увидеть, какой pg_dump процесс заблокирован, и изучить pg_locks представление этой базы данных, чтобы лучше понять, что происходит. В ваших журналах должно быть указано, какая база данных задерживает дамп, а ps сообщит вам, какая pg_dump работает. pg_stat_activity позволит вам идентифицировать соединение процесса pg_dump.

Кстати, вы совершенно не в состоянии выполнить какую-либо обработку ошибок в этом скрипте. Если резервное копирование завершится неудачно, вы никогда об этом не узнаете, если только не прочитаете журналы и не заметите какой-нибудь полезный вывод stderr из pg_dump. Лично я рекомендую использовать pgbarman для регулярных резервных копий, хотя периодическое создание дампов по-прежнему является хорошей идеей.

Поскольку вы можете исключить template0 и template, даже если они, скорее всего, не являются проблемой, вы можете использовать:

psql --tuples-only -P format=unaligned -c "SELECT datname FROM pg_database WHERE NOT datistemplate AND datname <> 'postgres'";

вместо вашего решения для обработки текста. Вы обнаружите, что параметры --tuples-only и -P format=unaligned очень полезны при работе со сценариями с psql.

person Craig Ringer    schedule 19.04.2013
comment
Спасибо за ответ. На самом деле это был не мой сценарий :). Но буду иметь в виду. Иногда этот скрипт работает нормально и резервирует все базы данных, иногда половину. - person Andrius; 19.04.2013