Thread: pg_autovacuum and REINDEX at the same time (?)

pg_autovacuum and REINDEX at the same time (?)

From
Janar Kartau
Date:
Hi.
I've been running autovacuum over a month now without any problems, but
today one of the critical tables got locked and made a pretty big mess. :)
We have a cron script that does REINDEX on this table every 5 minutes.
So i wonder if running REINDEX and VACUUM on the same table at the same
time may cause this deadlock?
Or can a VACUUM make so much trouble?

Version: PostgreSQL 8.1.4 on x86_64-pc-linux-gnu, compiled by GCC
x86_64-pc-linux-gnu-gcc (GCC) 4.1.1 (Gentoo 4.1.1)

Vacuum settings:
vacuum_cost_delay = 150
vacuum_cost_page_hit = 6
vacuum_cost_page_miss = 10
vacuum_cost_page_dirty = 20
vacuum_cost_limit = 150

 From the log:

2007-02-28 10:40:13 EET - LOG:  autovacuum: processing database "dbname"
2007-02-28 10:40:56 EET - postgres FATAL:  sorry, too many clients
already            (here i assume the table got completely locked)
...
Lots and lots of it..
...
2007-02-28 10:41:35 EET - postgres FATAL:  sorry, too many clients already
2007-02-28 10:41:35 EET - postgres ERROR:  deadlock detected
2007-02-28 10:41:35 EET - postgres DETAIL:  Process 41021 waits for
AccessExclusiveLock on relation 965687 of database 16398; blocked by
process 41071.
        Process 41071 waits for AccessShareLock on relation 965684 of
database 16398; blocked by process 41021.
2007-02-28 10:41:35 EET - postgres CONTEXT:  SQL statement "REINDEX
TABLE category_tree"
        PL/pgSQL function "update_itemcount" line 48 at SQL statement
2007-02-28 10:41:35 EET - postgres STATEMENT:  SELECT * FROM
update_itemcount();
2007-02-28 10:41:35 EET - postgres ERROR:  current transaction is
aborted, commands ignored until end of transaction block

Re: pg_autovacuum and REINDEX at the same time (?)

From
Heikki Linnakangas
Date:
Janar Kartau wrote:
> Hi.
> I've been running autovacuum over a month now without any problems, but
> today one of the critical tables got locked and made a pretty big mess. :)
> We have a cron script that does REINDEX on this table every 5 minutes.
> So i wonder if running REINDEX and VACUUM on the same table at the same
> time may cause this deadlock?
> Or can a VACUUM make so much trouble?

ISTM that you have two separate issues.

The "sorry, too many clients already" error means that you've reached
the maximum number of connections, as set with the max_connections
setting. The autovacuum processes needs one connection to run.

I suspect that the deadlock is not related to the autovacuum, but just
an interaction between your transactions and the REINDEX.

What does the update_itemcount() function look like? Are you running the
REINDEX in a transaction?

Why do you need to reindex every 5 minutes? How long does the vacuum run
normally?

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: pg_autovacuum and REINDEX at the same time (?)

From
Janar Kartau
Date:
I know what causes the "sorry, too many clients already" error, but the
number of connections shouldn't grow so big.. so i guess the table
(category_tree) got locked.
We do REINDEX every 5 minutes because the table gets updated very often
and the query's took a lot of time. I think since we use autovacuum now,
it's not needed anymore.

Here's the fuction itself..

DECLARE
    row RECORD;
BEGIN
    UPDATE category_tree SET item_count = 0;

    FOR row IN SELECT
                count(I.item_id) AS itemcount
                ,CT.node_left
                ,CT.node_right
            FROM
                items I
                JOIN category_tree CT ON (I.category1=CT.category_id)
            WHERE
                date_start <= now()
                AND date_end >= now()
                AND item_status = 1
                AND I.view_group IS NULL
            GROUP BY
                node_left||node_right,
                node_left,
                node_right

            LOOP
        UPDATE category_tree SET item_count = item_count + row.itemcount
where node_left <= row.node_left AND node_right >= row.node_right;
    END LOOP;

    FOR row IN SELECT
                count(I.item_id) AS itemcount
                ,CT.node_left
                ,CT.node_right
            FROM
                items I
                JOIN category_tree CT ON (I.category2=CT.category_id)
            WHERE
                date_start <= now()
                AND date_end >= now()
                AND item_status = 1
                AND I.view_group IS NULL
            GROUP BY
                node_left||node_right,
                node_left,
                node_right

            LOOP
        UPDATE category_tree SET item_count = item_count + row.itemcount
where node_left <= row.node_left AND node_right >= row.node_right;
    END LOOP;

    --REINDEX TABLE category_tree;

    RETURN 1;
END;

and it's called from..

BEGIN;

SELECT * FROM update_itemcount();
UPDATE cache.cached_stats SET intval=(SELECT count(*) FROM items WHERE
item_status = 1 AND view_group IS NULL) WHERE stat_id = 1;

COMMIT;

Heikki Linnakangas wrote:
> Janar Kartau wrote:
>> Hi.
>> I've been running autovacuum over a month now without any problems,
>> but today one of the critical tables got locked and made a pretty big
>> mess. :)
>> We have a cron script that does REINDEX on this table every 5
>> minutes. So i wonder if running REINDEX and VACUUM on the same table
>> at the same time may cause this deadlock?
>> Or can a VACUUM make so much trouble?
>
> ISTM that you have two separate issues.
>
> The "sorry, too many clients already" error means that you've reached
> the maximum number of connections, as set with the max_connections
> setting. The autovacuum processes needs one connection to run.
>
> I suspect that the deadlock is not related to the autovacuum, but just
> an interaction between your transactions and the REINDEX.
>
> What does the update_itemcount() function look like? Are you running
> the REINDEX in a transaction?
>
> Why do you need to reindex every 5 minutes? How long does the vacuum
> run normally?
>

Re: pg_autovacuum and REINDEX at the same time (?)

From
Heikki Linnakangas
Date:
Janar Kartau wrote:
> I know what causes the "sorry, too many clients already" error, but the
> number of connections shouldn't grow so big.. so i guess the table
> (category_tree) got locked.

If that happens again, take a look at pg_stat_activity or ps output to
see what's going on. Something must be using the connections, a locked
table alone won't give you that error message.

> We do REINDEX every 5 minutes because the table gets updated very often
> and the query's took a lot of time. I think since we use autovacuum now,
> it's not needed anymore.

Yeah, a vacuum is normally enough to keep the indexes in good shape. I'd
  suggest removing the REINDEX call and either letting autovacuum handle
it, or adding an explicit VACUUM call after the commit.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com