RE: [Patch] Optimize dropping of relation buffers using dlist

From: "tsunakawa(dot)takay(at)fujitsu(dot)com" <tsunakawa(dot)takay(at)fujitsu(dot)com>
To: "k(dot)jamison(at)fujitsu(dot)com" <k(dot)jamison(at)fujitsu(dot)com>, "k(dot)jamison(at)fujitsu(dot)com" <k(dot)jamison(at)fujitsu(dot)com>
Cc: 'Amit Kapila' <amit(dot)kapila16(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Kyotaro Horiguchi <horikyota(dot)ntt(at)gmail(dot)com>, Andres Freund <andres(at)anarazel(dot)de>, Robert Haas <robertmhaas(at)gmail(dot)com>, Tomas Vondra <tomas(dot)vondra(at)2ndquadrant(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: RE: [Patch] Optimize dropping of relation buffers using dlist
Date: 2020-09-16 02:38:17
Message-ID: TYAPR01MB2990E3035182033F94120C94FE210@TYAPR01MB2990.jpnprd01.prod.outlook.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

The code doesn't seem to be working correctly.

(1)
+ for (block_num = 0; block_num <= nblocks; block_num++)

should be

+ for (block_num = firstDelBlock[fork_num]; block_num < nblocks; block_num++)

because:

* You only want to invalidate blocks >= firstDelBlock[fork_num], don't you?
* The relation's block number ranges from 0 to nblocks - 1.

(2)
+ INIT_BUFFERTAG(newTag, rnode.node, forkNum[fork_num],
+ firstDelBlock[block_num]);

Replace firstDelBlock[fork_num] with block_num, because you want to process the current block of per-block loop. Your code accesses memory out of the bounds of the array, and doesn't invalidate any buffer.

(3)
+ if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) &&
+ bufHdr->tag.forkNum == forkNum[fork_num] &&
+ bufHdr->tag.blockNum >= firstDelBlock[block_num])
+ InvalidateBuffer(bufHdr); /* releases spinlock */
+ else
+ UnlockBufHdr(bufHdr, buf_state);

Replace
bufHdr->tag.blockNum >= firstDelBlock[fork_num]
with
bufHdr->tag.blockNum == block_num
because you want to check if the found buffer is for the current block of the loop.

(4)
+ /*
+ * We've invalidated the nblocks already. Scan the shared buffers
+ * for each fork.
+ */
+ if (block_num > nblocks)
+ {
+ DropRelFileNodeBuffersOfFork(rnode.node, forkNum[fork_num],
+ firstDelBlock[fork_num]);
+ }

This part is unnecessary. This invalidates all buffers that (2) failed to process, so the regression test succeeds.

Regards
Takayuki Tsunakawa

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Kyotaro Horiguchi 2020-09-16 02:56:29 Re: [Patch] Optimize dropping of relation buffers using dlist
Previous Message Michael Paquier 2020-09-16 02:30:06 Re: Force update_process_title=on in crash recovery?