Received: from localhost (maia-1.hub.org [200.46.204.191]) by postgresql.org (Postfix) with ESMTP id 857209FBC76 for ; Tue, 8 May 2007 07:24:07 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.191]) (amavisd-maia, port 10024) with ESMTP id 61274-01 for ; Tue, 8 May 2007 07:23:57 -0300 (ADT) X-Greylist: whitelisted by SQLgrey-1.7.4 Received: from smtp8-g19.free.fr (smtp8-g19.free.fr [212.27.42.65]) by postgresql.org (Postfix) with ESMTP id DEB819FB28A for ; Tue, 8 May 2007 07:23:57 -0300 (ADT) Received: from pulsar.staff.proxad.net (pulsar.staff.proxad.net [213.228.1.109]) by smtp8-g19.free.fr (Postfix) with ESMTP id C795F199C0; Tue, 8 May 2007 12:23:56 +0200 (CEST) Date: Tue, 8 May 2007 12:23:56 +0200 (CEST) From: Pomarede Nicolas X-X-Sender: npomarede@localhost To: Heikki Linnakangas cc: pgsql-performance@postgresql.org Subject: Re: truncate a table instead of vaccum full when count(*) is 0 In-Reply-To: <46404BEA.5060009@enterprisedb.com> Message-ID: References: <46404BEA.5060009@enterprisedb.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.119 tagged_above=0 required=5 tests=AWL=0.304, BAYES_40=-0.185 X-Spam-Level: X-Archive-Number: 200705/101 X-Sequence-Number: 24491 On Tue, 8 May 2007, Heikki Linnakangas wrote: > Pomarede Nicolas wrote: >> But for the data (dead rows), even running a vacuum analyze every day is >> not enough, and doesn't truncate some empty pages at the end, so the data >> size remains in the order of 200-300 MB, when only a few effective rows are >> there. > > For a table like that you should run VACUUM much more often than once a day. > Turn on autovacuum, or set up a cron script etc. to run it every 15 minutes > or so. Yes, I already do this on another spool table ; I run a vacuum after processing it, but I wondered if there was another way to keep the disk size low for this table. As for autovacuum, the threshold values to analyze/vacuum are not adapted to my situation, because I have some big tables that I prefer to keep vacuumed frequently to prevent growing in disk size, even if the number of insert/update is not big enough and in my case autovacuum would not run often enough. Instead of configuring autovacuum on a per table basis, I prefer running a vacuum on the database every day. > >> Running a vacuum full is a solution for now, but it locks the table for too >> long (10 minutes or so), which is not acceptable in that case, since events >> should be processed in less that 10 seconds. >> >> So, I would like to truncate the table when the number of rows reaches 0 >> (just after the table was processed, and just before some new rows are >> added). >> >> Is there an easy way to do this under psql ? For example, lock the table, >> do a count(*), if result is 0 row then truncate the table, unlock the table >> (a kind of atomic 'truncate table if count(*) == 0'). >> >> Would this work and what would be the steps ? > > It should work, just like you describe it, with the caveat that TRUNCATE will > remove any old row versions that might still be visible to an older > transaction running in serializable mode. It sounds like it's not a problem > in your scenario, but it's hard to say for sure without seeing the > application. Running vacuum more often is probably a simpler and better > solution, anyway. > > Which version of PostgreSQL is this? Shouldn't locking the table prevent this ? I mean, if I try to get an exclusive lock on the table, shouldn't I get one only when there's no older transaction, and in that case I can truncate the table safely, knowing that no one is accessing it due to the lock ? the pg version is 8.1.2 (not the latest I know, but migrating this base is quite complicated since it needs to be up 24/24 a day) thanks Nicolas