Re: Updates, ShareLocks, RowExclusiveLocks, and deadlocks

From: Ben Chobot <bench(at)silentmedia(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Updates, ShareLocks, RowExclusiveLocks, and deadlocks
Date: 2012-04-25 19:12:37
Message-ID: 9C8B85AA-B22B-43DA-A857-FF3435D5CD15@silentmedia.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Apr 25, 2012, at 12:35 PM, Tom Lane wrote:

> Ben Chobot <bench(at)silentmedia(dot)com> writes:
>> We have a few daemon process that constantly pull batches of logs from a work queue and then insert into or update a single table in a single transaction, ~1k rows at a time. I've been told the transaction does nothing other than insert and update on that table, and I can verify the table in question has no triggers. This is 9.1.3.
>> What we've noticed is that most updates come with a RowExclusiveLock, according to pg_locks, which is what you'd expect from the manual. Unfortunately, sometimes, some of those update transactions have ShareLocks, which doesn't make any sense to us, because we're not taking explicit locks and the manual claims ShareLocks only automatically come from index creation, which we're also not doing explicitly. This is a problem because it's showing up as deadlocks, every few minutes.
>
> You'd really need to provide more information here, but what I suspect
> is that you're seeing row-level locks in process of being acquired.
> For implementation reasons that type of activity will transiently
> try to acquire ShareLock on another transaction's XID. Or this might
> be something different, but without seeing a full copy of the pg_locks
> rows you're talking about, it's hard to be sure. In any case, I'd
> speculate that the underlying cause is conflicting updates on the same
> row, and/or foreign-key-related row locks.

So, if I understand what you're saying, if I have two connections each transactionally updating many rows, then each transaction will need to acquire a RowExclusiveLock for each row (as documented), and also (as not documented?) each acquisition will temporarily acquire a ShareLock on the other transaction's transactionid? That seems to fit what I'm seeing in pg_locks, and I suppose if there is an overlap in rows between to two transactions, and if those updates happened in the wrong order, then we'd get deadlock. I just assumed we'd see that in the logs as deadlocks due to waiting for RowExclusiveLocks, while it sounds like you are saying the log will show them as ShareLocks?

If that's the case, would doing the updates in, say, primary key order solve this problem? I'm pretty sure we're just pulling things out of the queue and running them in random order.

If that's not the case, then what information would be helpful in understanding what's going on? All of pg_locks or just the locks related to the virtualtransactionid of the update with the SharedLock? There are no foreign keys related to this table.

Either way, thanks!

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Tom Lane 2012-04-25 19:31:46 Re: Updates, ShareLocks, RowExclusiveLocks, and deadlocks
Previous Message George Weaver 2012-04-25 18:39:44 Re: Using copy with a file containing blank rows