powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Дублирование ивентов PgQ
25 сообщений из 32, страница 1 из 2
Дублирование ивентов PgQ
    #38865904
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С недавних пор возникла ситуация, когда pgq создает дублирующие батчи. Имеются ввиду батчи с разными batch_id, но содержащие идентичные ивенты.

Консумер читает батч и процессит ивенты поодному, вызывая pgq_ext.set_event_done() после обработки каждого ивента( и конечно проверяет is_even_done перед обработкой). После обработки всех ивентов батча, консумер выполняет finish_batch() и берет следующий.

Когда возникает проблема, консумер обрабатывает все ивенты батча 1, делает finish_batch(), finish_batch говорит "WARNING: finish_batch: batch 1 not found", после этого консумер берет батч 2, который содержит все ивенты, уже обработанные в батче 1( тот же event_id, тот же пейлоад)

Сталкивался ли кто то с такой ситуацией?
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38867092
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть подозрение, что виновата нестабильность времени на сервере, оказалось ntp был поломан. Мониторим пока.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868073
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кактуз,

а какая версия skytools?
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868141
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Версия 3.1.5, если точнее то версия deb пакета 3.1.5-1.pgdg70+1

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
# SELECT pgq_ext.version();
 version 
---------
 3.1
(1 row)
# SELECT version();
                                           version                                            
----------------------------------------------------------------------------------------------
 PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 64-bit
(1 row)
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868144
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
починка ntp проблемы не решила.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868299
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кактуз,

> консумер

какой конкретно консумер?

"finish_batch: batch % not found"
это говорит о том, что батча такого не было вам выдано.

опишите подробно схему, с указанием, кто куда и через что подключается, что за консумер, и как вы его запускаете.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868300
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и штатно ли работал сервер - база - консумер перед возникновением "дублирования"?
и еще всё таки уточните, как вы видите, что "тот же event_id, тот же пейлоад"?
ну и какую задачу реашет косумер в общем?
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868453
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha Tyurin,

Консумер самописный, он логгирует каждый полученный батч и каждый евент батча. Точно известно что батч ему был выдан.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868455
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha Tyurinи штатно ли работал сервер - база - консумер перед возникновением "дублирования"?
и еще всё таки уточните, как вы видите, что "тот же event_id, тот же пейлоад"?
ну и какую задачу реашет косумер в общем?

Все работало штатно.
Я вижу в логах что консумер вычитывает евенты батча, обрабатывает их(он логирует евенты и отсылает их на REST API удаленной системы), после этого finish_batch дает вышеописанный ворнинг. Следующий батч содержит эти же евенты(такие же ev_id, и такой же пайлоад). Отмечу что удаленная система ведет логи, и эти логи потдверждают вышеописанный сценарий.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868458
Misha Tyurin,

предположим, что кроме триггерной репликации, наши сервера имеют горячие стендбаи (оба--два, и подписчик и публикатор)
предположим, далее, что батч (его приём) накатан на упавший впоследствии праймари подписчика. (ну например).
а на стендбай подписчика -- нет (по какой-то причине).
Может ли в результате батч очиститься из очереди (на паблишере) , а на запущенном в кач-ве праймери стендбае считаться ненакаченным ?

-- очень похоже на такую историю.
(как вариант -- подписчик упал отработав , но не закоммитив накатку батча [батарейка сдохла], а паблишер почему-то её отработал, без всяких стендбаев и т.п. --Имеем -- на подписчике требуется батч, на публикаторе его нет).
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868459
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
общая логика работы такова:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Псевдокод
while true {
    batch=pgq.get_next_batch()
    for event in pgq.get_batch_events(batch) {
        if pgq_ext.is_event_done(event) 
            next;
        process(event);
        pgq_ext.set_event_done(event)
    }
    pgq.finish_batch()
}
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868460
КактузMisha Tyurinи штатно ли работал сервер - база - консумер перед возникновением "дублирования"?
и еще всё таки уточните, как вы видите, что "тот же event_id, тот же пейлоад"?
ну и какую задачу реашет косумер в общем?

Все работало штатно.
Я вижу в логах что консумер вычитывает евенты батча, обрабатывает их(он логирует евенты и отсылает их на REST API удаленной системы), после этого finish_batch дает вышеописанный ворнинг. Следующий батч содержит эти же евенты(такие же ev_id, и такой же пайлоад). Отмечу что удаленная система ведет логи, и эти логи потдверждают вышеописанный сценарий.

вам надо иисчислить потерянный батч, и катануть его дельту руками, и удалить его с подписчика. штатно это делается ресинком, но очень дорого (COPY all на диск + сравнение)
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868463
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
интересуюсьвам надо иисчислить потерянный батч, и катануть его дельту руками, и удалить его с подписчика. штатно это делается ресинком, но очень дорого (COPY all на диск + сравнение)

У меня нет репликации. У меня консумер другим занимается, прочитайте внимательно.
Проблема в том наш консумер обрабатывает евенты батча, его евенты магическим образом перемещаются в следующий.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868481
Кактуз,
да , я уже поудмал, что у вас не репликация.

под руками нет установленного pgq, -- если я верно помню -- там эти сообщения могут выкидывать plpgsql хранимки pgq-ных схем . если так -- почитайте тексты-- там станет ясно, что на самом деле у вас происходит (а не то, что вы об этом думаете).

если не так -- то придется в исходники pgq лезть -- а это уже сложнее.


я всё таки думаю, что у вас рассогласованное состояние публикатора и подписчика. и таково оно, поскольку где-то (на чьей-то стороне) не закоммитили очередную порцию. (там таки нет диспетчера распределенных транз. или я не прав ? )
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868500
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кактуз,

по вашему описанию и псевдокоду сложно что-то сказать определенно, так как очень много всего не известного.

у вас вероятно финиш батч не прошел где-то.

обращаю внимание тогда на этот кусок
https://github.com/markokr/skytools/blob/master/sql/pgq/functions/pgq.finish_batch.sql
WARNING: finish_batch...
такой варнинг -- это вот так как не нашли.
но если смотреть
https://github.com/markokr/skytools/blob/master/sql/pgq/functions/pgq.next_batch.sql

-- has already active batch
if batch_id is not null then
return;
end if;

то выглядит так, как будто у вас код где-то консумера развалился или что-то где-то "переключалось"
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868504
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha Tyurin,

> у вас вероятно финиш батч не прошел где-то.

это ни при чем.

надо смотреть как вы с транзакциями в вашем консумере обращаетесь.
почти уверен что, вы

1) открывайте транзакцию в источнике и получаете next_batch
2) ! далее не закрываете её
3) что-то делает в приемнике
4) делаете финиш в источнике
5) закрываете транзакцию в источинике

вы из питона работаете? вы уверены, что понимаете как организовали транзакции ваши на обоих концах? там в питоне абстракции курсора-коннекта-транзакции всё замучено слегка.

и вот у вас код где-то "вылетел" между 1 и 5. а так как сиквенс не транзакционен вы имеете айди новое батча, а события старые.


---
ууух, это была заявка на вангу года уже в январе!
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868514
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
точнее, по вашему "логу", вылетает у вас между 1 и 4; т. е. вы делаете финиш уже того, что "отпало" и не закомитилось.

у вас кстати источник и приемник pgq -- это разные базы?

и в каком месте и по какому принципу идет в консумере работа с "удаленная система"?
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868570
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha TyurinMisha Tyurin,

> у вас вероятно финиш батч не прошел где-то.

это ни при чем.

надо смотреть как вы с транзакциями в вашем консумере обращаетесь.
почти уверен что, вы

1) открывайте транзакцию в источнике и получаете next_batch
2) ! далее не закрываете её
3) что-то делает в приемнике
4) делаете финиш в источнике
5) закрываете транзакцию в источинике

вы из питона работаете? вы уверены, что понимаете как организовали транзакции ваши на обоих концах? там в питоне абстракции курсора-коннекта-транзакции всё замучено слегка.

и вот у вас код где-то "вылетел" между 1 и 5. а так как сиквенс не транзакционен вы имеете айди новое батча, а события старые.


---
ууух, это была заявка на вангу года уже в январе!

консумер - приложение на руби, которое читает евенты из postgresql. Работа с pgq написана максимально низкоуронево, никакой динамической генерации sql нет.
Потребитель - REST API, с которым происходит работа по http. Для каждого евента в батче, приложение дергает REST API. Если происходит ексепшн любого рода(проблемы с сетью, http ответ отличается от 200OK) приложение падает и отсылает емейл с бектрейсом, и автоматически работу не возобновляет. В случае возникновения проблемы, код между 1 и 5 не вылетает, эксепшнов не происходит, это подтверждается логами на стороне API и логами postgresql где тоже не видно эксепшнов.
Еще раз уточняю что каждый евент метится обработанным путем вызова set_event_done(), кроме того все выполняется в "режиме автокоммита", то есть явно не вызывается begin/commit, то есть каждый вызов sql - внутри своей транзакции.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868597
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кактуз,
нет, не так.

> логами postgresql где тоже не видно эксепшнов

при роллбеке никакого експешина не происходит.
вы просто не коммитете next_batch().
как уж это происходит, это вам разбираться. отлаживайте свой код на руби.

еще раз повторю вопрос: у вас источник и приемник -- это одна и та же база? это может быть важно опять же для понимания как у вас транзакция открывается/закрывается.

--
я могу вам предложить отладку на увроне pg

1) мониторте
http://www.postgresql.org/docs/9.4/static/monitoring-stats.html#PG-STAT-DATABASE-VIEW
xact_rollback

2) ! включите логи запросов на сесии работы с pgq ! --- и вы увидете как у ваз вызывается get_next_batch() и get_events() -- там будет видно, одна и та же ли это транзакция
http://www.postgresql.org/docs/9.4/static/runtime-config-logging.html
%x Transaction ID (0 if none is assigned)


и еще вам можно оч много вариантов предложить, но пока это попробуйте
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868610
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha TyurinКактуз,
нет, не так.

> логами postgresql где тоже не видно эксепшнов

при роллбеке никакого експешина не происходит.
вы просто не коммитете next_batch().
как уж это происходит, это вам разбираться. отлаживайте свой код на руби.

еще раз повторю вопрос: у вас источник и приемник -- это одна и та же база? это может быть важно опять же для понимания как у вас транзакция открывается/закрывается.

--
я могу вам предложить отладку на увроне pg

1) мониторте
http://www.postgresql.org/docs/9.4/static/monitoring-stats.html#PG-STAT-DATABASE-VIEW
xact_rollback

2) ! включите логи запросов на сесии работы с pgq ! --- и вы увидете как у ваз вызывается get_next_batch() и get_events() -- там будет видно, одна и та же ли это транзакция
http://www.postgresql.org/docs/9.4/static/runtime-config-logging.html
%x Transaction ID (0 if none is assigned)


и еще вам можно оч много вариантов предложить, но пока это попробуйте

Я уже несколько раз написал, что приемник это HTTP REST API - это не база данных, а внешний сервис, работающий по протоколу http, он не поддерживает транзакции и атомарно обрабатывает только один запрос. Именно потому евенты обрабатываются поодному. Транзакции у меня не открываются/закрываются явно(приложение не вызывает begin/commit). Каждый вызов любой хранимки связанной с pgq происходит в своей транзакции, которая неявно начинается и коммитится, в одной транзакции выполняется только один statement. Я отлично знаю про возможности логгирования pg, проблема в том что на данный момент несколько сложно записать логи по причине их объема, а проблема повторяется нечасто и только с одним инстансом. В тестовом окружении, с теми же версиями кода проблема не повторяется. Логгирование SQL, в тестовом окружении не показывает ни единого begin/commit/rollback которые выполняло бы приложение.
Код: sql
1.
2.
3.
4.
5.
6.
2015-01-31 19:37:14.374 UTC-sandbox-1.1.1.1@sandbox_db-54cd2eba.7aa8 LOG:  statement: SELECT pgq.next_batch('routeserver', 'routeserver')
2015-01-31 19:37:14.875 UTC-sandbox-1.1.1.1@sandbox_db-54cd2eba.7aa8 LOG:  statement: SELECT pgq.next_batch('routeserver', 'routeserver')
2015-01-31 19:37:14.881 UTC-sandbox-1.1.1.1@sandbox_db-54cd2eba.7aa8 LOG:  statement: SELECT * FROM pgq.get_batch_events(185641) WHERE pgq_ext.is_event_done('routeserver', 185641, ev_id) = false ORDER BY ev_id
2015-01-31 19:37:14.889 UTC-sandbox-1.1.1.1@sandbox_db-54cd2eba.7aa8 LOG:  statement: SELECT pgq.finish_batch(185641)
2015-01-31 19:37:14.893 UTC-sandbox-1.1.1.1@sandbox_db-54cd2eba.7aa8 LOG:  statement: SELECT pgq.next_batch('routeserver', 'routeserver')
2015-01-31 19:37:15.394 UTC-sandbox-1.1.1.1@sandbox_db-54cd2eba.7aa8 LOG:  statement: SELECT pgq.next_batch('routeserver', 'routeserver')


54cd2eba.7aa8 - id сессии, а не транзакции.

Ваш посыл я понял - next_batch() незакоммичен, а get_batch_events сработал потому что был с ним в единой транзакции, я в 100500й раз проверю этот вариант, но сложно проверить что один и тот же код внезапно стал явно начинать транзакции, если он был написаен чтобы этого не делать, и в тестовом окружении этого не делает. Не пишите пожалуйста очевидных вещей типа, как логгировать запросы в пг.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868615
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha Tyurin,
Специально логи с тестового окружения, где работает этот же код. log_line_prefix = '%m-%u-%h@%d-%c-%x-%v '
У каждой строки свой virtual transaction id. transaction_id везде 0, тк явно транзакция не начата.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
2015-01-31 19:56:13.749 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428930 LOG:  statement: SELECT pgq.next_batch('routeserver', 'routeserver')
2015-01-31 19:56:13.780 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428931 LOG:  statement: SELECT * FROM pgq.get_batch_events(185666) WHERE pgq_ext.is_event_done('routeserver', 185666, ev_id) = false ORDER BY ev_id
2015-01-31 19:56:13.784 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428932 LOG:  statement: SELECT pgq_ext.is_event_done('routeserver', 185666, '2093145')
2015-01-31 19:56:13.806 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428933 LOG:  statement: SELECT pgq_ext.set_event_done('routeserver', 185666, '2093145')
2015-01-31 19:56:13.808 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428934 LOG:  statement: SELECT pgq_ext.is_event_done('routeserver', 185666, '2093146')
2015-01-31 19:56:13.842 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428935 LOG:  statement: SELECT pgq_ext.set_event_done('routeserver', 185666, '2093146')
2015-01-31 19:56:13.844 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428936 LOG:  statement: SELECT pgq_ext.is_event_done('routeserver', 185666, '2093147')
2015-01-31 19:56:13.864 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428937 LOG:  statement: SELECT pgq_ext.set_event_done('routeserver', 185666, '2093147')
2015-01-31 19:56:13.866 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428938 LOG:  statement: SELECT pgq_ext.is_event_done('routeserver', 185666, '2093148')
2015-01-31 19:56:13.899 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428939 LOG:  statement: SELECT pgq_ext.set_event_done('routeserver', 185666, '2093148')
2015-01-31 19:56:13.902 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428940 LOG:  statement: SELECT pgq_ext.is_event_done('routeserver', 185666, '2093149')
2015-01-31 19:56:13.923 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428941 LOG:  statement: SELECT pgq_ext.set_event_done('routeserver', 185666, '2093149')
2015-01-31 19:56:13.926 UTC-sandbox-1.1.1.1@sandbox_db-54cd328d.7c78-0-5/428942 LOG:  statement: SELECT pgq.finish_batch(185666)
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868621
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кактуз,

у вас одна база. тааак.
а через что и как вы коннектитись к pg? есть ли разница между боевым окружением и тестовым?

какая там среда, библиотеки? как там "автокоммит" выставляется?
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868623
Кактуз
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha TyurinКактуз,

у вас одна база. тааак.
а через что и как вы коннектитись к pg? есть ли разница между боевым окружением и тестовым?

какая там среда, библиотеки? как там "автокоммит" выставляется?

Автокоммит по дефолту, используется ActiveRecord, но вся работа с pgq сделана сырыми запросами, без всякого "интеллекта" фреймворка.
Разница продакшна и сендбокса только в данных и нагрузке. Ну и в том что на одном из продакшн инстансов наблюдается вышеописанная проблема.
Когда проблема возникла я сразу начал проверять именно приложение, однако в нем проблем на нашел.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868626
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кактуз,

ну пока не сильно картина проясняется.

> на одном из продакшн инстансов

вот там и надо логи смотреть.
...
Рейтинг: 0 / 0
Дублирование ивентов PgQ
    #38868636
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT pgq.next_batch('routeserver', 'routeserver')
SELECT pgq.next_batch('routeserver', 'routeserver')
SELECT * FROM pgq.get_batch_events(185641) WHERE pgq_ext.is_event_done('routeserver', 185641, ev_id) = false ORDER BY ev_id
SELECT pgq.finish_batch(185641)
SELECT pgq.next_batch('routeserver', 'routeserver')
SELECT pgq.next_batch('routeserver', 'routeserver')


вот это тоже у вас какой-то интересный пример. это реальный лог?
где обработка то событий? или вы её вы просто не привели?

батч айди вернулся, а события уже все были отработаны?
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Дублирование ивентов PgQ
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]