Thread: TRUNCATE locking problem

TRUNCATE locking problem

From
Joe Maldonado
Date:
Hello all,

We am running PostgreSQL 7.4.5 and recently we have noticed some strange
behaviour with regards to the TRUNCATE statement.

I think it would help to provide a quick overview of what we are doing
with the table in question in order to properly explain this.

The application which are using the database require frequent access to
this table to perform lookups and all of these are via SELECT
statements.  Most of these join the table in one way or the other to
perform the lookup needed.  Every so often, once per day or so, a
process will receive new data to populate this table.  Once the data is
received the process TRUNCATEs the table and then performs a COPY
operation to repopulate the table.

There is also an autovacuum process which routinely VACUUMs the database
though the logs do not show that it is vacuuming when this happens.

The behaviour we are experiencing is that the TRUNCATE statement will
aquire an ACCESS_EXCLUSIVE lock on the table and then go in to a waiting
state.  While TRUNCATE is in this state no other process can SELECT on
this table.

It seems that TRUNCATE is first posting a lock on the table and then
waiting for other transactions to finish before truncating the table
thus blocking all other operations.

Is this what is actually going on or am I missing something else? and is
there a way to prevent this condition from happening?

Thanks in advance,

- Joe Maldonado

Re: TRUNCATE locking problem

From
Stephen Frost
Date:
* Joe Maldonado (jmaldonado@webehosting.biz) wrote:
> It seems that TRUNCATE is first posting a lock on the table and then
> waiting for other transactions to finish before truncating the table
> thus blocking all other operations.
>
> Is this what is actually going on or am I missing something else? and is
> there a way to prevent this condition from happening?

TRUNCATE isn't MVCC-safe, for one thing.  For another, yes, it uses a
much heavier lock on the table.  If you don't want to use a heavy lock
on the table then you'll need to delete from *;.  I've got a similar
setup to you and was looking at using truncate for it but I've been
starting to think just interjecting a vacuum in the middle might be
better.  ie:

Instead of using:
truncate x;
insert into x;

Doing:
delete from x;
vacuum x;
insert into x;

I'm not really sure which would be faster, so I'm kind of curious about
that.  In my case people are rarely using the table at the same time
they'd be truncating/delete'ing it (the UI doesn't actually allow it) so
the total time may be close between the two.  For your case that might
not be true since the vacuum might not be able to do much due to the
other select's, which means the table ends up being double the size due
to the old tuples, etc.  If someone else has a better solution I'd love
to hear it.

    Thanks,

        Stephen

Attachment

Re: TRUNCATE locking problem

From
Tom Lane
Date:
Joe Maldonado <jmaldonado@webehosting.biz> writes:
> It seems that TRUNCATE is first posting a lock on the table and then
> waiting for other transactions to finish before truncating the table
> thus blocking all other operations.

That's what it's supposed to do.  If you have a problem with the length
of the delay, find the (other) transaction that's accessing the table
for too long and fix that.

            regards, tom lane

Re: TRUNCATE locking problem

From
Joe Maldonado
Date:
Thanks...I just wanted to verify that it was the intended behaviour
prior to going in and changing code :)

- Joe Maldonado

Tom Lane wrote:

>Joe Maldonado <jmaldonado@webehosting.biz> writes:
>
>
>>It seems that TRUNCATE is first posting a lock on the table and then
>>waiting for other transactions to finish before truncating the table
>>thus blocking all other operations.
>>
>>
>
>That's what it's supposed to do.  If you have a problem with the length
>of the delay, find the (other) transaction that's accessing the table
>for too long and fix that.
>
>            regards, tom lane
>
>---------------------------(end of broadcast)---------------------------
>TIP 9: In versions below 8.0, the planner will ignore your desire to
>       choose an index scan if your joining column's datatypes do not
>       match
>
>


Re: TRUNCATE locking problem

From
Joe Maldonado
Date:
Hello all again...

While researching this locking issue I got some of the logs and found
that in one of the cases there was a SELECT running for a long time,
about 2 hours.  This select statement does not usually take more than a
few seconds though, it appeared that TRUNCATE was waiting on it to
finish before continuing.

When I looked at the SELECT statement I found something which I think
may have caused something of a deadlock though since I am quite ignorant
as to how these locks interact I apologize if this is a dumb question :)

The SELECT statement in question contains a sub SELECT in the FROM
clause which in turn is joining with a view that contains the table
which TRUNCATE is being executed against.

Is it possible that the SELECT was issues just before the TRUNCATE
statement was issues and the view in the sub SELECT was waiting on
TRUNCATE's lock?

- Joe Maldonado

Joe Maldonado wrote:

> Thanks...I just wanted to verify that it was the intended behaviour
> prior to going in and changing code :)
>
> - Joe Maldonado
>
> Tom Lane wrote:
>
>> Joe Maldonado <jmaldonado@webehosting.biz> writes:
>>
>>
>>> It seems that TRUNCATE is first posting a lock on the table and then
>>> waiting for other transactions to finish before truncating the table
>>> thus blocking all other operations.
>>>
>>
>>
>> That's what it's supposed to do.  If you have a problem with the length
>> of the delay, find the (other) transaction that's accessing the table
>> for too long and fix that.
>>
>>             regards, tom lane
>>
>> ---------------------------(end of broadcast)---------------------------
>> TIP 9: In versions below 8.0, the planner will ignore your desire to
>>       choose an index scan if your joining column's datatypes do not
>>       match
>>
>>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
>               http://www.postgresql.org/docs/faq



Re: TRUNCATE locking problem

From
Tom Lane
Date:
Joe Maldonado <jmaldonado@webehosting.biz> writes:
> While researching this locking issue I got some of the logs and found
> that in one of the cases there was a SELECT running for a long time,
> about 2 hours.  This select statement does not usually take more than a
> few seconds though, it appeared that TRUNCATE was waiting on it to
> finish before continuing.

> The SELECT statement in question contains a sub SELECT in the FROM
> clause which in turn is joining with a view that contains the table
> which TRUNCATE is being executed against.

> Is it possible that the SELECT was issues just before the TRUNCATE
> statement was issues and the view in the sub SELECT was waiting on
> TRUNCATE's lock?

No.  That would be a deadlock and would be reported as such.

            regards, tom lane

Re: TRUNCATE locking problem

From
Joe Maldonado
Date:
Tom Lane wrote:

>Joe Maldonado <jmaldonado@webehosting.biz> writes:
>
>
>>While researching this locking issue I got some of the logs and found
>>that in one of the cases there was a SELECT running for a long time,
>>about 2 hours.  This select statement does not usually take more than a
>>few seconds though, it appeared that TRUNCATE was waiting on it to
>>finish before continuing.
>>
>>
>
>
>
>>The SELECT statement in question contains a sub SELECT in the FROM
>>clause which in turn is joining with a view that contains the table
>>which TRUNCATE is being executed against.
>>
>>
>
>
>
>>Is it possible that the SELECT was issues just before the TRUNCATE
>>statement was issues and the view in the sub SELECT was waiting on
>>TRUNCATE's lock?
>>
>>
>
>No.  That would be a deadlock and would be reported as such.
>
>            regards, tom lane
>
>

Again many thanks :)

- Joe Maldonado