dead row (dead tuple)
A row version PostgreSQL has marked as no longer visible: an UPDATE writes a new version and marks the old one dead, a DELETE simply marks it dead. Nothing is removed at the time, because transactions that started earlier are still entitled to see the old version. So deleting a million rows adds work without freeing anything, and df -h does not move: that is the expected behaviour, not a DELETE that failed. Once the clean-up has run, the space becomes reusable by that table — it is not returned to the filesystem. Only VACUUM FULL rewrites the table into a new file and finally makes df move, at the cost of an exclusive lock that stops reads and writes. The count is in n_dead_tup, a column of pg_stat_user_tables, next to last_autovacuum, which says whether anything has dealt with them and when.
Also written: dead tuple, n_dead_tup
