Я хочу понять приведенное ниже поведение результата для поиска размера таблицы с x МБ при попытке подсчитать записи в этой таблице, но не найдено записей в базе данных postgres
db_server=# \dt+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------------------------------+-------+---------+------------+-------------
user | table | table | user | 7592 MB |
db_server=# select count(*) from table ;
count
-------
0
Скорее всего, это раздутие
(мертвые кортежи).
Из описания VACUUM
(https://www.postgresql.org/docs/13/sql-vacuum.html):
VACUUM восстанавливает память, занятую мертвыми кортежами. В обычной работе PostgreSQL кортежи, удаленные или устаревшие в результате обновления, физически не удаляются из своей таблицы; они остаются до тех пор, пока не будет выполнен ВАКУУМ. Поэтому необходимо периодически делать VACUUM, особенно на часто обновляемых таблицах.
Есть несколько сложных запросов, чтобы сообщить об этом здесь: https://wiki.postgresql.org/wiki/Show_database_bloat
Это тоже информативно: https://www.percona.com/blog/2018/08/06/basic-understanding-bloat-vacuum-postgresql-mvcc/
VACUUM
должен очистить его. .
Короче говоря, это происходит, когда вы вставляете данные, а затем обновляете или удаляете их. Удаленное пространство не освобождается, потому что оно может понадобиться более старым транзакциям. Обновление выполняется как копирование при записи
, поскольку для более старых транзакций могут потребоваться более старые данные. Еще одним фактором является то, что данные организованы в страницы по 8 КБ. Страница должна быть пустой, чтобы обычный VACUUM
освободил ее. Если страница частично используется, то только VACUUM FULL
может восстановить это пространство, но эта операция занимает больше времени, требует временного пространства и блокирует таблицу, насколько я помню.
Также должен быть запущен процесс autovacuum
, который должен очистить это в какой-то момент. автоочистка
включена по умолчанию, начиная с версии 8.3.