pg_stat_statements в YugabyteDB

В YugabyteDB, распределенной SQL базе данных, использующей PostgreSQL, расширение pg_stat_statements установлено по умолчанию. Однако утверждения собираются локально в каждом узле, что означает, что вам нужно запросить pg_stat_statements или вызвать pg_stat_statements_reset() на каждом узле. YugabyteDB является “облачной”, вы можете добавлять и удалять узлы. При использовании YugabyteDB Managed или YugabyteDB Anywhere это делается автоматически. Если вы используете YugabyteDB бесплатно, вы должны автоматизировать это.

Здесь я показываю простой способ сделать это.

Сначала создадим таблицу, в которой будут храниться выписки, собранные со всех узлов, с указанием host, с которого они получены, и ts – метки времени, когда они были собраны:

drop table if exists ybwr_statements ;
create table ybwr_statements  as
select now() as ts,'' as host, * 
from pg_stat_statements where null is not null;
Войти в полноэкранный режим Выход из полноэкранного режима

Использование Create Table As Select делает его независимым от структуры таблицы, которая может меняться в зависимости от версии.

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

  • Я запрашиваю список серверов из yb_servers().
  • Я использую COPY TO PROGRAM для выполнения ysqlsh, эквивалента psql, который присутствует на каждом узле.
  • Я нахожу его из файла postmaster.opts. Вы также можете найти его или получить из рабочего каталога yb-tserver.
  • Я запускаю insert into ybwr_statements select '%s','%s',* from pg_stat_statements, который я передаю как STDIN в ysqlsh через COPY TO, поскольку мне все равно нужен входной запрос.
  • Я также сбрасываю pg_stat_statements_reset(), если сбор проходит успешно (вызывая ysqlsh с -v ON_ERROR_STOP=1).
  • для отладки я добавляю > /tmp/log.txt 2>&1 в конец командной строки. Вы можете предпочесть использовать COPY FROM PROGRAM, передавая запросы с помощью -c, и хранить вывод в таблице.

Вот как это делается:

do $DO$
declare i record;
begin
for i in (select now() as ts, host from yb_servers()) loop
 execute format(
  $COPY$
  copy (select $SQL$ insert into ybwr_statements select '%s','%s',* from pg_stat_statements; select pg_stat_statements_reset(); $SQL$ ) to program
   $BASH$ $(awk '{sub("/postgres/bin/postgres .*","");print}' ./postmaster.opts)/bin/ysqlsh -h $(hostname) -v ON_ERROR_STOP=1 $BASH$
  $COPY$
 ,i.ts,i.host);
end loop;
end;
$DO$
;
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем вы можете запросить ybwr_statements:

select ts, host, calls, total_time, query 
from ybwr_statements 
order by total_time;
Войти в полноэкранный режим Выйти из полноэкранного режима

Вот пример на незанятой базе данных, где я захватил только свои запросы на захват:

Это пример для демонстрации техники. Вы можете запланировать его, например, каждый час, и у вас будут ежечасные снимки запросов в таблице ybwr_statements. Вы можете не вызывать pg_stat_statements_reset() и будете различать снимки при выполнении запросов.

Оцените статью
Procodings.ru
Добавить комментарий