linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/lessons/pg-lab-13-1-hot-fillfactor

lesson ── postgres-labs ── ~22 мин ── 5 шагов

Поймай HOT-обновление и поиграй с fillfactor

UPDATE в PostgreSQL не меняет строку на месте - он пишет новую версию. HOT-обновление делает это, не трогая индексы, если индексируемые колонки не изменились и в странице есть место. Сейчас ты поймаешь оба случая по счётчикам pg_stat_all_tables и увидишь, как fillfactor возвращает обновления в HOT-русло.

Подключись к базе: psql на клиент-ноде настроен на базу lab. Перед каждым шагом сначала предскажи, что покажет счётчик, потом проверь.

▶ интерактивный sandbox

Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.

запустить sandbox →

stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Собери таблицу с индексом и сбрось статистику

    sql
    CREATE TABLE acc (id int PRIMARY KEY, balance int, note text);
    CREATE INDEX acc_note_idx ON acc (note);
    INSERT INTO acc VALUES (1, 100, 'alice');
    SELECT pg_stat_reset();

    Индекс по note нам нужен, чтобы было что «ломать»: пока мы не трогаем note, обновления остаются HOT.

    ✓ Таблица и два индекса (pkey + note) на месте, счётчики обнулены.

  2. 02

    Обнови неиндексируемую колонку — это должно быть HOT

    sql
    UPDATE acc SET balance = 200 WHERE id = 1;
    SELECT n_tup_upd, n_tup_hot_upd
    FROM pg_stat_all_tables WHERE relname = 'acc';

    balance не входит ни в один индекс, строка маленькая, место в странице есть. Предскажи: вырастет ли n_tup_hot_upd?

    подсказка

    Статистика обновляется чуть позже коммита - если счётчик ещё ноль, повтори SELECT.

    ✓ Обновление осталось HOT — индексы не тронуты.

  3. 03

    Обнови индексируемую колонку — сломай HOT

    sql
    UPDATE acc SET note = 'alice2' WHERE id = 1;
    SELECT n_tup_upd, n_tup_hot_upd
    FROM pg_stat_all_tables WHERE relname = 'acc';

    note входит в acc_note_idx, значит индекс обязан получить новую запись - это уже не HOT. Предскажи: какой счётчик вырастет, а какой нет?

    ✓ n_tup_upd обогнал n_tup_hot_upd — последний UPDATE не был HOT.

  4. 04

    Вскрой страницу и найди следы версий

    Сделаем серию HOT-обновлений и заглянем в страницу через pageinspect.

    sql
    UPDATE acc SET balance = balance + 1 WHERE id = 1;
    UPDATE acc SET balance = balance + 1 WHERE id = 1;
    UPDATE acc SET balance = balance + 1 WHERE id = 1;
    SELECT balance FROM acc WHERE id = 1;   -- чтение может запустить prune
    SELECT lp, lp_flags, t_ctid
    FROM heap_page_items(get_raw_page('acc', 0));

    Найди указатели: lp_flags = 1 (LP_NORMAL) ведут к версиям, lp_flags = 2 (LP_REDIRECT) - след HOT-цепочки, оставленный prune.

    подсказка

    Redirect появляется не всегда сразу — он результат внутристраничной очистки.

    ✓ Страница прочитана — ты видишь указатели и их статусы своими глазами.

  5. 05

    Снизь fillfactor и убедись, что он применился

    fillfactor оставляет в странице резерв под новые версии. Поставим 70% и перепишем таблицу, чтобы настройка подействовала на её страницы.

    sql
    ALTER TABLE acc SET (fillfactor = 70);
    VACUUM FULL acc;   -- переписывает таблицу с новым fillfactor
    SELECT reloptions FROM pg_class WHERE relname = 'acc';

    На живой таблице fillfactor действует только на новые страницы; VACUUM FULL переписал существующие, так что резерв появился сразу.

    ✓ fillfactor=70 записан — 30% страницы теперь в резерве под HOT.

Что ты узнал

HOT-обновление не пишет в индексы, если индексируемые колонки не изменились и версия влезает в страницу. Счётчики n_tup_upd и n_tup_hot_upd показывают, остаётся ли UPDATE в HOT-русле, а fillfactor резервирует место под новые версии.

команды

  • SELECT n_tup_upd, n_tup_hot_upd FROM pg_stat_all_tables WHERE relname='acc';доля HOT-обновлений
  • ALTER TABLE acc SET (fillfactor = 70);резерв под HOT-версии
  • SELECT lp, lp_flags FROM heap_page_items(get_raw_page('acc',0));статусы указателей страницы

концепции

  • · HOT-обновление не трогает индексы и складывает версии в цепочку внутри страницы
  • · индексируемая колонка в UPDATE или нехватка места ломают HOT
  • · fillfactor ниже 100 оставляет резерв и применяется только к новым страницам

← предыдущая

Поймай SELECT, который пишет

следующая →

Заставь долгую транзакцию держать мусор всей базы

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки