UDP Overflow / UDP Drops в резервной службе Postgres
Я в тупике, пытаясь предотвратить переполнение буфера UDP в резервной службе Postgres. Любая помощь будет наиболее ценной.
По сути, буфер UDP, связанный с процессом pg_standby на моем локальном интерфейсе, постепенно заполняется, как только я запускаю Postgres, пока он не достигнет своей максимальной емкости, а затем продолжит устойчиво отбрасывать пакеты. Перезапуск Postgres (конечно) очищает буфер, но затем он снова начинает заполняться.
Насколько я могу судить, это на самом деле не вызывает никаких проблем. (Это происходит только с резервной службой, и восстановление данных после сбоя не показывает ничего недостающего.) Тем не менее, я не хочу переполнения буферов.
Существенные моменты:
а) запрашивая информацию "/proc" для UDP, я вижу непустые буферы; а порт UDP для единственного непустого буфера (hex E97B -> dec 59771) позволяет нам использовать netstat для отображения интерфейса (localhost) и PID (438), что подтверждает, что процесс "pg_standby" является виновником:
# cat /proc/net/udp | grep -v '00000000:0000'
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
16: 0100007F:E97B 0100007F:E97B 01 00000000:01000400 00:00000000 00000000 600 0 73123706 2 ffff880026d64ac0 0
# netstat -anp | grep 59771
udp 16778240 0 127.0.0.1:59771 127.0.0.1:59771 ESTABLISHED 438/pg_standby
# ps -F -p 438
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
postgres 438 29613 0 1016 496 0 11:18 ? 00:00:00 /usr/pgsql-9.1/bin/pg_standby -t /archive_wals/stoprecovery.trigger -c /archive_wals 000000010000000A000000C8 pg_xlog/RECOVERYXLOG 000000010000000A000000C6
б) переполнение происходит, даже когда мои брандмауэры на обоих серверах (iptables) закрыты
в) мои UDP-буферы кажутся более чем достаточно большими. Я мог бы сделать их больше, но это только замаскирует проблему
# grep rmem /etc/sysctl.conf | grep -v tcp
net.core.rmem_max = 26214400
net.core.rmem_default = 16777216
г) онлайн-обсуждения подобных проблем, кажется, затрагивают либо более старые версии Postgres, либо сборщик статистики; Чтобы исключить это, я попытался отключить сбор статистики, но проблема не исчезла:
# egrep '(track)' postgresql.conf | grep -v '^\s*#'
track_activities = off
track_counts = off
e) полученный пакет UDP не очень информативен; tshark verbose sniff показывает что-то вроде этого для каждого нового отброшенного UDP-пакета:
Data (72 bytes)
0000 0b 00 00 00 48 00 00 00 01 00 00 00 00 00 00 00 ....H...........
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040 00 00 00 00 00 00 00 00 ........
Data: 0B0000004800000001000000000000000000000000000000...
[Length: 72]
f) активность базы данных невелика (например, примерно один файл WAL размером 16 МБ реплицируется с первичного на вторичный сервис каждые 45 минут)
g) Ранее я запускал Postgres 8.3.5 с другой идентичной настройкой; эта проблема началась только когда я обновился до 9.1.9
Фон на моей установке:
- две системы CentOS 6.4 x86_64 бит (VM), каждая из которых работает с Postgres 9.1.9, каждая в географически разнесенном (<50 миль) центре данных
- Postgres активен на моем основном сервере и работает в режиме ожидания на моей резервной копии:
- служба резервного копирования Postgres получает данные двумя способами:
- в качестве горячего резервирования при обработке файлов WAL посредством доставки журналов ( см. разделы 25.2.1-25.2.4 здесь)
- при отработке отказа текущий файл WAL на первичном (еще не доставленном) восстанавливается из раздела DRBD, синхронизированного с первичным блоком (здесь нет стандартной процедуры, но здесь обсуждается)
- ничто иное (как следствие) не работает на этих коробках, кроме Postgres