zubkov-andrei / pg_profile

Postgres historic workload reports
Other
212 stars 31 forks source link

Как отслеживать результат выполнения take_sample() #56

Closed triwada closed 1 year ago

triwada commented 1 year ago

Возник вопрос, как отслеживать результат выполнения take_sample().

Вызов take_sample() осуществляется, например, из bash-скрипта


    if ! is_replica
    then
        PGOPTIONS='--statement-timeout=5min' psql -AXt -c "select  profile.take_sample()"
        [ $? -ne 0 ] && exit 1
    fi

Вот только такое решение не позволяет отследить возникновение ошибки при вызове select profile.take_sample(), т.к. функция отработала с ошибкой, снимок не создался, а exit code получили такой, что как будто проблемы нет.

ниже bash - x от запуска того скрипта (сама ошибка в данном случае не важна, она могла быть любой другой)

+ PGOPTIONS=--statement-timeout=5min
+ psql -AXt -c 'select  profile.take_sample()'
(test,"permission denied for tablespace pg_global
while executing query on dblink connection named ""server_connection""
SQL statement ""INSERT INTO last_stat_tablespaces(
      server_id,
      sample_id,
      tablespaceid,
      tablespacename,
      tablespacepath,
      size,
      size_delta
    )
    SELECT
      sserver_id,
      s_id,
      dbl.tablespaceid,
      dbl.tablespacename,
      dbl.tablespacepath,
      dbl.size AS size,
      dbl.size_delta AS size_delta
    FROM dblink('server_connection', server_query)
    AS dbl (
        tablespaceid            oid,
        tablespacename          name,
        tablespacepath          text,
        size                    bigint,
        size_delta              bigint
    )""
PL/pgSQL function take_sample(integer,boolean) line 620 at SQL statement
PL/pgSQL function take_sample_subset(integer,integer) line 27 at assignment
SQL function ""take_sample"" statement 1
",00:00:00.07)
+ '[' 0 -ne 0 ']'
triwada commented 1 year ago

как вариант можно добавить в мониторинг время последнего создания сэмпла, но тогда при большом размере таблицы profile.samples явно нужен индекс по sample_time

postgres=# explain (analyze,buffers) select max(sample_time) from profile.samples where sample_time>now()-interval'1d';
                                                QUERY PLAN
----------------------------------------------------------------------------------------------------------
 Aggregate  (cost=57.19..57.20 rows=1 width=8) (actual time=0.613..0.614 rows=1 loops=1)
   Buffers: shared hit=14
   ->  Seq Scan on samples  (cost=0.00..57.16 rows=15 width=8) (actual time=0.589..0.605 rows=72 loops=1)
         Filter: (sample_time > (now() - '1 day'::interval))
         Rows Removed by Filter: 2451
         Buffers: shared hit=14
 Planning time: 0.119 ms
 Execution time: 0.636 ms
(8 строк)
zubkov-andrei commented 1 year ago

Добрый день! Конкретную реализацию я вам прямо сейчас не предложу, в значительной степени это будет завитель от вашего скрипта и механизмов информирования. Думаю, вам следует анализировать не только код возврата psql, но еще и содержание stdout. Для упрощения такого анализа, надо исполнять запрос, который будет возвращать легко анализируемый ответ, например, так:

psql -Aqtc "select count(*) from take_sample() WHERE result IS DISTINCT FROM 'OK'"

Выводом будет число серверов, для которых выполнение снимка оказалось неудачным.

triwada commented 1 year ago

Спасибо за совет, попробую воспользоваться.

Возник ещё один вопрос: т.к. в таблице servers есть поле last_sample_id, то может стоит добавить в эту же таблицу и last_sample_time ИЛИ/И last sample result?

zubkov-andrei commented 1 year ago

Поле last_sample_id таблицы servers используется в качестве текущего значения последовательности, хранить там еще и время никакого смысла нет, поскольку при необходимости его легко можно получить из таблицы samples. Хранение результата выполнения снимка не имеет смысла, потому что в большинстве случаев при ошибке снимок не создаётся и привязать его ошибку будет не к чему.

triwada commented 1 year ago

При относительно большой таблице samples без индекса по sample_time - на так уже и легко. Раз last_sample_id обновляется при каждом "удачном" создании сэмпла, то не проще ли сразу сохранить last_sample_time дополнительно в таблице servers? Вроде накладных расходов не так много, зато удобно.

zubkov-andrei commented 1 year ago

Позвольте, индекс по sample_time есть: core.sql:26 Другой вопрос что это составной индекс, и чтобы его использовать нужен еще идентификатор сервера. Но без идентификатора сервера поиск по времени видится мне лишенным смысла.

triwada commented 1 year ago

Позвольте, индекс по sample_time есть: core.sql:26 Проглядел. Тогда вопросов больше нет. Спасибо за ответы.