Skip to content

archive mode и ошибка вида WAL segment %s could not be archived in %d seconds #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
triwada opened this issue May 20, 2020 · 49 comments · Fixed by #493
Closed

Comments

@triwada
Copy link

triwada commented May 20, 2020

Имеется нагруженный инстанс в плане высокой скорости модификации данных (и соответственно большой cкорости переключения сегментов WAL). Периодически возникает очередь архивации WAL до нескольких тысяч сегментов (archiver не успевает быстро отрабатывать из-за большого потока WAL).
Бэкапы с режимом --stream отпадают из очень большого объема WAL, остаётся только archive.
Но в пики высокой скорости генерации WAL бэкапы DELTA/PAGE не завершаются только из-за ошибки вида "WAL segment %s could not be archived in %d seconds".
Как я понимаю, для успешного завершения инкрементного бэкапа должен выполниться archive_command для WAL с lsn на момент pg_stop_backup().
Из-за большой очереди архивации понятное дело что можно ждать очень долго этого события.

НО! В конечном счёте данный WAL всё же попадет в архив, пусть и спустя время.
Логично было бы иметь возможно запустить validate на такой ошибочный бэкап спустя время (когда WAL с lsn на момент pg_stop_backup() уже будет в архиве), чтобы он проверил, что все необходимые WAL имеются в архиве и поменял статус бэкапа с ERROR на OK.

Очень жалко, когда бэкап DELTA/PAGE объемом по 300 ГБ и выполнявший по несколько часов в итоге становится ошибочным только из-за того, что WAL вовремя не смог попасть в архив.

@gsmolk
Copy link
Contributor

gsmolk commented May 20, 2020

Добрый день!
Проблема в том, что постгрес имеет нездоровую тенденцию возвращать невалидный STOP_LSN, поэтому нам приходится прямо в процессе бэкапа это фиксить, а для этого нужно наличие сегмента с STOP_LSN.
А Вы пробовали увеличивать значение пробэкапного параметра --archive-timeout ?
Также начиная с версии 2.3.0 можно настроить многопоточное архивирование батчем. Пробовали?

@triwada
Copy link
Author

triwada commented May 20, 2020

уже итак подняли archive-timeout до 8000, но иногда и этого не хватает.
Версию 2.3.1 поставили недавно, пока тестируется, в документации особо не отражено, что такое batch-size и как определять его значение.

@gsmolk
Copy link
Contributor

gsmolk commented May 20, 2020

Это кол-во файлов, которое один процесс archive-push попытается отправить в архив.
В вашем случае, мне кажется, имеет смысл сделать --batch-size=100.
Если есть свободные ядра, то имеет смысл также использовать многопоточность - опция -j.
Документацию допишем.

@gsmolk
Copy link
Contributor

gsmolk commented May 20, 2020

НО! В конечном счёте данный WAL всё же попадет в архив, пусть и спустя время.
Логично было бы иметь возможно запустить validate на такой ошибочный бэкап спустя время (когда WAL с lsn на момент pg_stop_backup() уже будет в архиве), чтобы он проверил, что все необходимые WAL имеются в архиве и поменял статус бэкапа с ERROR на OK.

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

Я тут немного подумал, в случае, если постгрес вернул нормальный LSN, мы можем сохранить его в контрол файл до начала ожидания сегмента. Тогда получится поведение, которое Вы хотите.

@triwada
Copy link
Author

triwada commented May 20, 2020

т.е. если указать опции -j 8 --batch-size=100, то в итоге за один вызов archive_command должно архивироваться 800 WAL?

@gsmolk
Copy link
Contributor

gsmolk commented May 20, 2020

Нет, будет сархивировано максимум 100 с помощью 8 потоков.

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Как успехи?

@triwada
Copy link
Author

triwada commented May 21, 2020

сейчас пока выполняется FULL (это примерно на 30 часов), поэтому только после его завершения смогу сообщить, как пойдут DELTA/PAGE.

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Можно посмотреть в логе постгреса с какой скоростью идет архивирование.
Там должны быть сообщения вида:

PID [%d]: pg_probackup archive-push WAL file: %s, threads: %i/%i, batch: %lu/%i, compression: %s
PID [%d]: pg_probackup archive-push completed successfully, pushed: %u, skipped: %u, time elapsed: %s

@triwada
Copy link
Author

triwada commented May 21, 2020

пробовали запустить DELTA в режиме --stream и с использованием слота репликации, в итоге бэкап закончился
pg_probackup: could not receive data from WAL stream: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.

Суть данной ошибки непонятна, pg_probackup же должен использовать слот репликации.
Это ошибка на стороне pg_probackup?

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

pg_probackup: could not receive data from WAL stream: server closed the connection unexpectedly

Сервер со своей стороны закрыл соединение, надо смотреть в логе постгреса почему он это сделал.
Могу предположить, что дело в tcp keep alive. Если это так, то эту проблему можно решить так:

export PGOPTIONS='-c tcp_keepalives_idle=60 -c tcp_keepalives_count=75 -c tcp_keepalives_count=10'

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

А зачем Вам делать STREAM бэкапы, если у Вас есть архивирование? Или это другой инстанс?

@triwada
Copy link
Author

triwada commented May 21, 2020

перебираем все прочие варианты, раз уж в режиме archive не получается уже 2 суток ничего сделать.

Ошибка завершения сессии pg_probackup из лога postgres

2020-05-21 11:46:24 MSK [23551]: [3-1] us=backup,tx=0,db=[unknown],app=pg_probackup,cli=127.0.0.1 LOG: terminating walsender process due to replication timeout
2020-05-21 11:46:24 MSK [23551]: [4-1] us=backup,tx=0,db=[unknown],app=pg_probackup,cli=127.0.0.1 LOG: disconnection: session time: 3:15:52.301 user=backup database= host=127.0.0.1 port=21808

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Так давайте решим проблему с архивированием.
С какой скоростью сейчас генерится WAL?

@triwada
Copy link
Author

triwada commented May 21, 2020

в среднем 1 WAL/s, в пике может до 3 WAL/s (в течении нескольких часов)

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Это не очень высокая скорость генерации WAL.
Предлагаю следующее:

  1. Остановить текущий бэкап, если он запущен.
  2. Дать возможность archive-push разобрать накопившийся WAL.
  3. Можете посмотреть в постгресовом логе сообщения от archive-push?

@triwada
Copy link
Author

triwada commented May 21, 2020

странно, видимо, после обновления на версию 2.3 в файла лог не попадает archive_push при таких установках
log-level-console = OFF
log-level-file = LOG

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Архивирование через ssh работает?

@triwada
Copy link
Author

triwada commented May 21, 2020

нет, локально

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Хм, странно, сейчас посмотрю.
Можете пока включить --log-level-console=INFO для archive-push на некоторое время ?

@triwada
Copy link
Author

triwada commented May 21, 2020

включил, в логе postgres появились записи
INFO: PID [93122]: pg_probackup archive-push WAL file: 000000830001375C0000000C, threads: 1/10, batch: 1/1, compression: zlib
INFO: PID [93122]: pg_probackup archive-push completed successfully, pushed: 1, skipped: 0, time elapsed: 586ms
INFO: PID [93243]: pg_probackup archive-push WAL file: 000000830001375C0000000D, threads: 1/10, batch: 1/1, compression: zlib
INFO: PID [93243]: pg_probackup archive-push completed successfully, pushed: 1, skipped: 0, time elapsed: 618ms

@triwada
Copy link
Author

triwada commented May 21, 2020

так а какой параметр важнее -j или --batch-size?

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

так а какой параметр важнее -j или --batch-size?

-j не имеет смысла без --batch-size.
--batch_size задает объем работы. -j задает кол-во тредов, которые эту работу будут выполнять.

@triwada
Copy link
Author

triwada commented May 21, 2020

Поменял
INFO: PID [107298]: pg_probackup archive-push completed successfully, pushed: 1, skipped: 0, time elapsed: 584ms
INFO: PID [107304]: pg_probackup archive-push WAL file: 000000830001375E00000038, threads: 10/10, batch: 100/100, compression: zlib
INFO: PID [107304]: pg_probackup archive-push completed successfully, pushed: 100, skipped: 0, time elapsed: 10s:427ms
INFO: PID [107413]: pg_probackup archive-push WAL file: 000000830001375E0000009C, threads: 10/10, batch: 100/100, compression: zlib

но всё-таки выключил, иначе потом отчеты pgbadger немного визуально пострадают
log-level-console = OFF

Почему перестал работать log-level-file ?

@triwada
Copy link
Author

triwada commented May 21, 2020

log-level-console = OFF
log-level-file = LOG

не работает в версии 2.3.1 и 2.3.3

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Почему перестал работать log-level-file ?

Похоже что фикс для этого бага получился слишком оверкильный: #178
Заведу баг, пофиксим в 2.3.4.

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Давайте посмотрим, сколько нам еще осталось сархивировать:

select * from pg_stat_archiver, pg_current_wal_lsn();

@triwada
Copy link
Author

triwada commented May 21, 2020

postgres=# select last_archived_wal from pg_stat_archiver, pg_current_xlog_location();
ERROR:  recovery is in progress
HINT:  WAL control functions cannot be executed during recovery.
postgres=# select last_archived_wal from pg_stat_archiver;
    last_archived_wal
--------------------------
 000000830001378800000068
(1 row)

postgres=# \! ps -ef | grep recover
postgres 122304 122272 22 Apr19 ?        7-05:16:37 postgres: startup process   recovering 00000083000137F500000030

если я правильно посчитал разницу, то это около 30k WAL
137F5-13788=6D=109
109*255=27795

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

postgres=# select pg_size_pretty(pg_wal_lsn_diff('13788/68000000', '137F5/30000000'));
 pg_size_pretty 
----------------
 -435 GB

Давайте сделаем --batch-size=1000, и, если есть свободные cpu, увеличим кол-во тредов.
Какой уровень компрессии используете?

@triwada
Copy link
Author

triwada commented May 21, 2020

-j 20 --batch-size 1000 --compress-level=1

INFO: PID [38096]: pg_probackup archive-push WAL file: 00000083000137A30000005C, threads: 10/10, batch: 100/100, compression: zlib
INFO: PID [38096]: pg_probackup archive-push completed successfully, pushed: 100, skipped: 0, time elapsed: 9s:942ms
INFO: PID [39210]: pg_probackup archive-push WAL file: 00000083000137A3000000C0, threads: 10/10, batch: 100/100, compression: zlib
INFO: PID [39210]: pg_probackup archive-push completed successfully, pushed: 100, skipped: 0, time elapsed: 8s:301ms
INFO: PID [39422]: pg_probackup archive-push WAL file: 00000083000137A400000024, threads: 10/10, batch: 100/100, compression: zlib

INFO: PID [39422]: pg_probackup archive-push completed successfully, pushed: 100, skipped: 0, time elapsed: 8s:626ms
INFO: PID [39551]: pg_probackup archive-push WAL file: 00000083000137A400000088, threads: 20/20, batch: 1000/1000, compression: zlib
INFO: PID [39551]: pg_probackup archive-push completed successfully, pushed: 1000, skipped: 0, time elapsed: 1m:18s
INFO: PID [42061]: pg_probackup archive-push WAL file: 00000083000137A800000070, threads: 20/20, batch: 1000/1000, compression: zlib
INFO: PID [42061]: pg_probackup archive-push completed successfully, pushed: 1000, skipped: 0, time elapsed: 1m:20s
INFO: PID [45400]: pg_probackup archive-push WAL file: 00000083000137AC00000058, threads: 20/20, batch: 1000/1000, compression: zlib

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Сейчас разгребет за полчаса-час.

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Если по диску в архиве еще не умираете, то можно еще --batch-size увеличить.

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Как прогресс?

@triwada
Copy link
Author

triwada commented May 21, 2020

очень круто

postgres=# select pg_size_pretty(pg_xlog_location_diff('000137FA/D3', '137EE/C0'));
 pg_size_pretty
----------------
 48 GB
(1 row)

@triwada
Copy link
Author

triwada commented May 21, 2020

теперь в логе появляются строки вида
2020-05-21 15:42:13 MSK: LOG: Thread [22]: Opening compressed WAL segment "/{path}/000000830001362E00000078.gz"

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Это в пробэкапом логе?

@triwada
Copy link
Author

triwada commented May 21, 2020

да

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Видимо бэкап запустился.

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Разгрёб?

@triwada
Copy link
Author

triwada commented May 21, 2020

да, бэкапы PAGE начали выполняться

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

А можете показать статистику из show? Интересно посмотреть на время.

@triwada
Copy link
Author

triwada commented May 21, 2020

BACKUP INSTANCE 'dummy'
=====================================================================================================================================================
 Instance  Version  ID      Recovery Time           Mode  WAL Mode  TLI         Time    Data    WAL  Zratio  Start LSN       Stop LSN        Status
=====================================================================================================================================================
 dummy   9.6      QAP98F  ----                    PAGE  ARCHIVE   131/131   1h:15m       0      0    1.00  13851/26024288  0/0             RUNNING
 dummy   9.6      QAP3OD  2020-05-21 22:11:38+03  PAGE  ARCHIVE   131/131   6m:42s    26GB   19GB    3.51  1383E/33074EC0  13842/EC66B768  OK
 dummy   9.6      QAOY4D  2020-05-21 20:36:17+03  PAGE  ARCHIVE   131/131  31m:23s   109GB   27GB    8.39  1382C/F904F778  13833/B3441780  OK
 dummy   9.6      QAOFQ3  2020-05-21 18:33:43+03  PAGE  ARCHIVE   131/131    5h:6m   347GB  225GB    7.44  137E9/CA043ED8  13822/23752850  OK
 dummy   9.6      QAIRO3  2020-05-18 21:57:15+03  FULL  ARCHIVE   131/0    13h:40m  6893GB  360GB    2.38  134E1/A60ACE58  1353B/C0953050  OK
 dummy   9.6      QAIMCD  2020-05-18 10:13:37+03  PAGE  ARCHIVE   131/131   8m:38s    42GB   13GB    2.93  134D3/DE125398  134D7/21C22760  OK
 dummy   9.6      QAIB8E  2020-05-18 07:53:42+03  PAGE  ARCHIVE   131/131    2h:4m   231GB   57GB    3.21  134B4/DC03F518  134C3/E4C45A0   OK
 dummy   9.6      QAG2B8  2020-05-17 17:32:24+03  FULL  ARCHIVE   131/0    18h:38m  6813GB  529GB    2.39  133F8/33027AE8  1347C/69AEBF38  OK

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

Хм, интересно.
Похоже, что те данные, которые часто обновляются жмутся гораздо лучше относительно всей базы в целом. За 3 дня набежало всего 347 гигов, т.е. меняется примерно один и тот же сабсет данных. Ваш кейс выиграет от #201 и #66.
Скорость копирования PAGE (2h:4m 231GB) непропорционально низкая. Вангую, что из-за необходимости парсить тонну сжатого WAL. Надо придумать тут какую-то оптимизацию.

@triwada
Copy link
Author

triwada commented May 21, 2020

не удивлен, что первый PAGE после FULL идёт долго (это и с DELTA аналогично). Просто FULL идет по 30 часов, естественно за такое время изменений очень много.
На другой ноде этого кластера выполняется DELTA

 dummy   9.6      QAP3WP  2020-05-22 01:50:36+03  DELTA  ARCHIVE   131/131   3h:40m   263GB  155GB    8.41  1383F/EC05ACD0  13866/A5874DB0  OK
 dummy   9.6      QANEC1  2020-05-21 10:48:46+03  FULL   ARCHIVE   131/0    11h:22m  6998GB  715GB    2.40  13728/DA23B400  137DB/7A27F6B0  OK

@gsmolk
Copy link
Contributor

gsmolk commented May 21, 2020

С релизом #201 Вы сможете гораздо реже делать FULL, что позволит сэкономить время и место.
Обычно DELTA, особенно на таких объемах базы, проигрывает PAGE куда значительнее. Да, надо явно запилить парсинг WAL в процессе пуша.

@gsmolk
Copy link
Contributor

gsmolk commented May 24, 2020

Можем закрывать?

@triwada
Copy link
Author

triwada commented May 25, 2020

Я тут немного подумал, в случае, если постгрес вернул нормальный LSN, мы можем сохранить его в контрол файл до начала ожидания сегмента. Тогда получится поведение, которое Вы хотите.

Это планируется в #215?

@gsmolk
Copy link
Contributor

gsmolk commented May 25, 2020

Ага

@triwada
Copy link
Author

triwada commented May 25, 2020

тогда закрываем

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants