Re: [PATCH] Refactoring of LWLock tranches - Mailing list pgsql-hackers

From Ildus Kurbangaliev
Subject Re: [PATCH] Refactoring of LWLock tranches
Date
Msg-id 20151119170428.490de41d@lp
Whole thread Raw
In response to Re: [PATCH] Refactoring of LWLock tranches  ("andres@anarazel.de" <andres@anarazel.de>)
Responses Re: [PATCH] Refactoring of LWLock tranches
List pgsql-hackers
Thank you for the review. I've made changes according to your comments.
I don't stick on current names in the patch.

I've removed all unnecerrary indirections, and added cache aligning
to LWLock arrays.

On Tue, 17 Nov 2015 19:36:13 +0100
"andres@anarazel.de" <andres@anarazel.de> wrote:

> On 2015-11-17 14:14:50 +0300, Ildus Kurbangaliev wrote:
> > 1) We can avoid constants, and use a standard steps for tranches
> > creation.
>
> The constants are actually a bit useful, to easily determine
> builtin/non-builtin stuff.

Maybe I'm missing something here, but I don't see much difference with
other tranches, created in Postgres startup. In my opinion they are also
pretty much builtin.

>
> > 2) We have only one global variable (BufferCtl)
>
> Don't see the advantage. This adds another, albeit predictable,
> indirection in frequent callsites. There's no architectural advantage
> in avoiding these.
>
> > 3) Tranches moved to shared memory, so we won't need to do
> > an additional work here.
>
> I can see some benefit, but it also doesn't seem like a huge benefit.

The moving base tranches to shared memory has been discussed many times.
The point is using them later in pg_stat_activity and other monitoring
views.

>
>
> > 4) Also we can kept buffer locks from MainLWLockArray there (that
> > was done in attached patch).
>
> That's the 'blockLocks' thing? That's a pretty bad name. These are
> buffer mapping locks. And this seems like a separate patch, separately
> debated.

Changed to BufMappingPartitionLWLocks. If this patch is all about
separating LWLocks of the buffer manager, why not use one patch for this
task?

>
> > +    if (!foundCtl)
> >      {
> > -        int            i;
> > +        /* Align descriptors to a cacheline boundary. */
> > +        ctl->base.bufferDescriptors = (void *)
> > CACHELINEALIGN(ShmemAlloc(
> > +            NBuffers * sizeof(BufferDescPadded) +
> > PG_CACHE_LINE_SIZE)); +
> > +        ctl->base.bufferBlocks = (char *)
> > ShmemAlloc(NBuffers * (Size) BLCKSZ);
>
> I'm going to entirely veto this.
>
> > +        strncpy(ctl->IOLWLockTrancheName, "buffer_io",
> > +            BUFMGR_MAX_NAME_LENGTH);
> > +        strncpy(ctl->contentLWLockTrancheName,
> > "buffer_content",
> > +            BUFMGR_MAX_NAME_LENGTH);
> > +        strncpy(ctl->blockLWLockTrancheName,
> > "buffer_blocks",
> > +            BUFMGR_MAX_NAME_LENGTH);
> > +
> > +        ctl->IOLocks = (LWLockMinimallyPadded *)
> > ShmemAlloc(
> > +            sizeof(LWLockMinimallyPadded) *
> > NBuffers);
>
> This should be cacheline aligned.

Fixed

>
> > -            buf->io_in_progress_lock = LWLockAssign();
> > -            buf->content_lock = LWLockAssign();
> > +
> > LWLockInitialize(BufferDescriptorGetContentLock(buf),
> > +                ctl->contentLWLockTrancheId);
> > +            LWLockInitialize(&ctl->IOLocks[i].lock,
> > +                ctl->IOLWLockTrancheId);
>
> Seems weird to use the macro accessing content locks, but not IO
> locks.

Fixed

>
> >  /* Note: these two macros only work on shared buffers, not local
> > ones! */ -#define BufHdrGetBlock(bufHdr)    ((Block)
> > (BufferBlocks + ((Size) (bufHdr)->buf_id) * BLCKSZ)) +#define
> > BufHdrGetBlock(bufHdr)    ((Block) (BufferCtl->bufferBlocks +
> > ((Size) (bufHdr)->buf_id) * BLCKSZ))
>
> That's the additional indirection I'm talking about.
>
> > @@ -353,9 +353,6 @@ NumLWLocks(void)
> >      /* Predefined LWLocks */
> >      numLocks = NUM_FIXED_LWLOCKS;
> >
> > -    /* bufmgr.c needs two for each shared buffer */
> > -    numLocks += 2 * NBuffers;
> > -
> >      /* proc.c needs one for each backend or auxiliary process
> > */ numLocks += MaxBackends + NUM_AUXILIARY_PROCS;
>
> Didn't you also move the buffer mapping locks... ?
>
> > diff --git a/src/include/storage/buf_internals.h
> > b/src/include/storage/buf_internals.h index 521ee1c..e1795dc 100644
> > --- a/src/include/storage/buf_internals.h
> > +++ b/src/include/storage/buf_internals.h
> > @@ -95,6 +95,7 @@ typedef struct buftag
> >      (a).forkNum == (b).forkNum \
> >  )
> >
> > +
> >  /*
>
> unrelated change.
>
> >   * The shared buffer mapping table is partitioned to reduce
> > contention.
> >   * To determine which partition lock a given tag requires, compute
> > the tag's @@ -104,10 +105,9 @@ typedef struct buftag
> >  #define BufTableHashPartition(hashcode) \
> >      ((hashcode) % NUM_BUFFER_PARTITIONS)
> >  #define BufMappingPartitionLock(hashcode) \
> > -    (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + \
> > -        BufTableHashPartition(hashcode)].lock)
> > +    (&((BufferCtlData
> > *)BufferCtl)->blockLocks[BufTableHashPartition(hashcode)].lock)
> > #define BufMappingPartitionLockByIndex(i) \
> > -    (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + (i)].lock)
> > +    (&((BufferCtlData *)BufferCtl)->blockLocks[i].lock)
>
> Again, unnecessary indirections.

Fixed

>
> > +/* Maximum length of a bufmgr lock name */
> > +#define BUFMGR_MAX_NAME_LENGTH    32
>
> If we were to do this I'd just use NAMEDATALEN.

Fixed

>
> > +/*
> > + * Base control struct for the buffer manager data
> > + * Located in shared memory.
> > + *
> > + * BufferCtl variable points to BufferCtlBase because of only
> > + * the backend code knows about BufferDescPadded, LWLock and
> > + * others structures and the same time it must be usable in
> > + * the frontend code.
> > + */
> > +typedef struct BufferCtlData
> > +{
> > +    BufferCtlBase base;
>
> Eeek. What's the point here?

The point was using BufferCtlBase in the backend and frontend code.
The frontend code doesn't know about LWLock and other structures.
Anyway I've removed this code.

--
Ildus Kurbangaliev
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company

Attachment

pgsql-hackers by date:

Previous
From: David Steele
Date:
Subject: Re: Additional role attributes && superuser review
Next
From: Nikolay Shaplov
Date:
Subject: [PROPOSAL] TAP test example