Странное поведение слейва PG при потоковой репликации и изменениях на мастере

Artemiy
Дата: 19.02.2015 13:43:20
Добрый день

Есть два похожих больших приложения. На одном 9.3.4, на втором 9.2.9. Ситуация и там и там одна и таже.
Потоковая репликация, по 1-3 слейва. На каждой машине баунсер.

Есть регулярный ночной процесс, в котором меняется много данных.
Есть в этом процессе один этап, в котором удаляется чистится таблица (делит), делается большой инсерт в эту таблицу.
Таблица 100 мб, индексов 50 мб. Данных вставляется не много, но для что бы их посчитать уходит много времени и ресурсов. Там запрос по нескольким большим таблицам (десятки гб) с группировкой, агрегатами и юнионами.

В этот момент на мастере подскакивает CPU и другие показатели, но ничего критичного, мастер вывозит. Слейв такой же по конфигурации и железу по непонятным причинам затыкается. Продолжаться этот может 30 мин. Постгрес на слейве жрет много цпу, как бы вешается. Заканчивается все это перезапуском баунсера, который тоже в результате висит и даже после того как ПГ приходит в себя он не начинает работать.

Проблема в том, что постгрес вешается очень зло. Все новые соединения получают accept(), но дальше постгрес их не обрабатывает.
Таким образом любое подключение к постгресу в этот момент висит до бесконечности.

Чем занят постгрес в это время пока не смотрели. Мониторинг в это время так же не работает, т.к. его конекты к постгресу так же висят и прерывается процесс опроса метрик.

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

Есть понимание что процесс нужно облегчать, уходить от полной перезаписи, уменьшать кол-во изменений.
Не понятно почему мастер переваривает, а слейв, который должен только накатить логи (таблица 100 мб), так вешается.

Планируем переделку процесса, обновление ПГ до 9.3.6.

Есть мысли о том, что происходит?
Gold_
Дата: 19.02.2015 13:51:38
Artemiy,
DDL не делаете например, перед этим инсертом не делаете?
Artemiy
Дата: 19.02.2015 14:07:10
Gold_,

В этой транзакции или в другой до?

В этой транзакции в одном аппликейшене делается create/drop temp table + индекс на ней.
В этой транзакции в другом аппликейшене не делается DDL.

В другой транзакции, раньше, делается:
TRUNCATE TABLE
setval
create/drop temp
SET CONSTRAINTS ALL DEFERRED
SET CONSTRAINTS ALL IMMEDIATE
Gold_
Дата: 19.02.2015 14:43:43
Artemiy,

TRUNCATE TABLE

Эта TABLE на реплике активно читается? длинными транзакциями?
интересуюсь
Дата: 19.02.2015 14:59:28
Artemiy,
а логи потгреса на стендбае и его баунсера не пробовали читать ?
Artemiy
Дата: 19.02.2015 15:01:25
Gold_,

Нет это постоянная таблица используется как "временная" в регулярном процессе. Пишется и читается только на мастере одним процессом. В нее заливаются данные из внешней системы.
Maxim Boguk
Дата: 19.02.2015 15:44:41
Artemiy
Gold_,

В этой транзакции или в другой до?

В этой транзакции в одном аппликейшене делается create/drop temp table + индекс на ней.
В этой транзакции в другом аппликейшене не делается DDL.

В другой транзакции, раньше, делается:
TRUNCATE TABLE
setval
create/drop temp
SET CONSTRAINTS ALL DEFERRED
SET CONSTRAINTS ALL IMMEDIATE


Без изучения ситуации глазами на репликах во время проблем вряд ли что то удасться сказать.
Обратить внимание на вывод top (LA/cpu usage) и на вывод iostat -x -m 10.

Вариантов много, один из наиболее вероятных - то что что после "делается большой инсерт" вы не делаете принудительный analyze таблицы в той же транзакции.

В итоге если реплика активно с этой таблицей работает может сложится ситуация кривых планов на реплике пока autoanalyze не сработает на мастере, а дальше домино:
кривые планы на реплике ->
CPU/LA в небо ->
замедляется проигрывание WAL c мастера так как ресурсов не хватает
-> даже если мастер быстро сделал autoanalyze когда он там еще проиграется на реплике в таких условиях никто не скажет
-> все грустно и печально (я такое на практике наблюдал пару раз).

В качестве острой приправы при большом max_connections/work_mem сервер у вас еще и в swap улетит вместе с кусками shared_buffer, и станет совсем весело.

PS: включите лог всех запросов с временами на реплике и посмотрите по логу потом чем реплика была занята в это время (если CPU/LA или io utilization были высокими). Ну и не надо ставить max_connections больше чем cpu*2 на чтобы в случае если все коннекты были всетаки заняты работой сервер ну хоть как то отвечал.

--Maxim Boguk
www.postgresql-consulting.ru
Misha Tyurin
Дата: 19.02.2015 16:22:25
swapoff -a

наше всё)
Maxim Boguk
Дата: 19.02.2015 16:31:34
Misha Tyurin
swapoff -a

наше всё)


лучше всетаки vm.swappiness=1 + swap
иначе начинает злой OOM killer приходить не по делу временами (т.е. в ситуации когда память на самом то деле есть).
Ну или надо аккуратно с overcommit memory настройками играться.

--Maxim Boguk
www.postgresql-consulting.ru
Misha Tyurin
Дата: 19.02.2015 16:55:21
Maxim Boguk,

> overcommit memory настройками играться

да, че-то там вроде надо настраивать