Перейти к основному содержимому

Мониторинг производительности

  1. Включите сбор данных по нагрузке на подсистему ввода-вывода.

    postgres@monman_db=# ALTER SYSTEM SET track_io_timing TO on;
    ALTER SYSTEM

    Перезагрузите конфигурацию.

    postgres@monman_db=# SELECT pg_reload_conf();
    pg_reload_conf
    ----------------
    t
    (1 row)

    Параметр track_io_timing включен — теперь планировщик собирает статистику времени операций ввода-вывода.

  2. Подготовьте таблицы для проведения нагрузочного тестирования утилитой pgbench.

    postgres@monman_db=# \! pgbench -i monman_db
    Разбор команды

    • \! — метакоманда psql, которая передает следующую команду оболочке ОС;
    • pgbench -i monman_db — инициализация базы данных monman_db таблицами pgbench: создание таблиц и заполнение тестовыми данными.
    dropping old tables...
    NOTICE: table "pgbench_accounts" does not exist, skipping
    NOTICE: table "pgbench_branches" does not exist, skipping
    NOTICE: table "pgbench_history" does not exist, skipping
    NOTICE: table "pgbench_tellers" does not exist, skipping
    creating tables...
    generating data (client-side)...
    100000 of 100000 tuples (100%) done (elapsed 0.18 s, remaining 0.00 s)
    vacuuming...
    creating primary keys...
    done in 0.38 s (drop tables 0.01 s, create tables 0.02 s, client-side generate 0.25 s, vacuum 0.03 s, primary keys 0.07 s).

    Проверьте созданные таблицы.

    postgres@monman_db=# \d
    List of relations
    Schema | Name | Type | Owner
    --------+------------------+----------+----------
    public | fatab | table | postgres
    public | fatab_id_seq | sequence | postgres
    public | pgbench_accounts | table | postgres
    public | pgbench_branches | table | postgres
    public | pgbench_history | table | postgres
    public | pgbench_tellers | table | postgres
    (6 rows)

    В схеме public появились таблицы pgbench_accounts, pgbench_branches, pgbench_history и pgbench_tellers — готовые к нагрузочному тестированию.

  3. Сбросьте накопленную кумулятивную статистику.

    postgres@monman_db=# SELECT pg_stat_reset();
    pg_stat_reset
    ---------------
    (1 row)
    postgres@monman_db=# SELECT pg_stat_reset_shared('bgwriter');
    pg_stat_reset_shared
    ----------------------
    (1 row)

    Сброс статистики позволяет собрать чистые метрики без влияния предыдущих операций.

  4. Запустите нагрузочное тестирование на 30 секунд.

    postgres@monman_db=# \! pgbench -T30 monman_db
    Разбор команды

    • \! — метакоманда psql для выполнения команды оболочки ОС;
    • pgbench -T30 monman_db — запуск нагрузочного тестирования базы monman_db на длительность 30 секунд.
    pgbench (15.5)
    starting vacuum...end.
    transaction type: <builtin: TPC-B (sort of)> scaling factor: 1
    query mode: simple
    number of clients: 1
    number of threads: 1
    maximum number of tries: 1
    duration: 30 s
    number of transactions actually processed: 9985
    number of failed transactions: 0 (0.000%)
    latency average = 3.003 ms
    initial connection time = 21.177 ms
    tps = 333.035253 (without initial connection time)

    За 30 секунд было выполнено 9985 транзакций без ошибок — средняя производительность составила 333 TPS при задержке 3 мс на транзакцию.

  5. Получите собранную статистику по строкам таблицы pgbench_tellers.

    postgres@monman_db=# SELECT * FROM pg_stat_all_tables WHERE relid = 'pgbench_tellers'::regclass \gx
    Разбор команды

    • SELECT * FROM pg_stat_all_tables — выборка всех полей из представления статистики таблиц;
    • WHERE relid = 'pgbench_tellers'::regclass — фильтрация по OID таблицы; приведение ::regclass преобразует текстовое имя в OID;
    • \gx — метакоманда psql, выводящая результат в расширенном виде (одно поле на строку).
    -[ RECORD 1 ]-----------+------------------------------
    relid | 16485
    schemaname | public
    relname | pgbench_tellers
    seq_scan | 9985
    seq_tup_read | 99850
    idx_scan | 0
    idx_tup_fetch | 0
    n_tup_ins | 0
    n_tup_upd | 9985
    n_tup_del | 0
    n_tup_hot_upd | 9985
    n_live_tup | 10
    n_dead_tup | 0
    n_mod_since_analyze | 0
    n_ins_since_vacuum | 0
    last_vacuum | 2024-11-11 09:05:49.584207+03
    last_autovacuum | 2024-11-11 09:07:02.217142+03
    last_analyze
    last_autoanalyze | 2024-11-11 09:07:02.217678+03
    vacuum_count | 1
    autovacuum_count | 2
    analyze_count | 0
    autoanalyze_count | 2

    За время тестирования над таблицей было выполнено 9985 последовательных сканирований (seq_scan) и 9985 обновлений строк (n_tup_upd). Все 9985 обновлений были HOT-обновлениями (n_tup_hot_upd), что означает обновление на месте без создания новых версий для индексов. Количество мертвых строк (n_dead_tup) равно 0 — автоочистка успешно обработала таблицу.

  6. Получите статистику по вводу-выводу для этой же таблицы.

    postgres@monman_db=# SELECT * FROM pg_statio_all_tables WHERE relid = 'pgbench_tellers'::regclass \gx
    Разбор команды

    • SELECT * FROM pg_statio_all_tables — выборка статистики ввода-вывода для всех таблиц;
    • WHERE relid = 'pgbench_tellers'::regclass — фильтрация по OID таблицы;
    • \gx — вывод в расширенном формате.
    -[ RECORD 1 ]-----+----------------
    relid | 16445
    schemaname | public
    relname | pgbench_tellers
    heap_blks_read | 0
    heap_blks_hit | 29981
    idx_blks_read | 1
    idx_blks_hit | 3
    toast_blks_read |
    toast_blks_hit |
    tidx_blks_read |
    tidx_blks_hit |

    Страницы с данными таблицы (heap_blks_read = 0) не считывались с диска — все 29981 обращение были удовлетворены из кеша (heap_blks_hit). Это означает, что данные таблицы полностью помещались в буферный кеш.

  7. Получите статистику по всей БД.

    postgres@monman_db=# SELECT * FROM pg_stat_database WHERE datname = 'monman_db' \gx
    -[ RECORD 1 ]-----------------+------------------------------
    datid | 16441
    datname | monman_db
    numbackends | 1
    xact_commit | 10091
    xact_rollback | 2
    blks_read | 373
    blks_hit | 165602
    tup_returned | 160090
    tup_fetched | 22585
    tup_inserted | 9991
    tup_updated | 29976
    tup_deleted | 0
    conflicts | 0
    temp_files | 0
    temp_bytes | 0
    deadlocks | 0
    checksum_failures | 0
    checksum_last_failure |
    blk_read_time | 6.067
    blk_write_time | 0
    session_time | 1178339.251
    active_time | 22034.291
    idle_in_transaction_time | 4911.254
    sessions | 2
    sessions_abandoned | 0
    sessions_fatal | 0
    sessions_killed | 0
    stats_reset | 2024-11-11 08:58:34.874476+03

    За сессию было зафиксировано 10091 транзакция (xact_commit) и 2 отката (xact_rollback). Соотношение попаданий в кеш (blks_hit = 165602) к чтениям с диска (blks_read = 373) высокое — кэш эффективно обслуживал запросы.

  8. Измените все строки таблицы fatab и снова получите из кумулятивной статистики количество измененных строк в БД.

    Выполните массовое обновление.

    postgres@monman_db=# UPDATE fatab SET nme = 0;
    UPDATE 100000

    Проверьте актуальное значение счетчика обновленных строк.

    postgres@monman_db=# SELECT tup_updated FROM pg_stat_database WHERE datname = 'monman_db';
    tup_updated
    -------------
    129979
    (1 row)

    Новое значение счетчика tup_updated равно 129979. Прежнее значение было 29979 — разница ровно 100000, что соответствует количеству измененных строк в таблице fatab.

Самопроверка​

Вопрос 1

Что означает значение heap_blks_read = 0?

Вопрос 2

В сеансе psql выполнены команды:

postgres@monman_db=# SELECT tup_updated FROM pg_stat_database WHERE datname = 'monman_db';
 tup_updated
-------------
      29979
(1 row)

postgres@monman_db=# UPDATE fatab SET nme = 0;
UPDATE 100000

postgres@monman_db=# SELECT tup_updated FROM pg_stat_database WHERE datname = 'monman_db';
 tup_updated
-------------
     129979
(1 row)

Почему значение tup_updated увеличилось ровно на 100000?

Вопрос 3

Какие представления относятся к кумулятивной статистике?