Hi, I am using PostgreSQL 8.1.4 for an embedded
application. For some reason, vacuum is not able to identify rows that
are candidates for removal (i.e., mark space as available). Background Info: I observed some performance problems – our database
seemed to be using an unusually high amount of cpu. Further investigation
of the problem revealed a very bloated database; the database was around 300M
when it should have been about 150M. A number of the database files were
quite large, however, the tables that they stored information for were very
small. For example, we had one table that had only 46 rows, but was using
up more than 17M of disk space. We had a number of other tables that were
similarly large. We run auto vacuum and I can see from the logs that it is
running quite frequently. When I run vacuum full from the psql, I can see that
space is not being recovered. I have run vacuum full with the verbose
flag set, I can see that messages that indicate the existence of “dead
row versions that cannot be removed yet. <--- CUT FROM VACUUM OUTPUT ---> CPU 0.00s/0.00u sec elapsed 0.18 sec. INFO:
"ibportreceivestatsca": found 0 removable, 88017 nonremovable row
versions in 4001 pages DETAIL: 87957 dead row versions
cannot be removed yet. There were 1 unused item pointers. <--- CUT FROM VACUUM OUTPUT ---> If I shutdown our application and run a vacuum full, the
space is recovered and the database size goes down to 150M. So, my best guess is that something in our application is
preventing vacuum from removing dead rows. What could cause this?
Would it be caused by a long-living transaction? What is the best way to
track the problem down...right now, I am looking through pg_stat_activity and
pg_locks to find processes that are “in transaction” and what locks
they are holding. Has anyone had a similar problem? If so, how did you
resolve it? Thanks Ike |