Re: [PATCH] Speedup truncates of relation forks

Поиск
Список
Период
Сортировка
От Masahiko Sawada
Тема Re: [PATCH] Speedup truncates of relation forks
Дата
Msg-id CAD21AoDiHjarKXLxK1YB+1m3_1DS_KFwTFeM0cnT339bF2ibrw@mail.gmail.com
обсуждение исходный текст
Ответ на RE: [PATCH] Speedup truncates of relation forks  ("Tsunakawa, Takayuki" <tsunakawa.takay@jp.fujitsu.com>)
Ответы RE: [PATCH] Speedup truncates of relation forks  ("Tsunakawa, Takayuki" <tsunakawa.takay@jp.fujitsu.com>)
RE: [PATCH] Speedup truncates of relation forks  ("Jamison, Kirk" <k.jamison@jp.fujitsu.com>)
Список pgsql-hackers
On Wed, Jun 12, 2019 at 12:25 PM Tsunakawa, Takayuki
<tsunakawa.takay@jp.fujitsu.com> wrote:
>
> From: Tomas Vondra [mailto:tomas.vondra@2ndquadrant.com]
> > Years ago I've implemented an optimization for many DROP TABLE commands
> > in a single transaction - instead of scanning buffers for each relation,
> > the code now accumulates a small number of relations into an array, and
> > then does a bsearch for each buffer.
> >
> > Would something like that be applicable/useful here? That is, if we do
> > multiple TRUNCATE commands in a single transaction, can we optimize it
> > like this?
>
> Unfortunately not.  VACUUM and autovacuum handles each table in a different transaction.

We do RelationTruncate() also when we truncate heaps that are created
in the current transactions or has a new relfilenodes in the current
transaction. So I think there is a room for optimization Thomas
suggested, although I'm not sure it's a popular use case.

I've not look at this patch deeply but in DropRelFileNodeBuffer I
think we can get the min value of all firstDelBlock and use it as the
lower bound of block number that we're interested in. That way we can
skip checking the array during scanning the buffer pool.

-extern void smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum,
bool isRedo);
+extern void smgrdounlinkfork(SMgrRelation reln, ForkNumber *forknum,
+                                                        bool isRedo,
int nforks);
-extern void smgrtruncate(SMgrRelation reln, ForkNumber forknum,
-                                                BlockNumber nblocks);
+extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum,
+                                                BlockNumber *nblocks,
int nforks);

Don't we use each elements of nblocks for each fork? That is, each
fork uses an element at its fork number in the nblocks array and sets
InvalidBlockNumber for invalid slots, instead of passing the valid
number of elements. That way the following code that exist at many places,

    blocks[nforks] = visibilitymap_mark_truncate(rel, nblocks);
   if (BlockNumberIsValid(blocks[nforks]))
   {
       forks[nforks] = VISIBILITYMAP_FORKNUM;
       nforks++;
   }

would become

    blocks[VISIBILITYMAP_FORKNUM] = visibilitymap_mark_truncate(rel, nblocks);

Regards,

--
Masahiko Sawada
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Heikki Linnakangas
Дата:
Сообщение: Re: pgbench rate limiting changes transaction latency computation
Следующее
От: Etsuro Fujita
Дата:
Сообщение: Re: BEFORE UPDATE trigger on postgres_fdw table not work