Re: TOAST condition for column size

From: Dilip Kumar <dilipbalaut(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org>, torikoshia <torikoshia(at)oss(dot)nttdata(dot)com>
Subject: Re: TOAST condition for column size
Date: 2021-01-19 13:56:34
Message-ID: CAFiTN-u6WprHYB-f2sBUc=-EXrP258i00a=ryCADDxX01LTboA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, 19 Jan 2021 at 6:28 PM, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:

> On Tue, Jan 19, 2021 at 5:18 PM Dilip Kumar <dilipbalaut(at)gmail(dot)com> wrote:
> >
> > On Mon, Jan 18, 2021 at 7:53 PM torikoshia <torikoshia(at)oss(dot)nttdata(dot)com>
> wrote:
> > >
> > > Hi,
> > >
> > > When I created a table consisting of 400 VARCHAR columns and tried
> > > to INSERT a record which rows were all the same size, there were
> > > cases where I got an error due to exceeding the size limit per
> > > row.
> > >
> > > =# -- create a table consisting of 400 VARCHAR columns
> > > =# CREATE TABLE t1 (c1 VARCHAR(100),
> > > c2 VARCHAR(100),
> > > ...
> > > c400 VARCHAR(100));
> > >
> > > =# -- insert one record which rows are all 20 bytes
> > > =# INSERT INTO t1 VALUES (repeat('a', 20),
> > > repeat('a', 20),
> > > ...
> > > repeat('a', 20));
> > > ERROR: row is too big: size 8424, maximum size 8160
> > >
> > > What is interesting is that it failed only when the size of each
> > > column was 20~23 bytes, as shown below.
> > >
> > > size of each column | result
> > > -------------------------------
> > > 18 bytes | success
> > > 19 bytes | success
> > > 20 bytes | failure
> > > 21 bytes | failure
> > > 22 bytes | failure
> > > 23 bytes | failure
> > > 24 bytes | success
> > > 25 bytes | success
> > >
> > >
> > > When the size of each column was 19 bytes or less, it succeeds
> > > because the row size is within a page size.
> > > When the size of each column was 24 bytes or more, it also
> > > succeeds because columns are TOASTed and the row size is reduced
> > > to less than one page size.
> > > OTOH, when it's more than 19 bytes and less than 24 bytes,
> > > columns aren't TOASTed because it doesn't meet the condition of
> > > the following if statement.
> > >
> > > --src/backend/access/table/toast_helper.c
> > >
> > > toast_tuple_find_biggest_attribute(ToastTupleContext *ttc,
> > > bool for_compression, bool check_main)
> > > ...(snip)...
> > > int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
> > > ...(snip)...
> > > if (ttc->ttc_attr[i].tai_size > biggest_size) // <- here
> > > {
> > > biggest_attno = i;
> > > biggest_size = ttc->ttc_attr[i].tai_size;
> > > }
> > >
> > >
> > > Since TOAST_POINTER_SIZE is 18 bytes but
> > > MAXALIGN(TOAST_POINTER_SIZE) is 24 bytes, columns are not TOASTed
> > > until its size becomes larger than 24 bytes.
> > >
> > > I confirmed these sizes in my environment but AFAIU they would be
> > > the same size in any environment.
> > >
> > > So, as a result of adjusting the alignment, 20~23 bytes seems to
> > > fail.
> > >
> > > I wonder if it might be better not to adjust the alignment here
> > > as an attached patch because it succeeded in inserting 20~23
> > > bytes records.
> > > Or is there reasons to add the alignment here?
> > >
> > > I understand that TOAST is not effective for small data and it's
> > > not recommended to create a table containing hundreds of columns,
> > > but I think cases that can be successful should be successful.
> > >
> > > Any thoughts?
> >
> > How this can be correct? because while forming the tuple you might
> > need the alignment.
> >
>
> Won't it be safe because we don't align individual attrs of type
> varchar where length is less than equal to 127?

Yeah right, I just missed that point.

> --
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message japin 2021-01-19 14:06:38 Use boolean array for nulls parameters
Previous Message Amit Kapila 2021-01-19 12:58:42 Re: TOAST condition for column size