Re: brininsert optimization opportunity

Richard Guo <guofenglinux@gmail.com>

From: Richard Guo <guofenglinux@gmail.com>
To: Soumyadeep Chakraborty <soumyadeep2007@gmail.com>
Cc: Tomas Vondra <tomas.vondra@enterprisedb.com>, Matthias van de Meent <boekewurm+postgres@gmail.com>, Alvaro Herrera <alvherre@alvh.no-ip.org>, pgsql-hackers <pgsql-hackers@postgresql.org>, Ashwin Agrawal <ashwinstar@gmail.com>
Date: 2023-11-27T07:37:20Z
Lists: pgsql-hackers
On Mon, Nov 27, 2023 at 1:53 PM Soumyadeep Chakraborty <
soumyadeep2007@gmail.com> wrote:

> On Sun, Nov 26, 2023 at 9:28 PM Richard Guo <guofenglinux@gmail.com>
> wrote:
> > It seems that we have an oversight in this commit.  If there is no tuple
> > that has been inserted, we wouldn't have an available insert state in
> > the clean up phase.  So the Assert in brininsertcleanup() is not always
> > right.  For example:
> >
> > regression=# update brin_summarize set value = brin_summarize.value;
> > server closed the connection unexpectedly
>
> I wasn't able to repro the issue on
> 86b64bafc19c4c60136a4038d2a8d1e6eecc59f2.
> with UPDATE/INSERT:
>
> This could be because since c5b7ba4e67aeb5d6f824b74f94114d99ed6e42b7,
> we have moved ExecOpenIndices()
> from ExecInitModifyTable() to ExecInsert(). Since we never open the
> indices if nothing is
> inserted, we would never attempt to close them with ExecCloseIndices()
> while the ii_AmCache
> is NULL (which is what causes this assertion failure).


AFAICS we would also open the indices from ExecUpdate().  So if we
update the table in a way that no new tuples are inserted, we will have
this issue.  As I showed previously, the query below crashes for me on
latest master (dc9f8a7983).

regression=# update brin_summarize set value = brin_summarize.value;
server closed the connection unexpectedly

There are other code paths that call ExecOpenIndices(), such as
ExecMerge().  I believe it's not hard to create queries that trigger this
Assert for those cases.

Thanks
Richard

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Add missing index_insert_cleanup calls

  2. Fix a couple typos in BRIN code

  3. Check if ii_AmCache is NULL in aminsertcleanup

  4. Use fipshash in brin_multi test

  5. Reuse BrinDesc and BrinRevmap in brininsert

  6. Consider fillfactor when estimating relation size

  7. Postpone some stuff out of ExecInitModifyTable.