Re: WIP: Avoid creation of the free space map for small tables - Mailing list pgsql-hackers

From John Naylor
Subject Re: WIP: Avoid creation of the free space map for small tables
Date
Msg-id CAJVSVGWxNu7gdxU6-QyUv=7ooSF5ujXVFu+gstKV62MbbdCHuA@mail.gmail.com
Whole thread Raw
In response to Re: WIP: Avoid creation of the free space map for small tables  (Amit Kapila <amit.kapila16@gmail.com>)
Responses Re: WIP: Avoid creation of the free space map for small tables  (John Naylor <jcnaylor@gmail.com>)
Re: WIP: Avoid creation of the free space map for small tables  (Amit Kapila <amit.kapila16@gmail.com>)
List pgsql-hackers
On 10/16/18, Amit Kapila <amit.kapila16@gmail.com> wrote:
> I think we can avoid using prevBlockNumber and try_every_block, if we
> maintain a small cache which tells whether the particular block is
> tried or not.  What I am envisioning is that while finding the block
> with free space, if we came to know that the relation in question is
> small enough that it doesn't have FSM, we can perform a local_search.
> In local_seach, we can enquire the cache for any block that we can try
> and if we find any block, we can try inserting in that block,
> otherwise, we need to extend the relation.  One simple way to imagine
> such a cache would be an array of structure and structure has blkno
> and status fields.  After we get the usable block, we need to clear
> the cache, if exists.

Here is the design I've implemented in the attached v6. There is more
code than v5, but there's a cleaner separation between freespace.c and
hio.c, as you preferred. I also think it's more robust. I've expended
some effort to avoid doing unnecessary system calls to get the number
of blocks.
--

For the local, in-memory map, maintain a static array of status
markers, of fixed-length HEAP_FSM_CREATION_THRESHOLD, indexed by block
number. This is populated every time we call GetPageWithFreeSpace() on
small tables with no FSM. The statuses are

'zero' (beyond the relation)
'available to try'
'tried already'

Example for a 4-page heap:

01234567
AAAA0000

If we try block 3 and there is no space, we set it to 'tried' and next
time through the loop we'll try 2, etc:

01234567
AAAT0000

If we try all available blocks, we will extend the relation. As in the
master branch, first we call GetPageWithFreeSpace() again to see if
another backend extended the relation to 5 blocks while we were
waiting for the lock. If we find a new block, we will mark the new
block available and leave the rest alone:

01234567
TTTTA000

On the odd chance we still can't insert into the new block, we'll skip
checking any others and we'll redo the logic to extend the relation.

If we're about to successfully return a buffer, whether from an
existing block, or by extension, we clear the local map.

Once this is in shape, I'll do some performance testing.

-John Naylor

Attachment

pgsql-hackers by date:

Previous
From: Amit Langote
Date:
Subject: Re: Side effect of CVE-2017-7484 fix?
Next
From: Michael Paquier
Date:
Subject: Buildfarm failures for hash indexes: buffer leaks