Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL database size (tablespace size) much bigger then calculated total sum of relations

Tags:

postgresql

Hallo all,

I see a very big difference between the actual database size (on the HDD and displayed by pg_database_size() call) and the size, calculated by summing up total relation sizes retrieved by pg_total_relation_size().

The first is 62G and the last is 16G (right the difference of the deleted data from the biggest table)

Here is a simplified query, that can show that difference on my system:

select current_database(),
       pg_size_pretty( sum(total_relation_raw_size)::bigint ) as calculated_database_size,
       pg_size_pretty( pg_database_size(current_database()) ) as database_size   
  from (select pg_total_relation_size(relid) as total_relation_raw_size
          from pg_stat_all_tables -- this includes also system tables shared between databases
         where schemaname != 'pg_toast' 
       ) as stats;

It seems like there is some dangling data there. As this situation appeared, after we dumped and full vacuumed lots of unused data from that DB.

P.S.: I suppose, that it was a database corruption of some sort... The only way to recover from this situation was to switch to the Hot-Standby database...

like image 334
valgog Avatar asked Jan 21 '11 16:01

valgog


People also ask

How big is too big for a Postgres database?

There is no PostgreSQL-imposed limit on the number of indexes you can create on a table. Of course, performance may degrade if you choose to create more and more indexes on a table with more and more columns. PostgreSQL has a limit of 1GB for the size of any one field in a table.

How do I find the size of a tablespace in PostgreSQL?

The pg_tablespace_size() function is used to get the size of a tablespace of a table. This function accepts a tablespace name and returns the size in bytes. Syntax: select pg_tablespace_size('tablespace_name');

How do you measure a Greenplum table?

How to check the size of a table? psql> select pg_size_pretty(pg_relation_size('schema. tablename')); Replace schema.

How do I vacuum a Postgres database?

PostgreSQL VACUUM Command — At a Glance The PostgreSQL VACUUM Command reclaims space occupied by dead tuples from tables and their indexes. The command will not empty up the disk space in the OS but instead makes it usable for new rows. A simple PostgreSQL VACUUM Command is shown below: VACUUM [ ( option [, ...] ) ]


2 Answers

LOBs are a very valid concern as BobG writes, since they are not deleted when the rows of your application table (containing the OIDs) get deleted.

These will NOT be deleted by the VACUUM process automatically, only you have run VACUUMLO on them.

Vacuumlo will delete all of the unreferenced LOBs from the database.

Example call:

vacuumlo -U postgres -W -v <database_name>

(I only included the -v to make vacuumlo a bit more verbose so that you see how many LOBs it removes)

After vacuumlo has deleted the LOBs, you can run VACUUM FULL (or let the auto-vacuum process run).

like image 130
sola Avatar answered Sep 25 '22 20:09

sola


Do you have unused LOBs?

If you have something like this:

CREATE TABLE bigobjects (
    id BIGINT NOT NULL PRIMARY KEY,
    filename VARCHAR(255) NOT NULL,
    filecontents OID NOT NULL
);

followed by:

\lo_import '/tmp/bigfile'
11357
INSERT INTO bigobjects VALUES (1, 'bigfile', 11357);
TRUNCATE TABLE bigobjects;

You'll still have the LOB (id 11357) in the database.

You can check the pg_catalog.pg_largeobject system catalog table for all the large objects in your database (recommend SELECT DISTINCT loid FROM pg_catalog.pg_largeobject unless you want to see all your LOB data as octal.)

If you clean out all your unused LOBs and do a VACUUM FULL, you should see a hefty reduction in storage. I just tried this on a personal dev database I've been using and saw a reduction in size from 200MB down to 10MB (as reported by pg_database_size(current_database()).)

like image 35
BobG Avatar answered Sep 23 '22 20:09

BobG