У меня есть сценарий оболочки bash, который выгружает все мои базы данных postgres из докера:
function dump_postgres {
mkdir -p ${BACKUP_DIR}/postgres/
docker ps -a --format '{{.Names}}\t{{.Ports}}' | grep 5432/tcp | awk '{ print $1 }' | while read -r line; do
echo "extracting database from container '${line}'"
docker exec -t ${line} pg_dumpall -v --lock-wait-timeout=600 -c -U postgres > ${BACKUP_DIR}/postgres/${line}.sql
done
}
dump_postgres >> "${LOG}" 2>> "${ERROR}"
Сценарий определяет, какие контейнеры докеров прослушивают порт postgres по умолчанию, и выгружает базу данных в формате sql.
Моя проблема в том, что эта команда внезапно останавливается через день при запуске cron. Он просто останавливается, а контейнер, который делает дамп, не выходит. Также нет вывода на stderr.
Вы знаете, как это решить?
РЕДАКТИРОВАТЬ:
crontab выглядит так:
30 1 * * * /home/mrbackup/backup.sh
работа планируется каждую ночь в 1:30. Сценарий сторожевого таймера в 3:00 уже видит, что резервное копирование не удалось и pg_dumpall зависает.
РЕДАКТИРОВАТЬ2: Сегодня вечером квассель - это проблема, но это меняется через день. nextcloud тоже создает проблемы. еще немного информации о процессах:
# ps -efH
root 493 1 0 Mai24 ? 00:00:04 /usr/sbin/cron -f
root 12401 493 0 01:30 ? 00:00:00 /usr/sbin/CRON -f
mrbackup 12402 12401 0 01:30 ? 00:00:00 /bin/sh -c /home/mrbackup/backup.sh
mrbackup 12403 12402 0 01:30 ? 00:00:00 /bin/bash /home/mrbackup/backup.sh
mrbackup 12412 12403 0 01:30 ? 00:00:00 /bin/bash /home/mrbackup/backup.sh
mrbackup 12428 12412 0 01:30 ? 00:00:11 docker exec -t quassel_postgres_1 pg_dumpall -v --lock-wait-timeout=600 -c -U postgres
root 12449 11150 0 01:30 ? 00:00:00 pg_dumpall -v --lock-wait-timeout=600 -c -U postgres
root 12467 12449 0 01:30 ? 00:00:00 sh -c "/usr/local/bin/pg_dump" -v --lock-wait-timeout '600' -Fp 'user=postgres dbname=quassel'
root 12468 12467 0 01:30 ? 00:00:16 /usr/local/bin/pg_dump -v --lock-wait-timeout 600 -Fp user=postgres dbname=quassel
strace показывает, что большинство подпроцессов pg_dump ждут блокировки?
futex(0xc42054cd38, FUTEX_WAIT, 0, NULL
два процесса перезапускают системный вызов:
restart_syscall(<... resuming interrupted futex ...>)
пытаясь посмотреть базу данных с помощью этого запроса:
SELECT a.datname,
c.relname,
l.mode,
l.GRANTED,
a.wait_event_type,
a.usename,
a.query,
a.query_start,
age(now(), a.query_start) AS "age",
a.pid
FROM pg_stat_activity a
JOIN pg_locks l ON l.pid = a.pid
JOIN pg_class c ON c.oid = l.relation
WHERE
NOW() - query_start > '10 second';
ORDER BY a.query_start;
дает мне следующее:
datname | relname | mode | granted | wait_event_type | usename | query | query_start | age | pid
---------+-----------------------------------------+-----------------+---------+-----------------+----------+--------------------------------------------------+-------------------------------+-----------------+-------
quassel | pg_attribute_relid_attnum_index | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_attribute_relid_attnam_index | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_attribute | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_class | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_init_privs_o_c_o_index | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_roles | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_init_privs | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
quassel | pg_depend_reference_index | AccessShareLock | t | | postgres | COPY public.sender (senderid, sender) TO stdout; | 2018-07-21 23:30:18.253695+00 | 07:11:41.798605 | 25095
и еще 100 строк
РЕДАКТИРОВАТЬ Я исправил свою первоначальную проблему, но мне все равно будет интересно узнать, почему труба лопается. Также почему процесс не завершается в этой ситуации.
Похоже, что трубопровод из док-контейнера иногда ломал трубу. Использование параметра -f из pg_dumpall решило проблему
docker exec -t ${line} pg_dumpall -v --lock-wait-timeout=600 -c -U postgres -f /tmp/export.sql
docker cp ${line}:/tmp/export.sql ${BACKUP_DIR}/postgres/${line}.sql
docker exec -t ${line} rm /tmp/export.sql