Re: 9.2beta1, parallel queries, ReleasePredicateLocks, CheckForSerializableConflictIn in the oprofile

From: Florian Pflug <fgp(at)phlo(dot)org>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Merlin Moncure <mmoncure(at)gmail(dot)com>, Sergey Koposov <koposov(at)ast(dot)cam(dot)ac(dot)uk>, Jeff Janes <jeff(dot)janes(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org, Stephen Frost <sfrost(at)snowman(dot)net>
Subject: Re: 9.2beta1, parallel queries, ReleasePredicateLocks, CheckForSerializableConflictIn in the oprofile
Date: 2012-06-01 12:47:29
Message-ID: 352641D5-DD57-4231-85F6-F535EFC23D00@phlo.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On May31, 2012, at 20:50 , Robert Haas wrote:
> Suppose we introduce two new buffer flags,
> BUF_NAILED and BUF_NAIL_REMOVAL. When we detect excessive contention
> on the buffer header spinlock, we set BUF_NAILED. Once we do that,
> the buffer can't be evicted until that flag is removed, and backends
> are permitted to record pins in a per-backend area protected by a
> per-backend spinlock or lwlock, rather than in the buffer header.
> When we want to un-nail the buffer, we set BUF_NAIL_REMOVAL. At that
> point, it's no longer permissible to record new pins in the
> per-backend areas, but old ones may still exist. So then we scan all
> the per-backend areas and transfer the pins to the buffer header, or
> else just wait until no more exist; then, we clear both BUF_NAILED and
> BUF_NAIL_REMOVAL.

A simpler idea would be to collapse UnpinBuffer() / PinBuffer() pairs
by queing UnpinBuffer() requests for a while before actually updating
shared state.

I'm imagining having a small unpin queue with, say, 32 entries in
backend-local memory. When we unpin a buffer, we add the buffer at the
front of the queue. If the queue overflows, we dequeue a buffer from the
back of the queue and actually call UnpinBuffer(). If PinBuffer() is called
for a queued buffer, we simply remove the buffer from the queue.

We'd drain the unpin queue whenever we don't expect a PinBuffer() request
to happen for a while. Returning to the main loop is an obvious such place,
but there might be others. We could, for example, drain the queue every time
we block on a lock or signal, and maybe also before we go do I/O. Or, we
could have one such queue per resource owner, and drain it when we release
the resource owner.

We already avoid calling PinBuffer() multiple times for multiple overlapping
pins of a single buffer by a single backend. The strategy above would extend
that to not-quite-overlapping pins.

best regards,
Florian Pflug

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Bryan Murphy 2012-06-01 13:07:42 Re: pg_upgrade from 9.0.7 to 9.1.3: duplicate key pg_authid_oid_index
Previous Message Simon Riggs 2012-06-01 11:51:09 Re: slow dropping of tables, DropRelFileNodeBuffers, tas