В четверг 10 октября 2024 г. в 13:10 завершился вебинар "Инструменты миграции: подходы к переносу данных"
Вебинар провели Роман Лавринчук и Александр Любушкин. Программа вебинара https://forsd.ru/migration_webcast_october
Запись вебинара будет опубликована позже. Следите за нашими новостями.
Приглашаем на вебинар "Обзор продуктов компании Axiom " (четверг 24 октября 2024 г. в 12:00).
Тема: импортозамещение в области корпоративной Java-разработки: JDK, сервер приложений, контейнеры Docker
Докладчик: Иван Диканев. Программа вебинара и регистрация: https://forsd.ru/axiom_24web

Свободное место после vacuum FULL

«Пост-Грэс-Кью-Эл» свободная объектно-реляционная СУБД. Обмениваемся вопросами и ответами о её работе.
Ответить
SShumeev
Сообщения: 5
Зарегистрирован: Ср июн 01, 2022 5:59 pm

Свободное место после vacuum FULL

Сообщение SShumeev »

Добрый день!

Сколько свободного места остается в таблице после vacuum (FULL, VERBOSE, ANALYZE) ?

На таблице размером 34 GB остается free_percent= 7.4

Считаю pgstattuple.

Это нормальное поведение vacuum FULL ?

Есть мин мах оценки free_percent после vacuum FULL ?

Как\где образуется это свободное пространство ?
AntonS
Сообщения: 97
Зарегистрирован: Пт июн 03, 2022 8:51 am

Re: Свободное место после vacuum FULL

Сообщение AntonS »

Из документации:
1. Модуль pgstattuple предоставляет функции получения статистики на уровне кортежей (версий строк). Одноименная функция pgstattuple возвращает физическую длину отношения, процент «мёртвых» кортежей и другую информацию. Столбец результата free_percent показывает процент свободного пространства.

2. Команда VACUUM FULL это режим «полной» очистки, который берет исключительную блокировку таблицы, так как он записывает новую копию таблицы и не освобождает старую до своего завершения.

Таблицы и индексы в PostgreSQL хранятся в файлах, которые содержат страницы. Размеры областей страниц можно получить с помощью расширения pageinspect.
На рисунке в книге Егора Рогова PostgreSQL 16 изнутри показано размещение внутри областей страниц. Свободное место, которое также отмечается в карте свободного пространства, расположено между массивом указателей и версиями строк:
page_areas.jpg
page_areas.jpg (19.79 КБ) 2671 просмотр

При обращениях к таблице, например при обычном чтении или модификации, может выполняться быстрая внутристраничная очистка. Версии строк, оставшиеся после очистки, физически сдвигаются в сторону старших адресов страницы так, чтобы все свободное место было представлено одним непрерывным куском.

Наконец, когда в таблицу приходит обычная очистка VACUUM или автоочистка AUTOVACUUM и удаляются ненужные версии строк, то появляется свободное место, которое записывается в карту свободного пространства, иногда страница может освободиться целиком. Если в конце файла образуются несколько свободных страниц, то перед завершениеем работы VACUUM может отрезать конец файла и таким образом вернуть свободное место операционной системе.

Если свободных страниц нет или они расположены не в конце файла, то СУБД PostgreSQL свободное место операционной системе не возвращает.
SShumeev
Сообщения: 5
Зарегистрирован: Ср июн 01, 2022 5:59 pm

Re: Свободное место после vacuum FULL

Сообщение SShumeev »

Может ли быть : длина строки чуть более половины свободного места под строки на странице -
тогда неиспользуемое свободное пространство - почти 50 % ?
roruizi
Сообщения: 5
Зарегистрирован: Ср июн 01, 2022 4:43 pm

Re: Свободное место после vacuum FULL

Сообщение roruizi »

Ну, во первых по умолчанию просто так сделать не получится (одной строкой забить 50% места на странице).
Для больших строк PostgreSQL использует механизм TOAS, детали ниже по ссылкам
https://postgrespro.ru/docs/postgresql/10/storage-toast
https://www.crunchydata.com/blog/postgr ... iced-bread

Этот механизм активно мешает забить страницу большими строками.
Но эту ситуацию можно принудительно воспроизвести

Код: Выделить всё

CREATE TABLE test (c1 text);
ALTER TABLE test ALTER c1 SET STORAGE PLAIN;  -- важно, без этого фокус не получится

INSERT INTO test (c1) SELECT rpad('c',4097,'x');

SELECT * FROM pgstattuple('test') \gx
-[ RECORD 1 ]------+------
table_len          | 8192
tuple_count        | 1
tuple_len          | 4125
tuple_percent      | 50.35
dead_tuple_count   | 0
dead_tuple_len     | 0
dead_tuple_percent | 0
free_space         | 4032
free_percent       | 49.22


INSERT INTO test (c1) SELECT rpad('c',4097,'x');
SELECT * FROM pgstattuple('test') \gx
-[ RECORD 1 ]------+------
table_len          | 16384
tuple_count        | 2
tuple_len          | 8250
tuple_percent      | 50.35
dead_tuple_count   | 0
dead_tuple_len     | 0
dead_tuple_percent | 0
free_space         | 8064
free_percent       | 49.22
Ответить