zubkov-andrei / pg_profile

Postgres historic workload reports
Other
212 stars 31 forks source link

take_sample_subset. Не получение или получение выборки дважды при параллельном запуске #94

Open vut12 opened 1 month ago

vut12 commented 1 month ago

Конфигурация

Отдельная машина для репозитория pg_profile. Version
PostgreSQL 15.7
dblink 1.2
pg_cron 1.6.2
pg_profile 4.6

pg_cron. 20 заданий для параллельного получения снимков каждые 30 минут:

SELECT cron.schedule('pg_profile-take_sample-gr01', '*/30 * * * *', $$CALL take_sample_subset(20,0)$$);
SELECT cron.schedule('pg_profile-take_sample-gr02', '*/30 * * * *', $$CALL take_sample_subset(20,1)$$);
SELECT cron.schedule('pg_profile-take_sample-gr03', '*/30 * * * *', $$CALL take_sample_subset(20,2)$$);
SELECT cron.schedule('pg_profile-take_sample-gr04', '*/30 * * * *', $$CALL take_sample_subset(20,3)$$);
SELECT cron.schedule('pg_profile-take_sample-gr05', '*/30 * * * *', $$CALL take_sample_subset(20,4)$$);
...
SELECT cron.schedule('pg_profile-take_sample-gr20', '*/30 * * * *', $$CALL take_sample_subset(20,19)$$);

pg_profile. Добавлено 10 серверов с которых собираются снимки.

Проблема

При каждом запуске заданий у случайных серверов получение выборки может запустится дважды с интервалом в несколько секунд или вовсе не запустится. Выглядит это так (внимание на время 12:30, 13:00, 15:30, 16:00):

select * from samples where server_id=13 order by sample_time desc;
 server_id | sample_id |      sample_time       
-----------+-----------+------------------------
        13 |      1865 | 2024-05-19 17:30:00+03
        13 |      1864 | 2024-05-19 17:00:00+03
        13 |      1863 | 2024-05-19 16:30:02+03
        13 |      1862 | 2024-05-19 16:00:01+03
        13 |      1861 | 2024-05-19 16:00:00+03
        13 |      1860 | 2024-05-19 15:30:01+03
        13 |      1859 | 2024-05-19 15:30:00+03
        13 |      1858 | 2024-05-19 15:00:01+03
        13 |      1857 | 2024-05-19 14:30:00+03
        13 |      1856 | 2024-05-19 14:00:00+03
        13 |      1855 | 2024-05-19 13:30:02+03
        13 |      1854 | 2024-05-19 12:30:03+03
        13 |      1853 | 2024-05-19 12:30:00+03
        13 |      1852 | 2024-05-19 12:00:00+03

Причина

Отсутствие сортировки в оконной функции в курсоре, определяющем подмножество серверов. Функция take_sample_subset:

c_servers CURSOR FOR
  SELECT server_id,server_name FROM (
      SELECT server_id,server_name, row_number() OVER () AS srv_rn
      FROM servers WHERE enabled
      ) AS t1
  WHERE srv_rn % sets_cnt = current_set;

Поэтому каждый запуск "row_number() OVER ()" может выдать разный результат. Это заметно во время параллельного получения выборок с нескольких серверов, когда таблица servers обновляется.

Решение

Добавить сортировку: "row_number() OVER (ORDER BY server_id)"

zubkov-andrei commented 1 month ago

Добрый день! Большое спасибо за обнаружение ошибки и детальное исследование!

vut12 commented 2 weeks ago

Аналогичная ситуация в функции take_subsample_subset.