Re: stack usage in toast_insert_or_update()

Поиск
Список
Период
Сортировка
От Pavan Deolasee
Тема Re: stack usage in toast_insert_or_update()
Дата
Msg-id 2e78013d0701310319o2d9d0bbdne2b7396732174a5b@mail.gmail.com
обсуждение исходный текст
Ответ на Re: stack usage in toast_insert_or_update()  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: stack usage in toast_insert_or_update()  ("Pavan Deolasee" <pavan.deolasee@gmail.com>)
Re: stack usage in toast_insert_or_update()  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers

On 1/31/07, Tom Lane <tgl@sss.pgh.pa.us> wrote:
"Pavan Deolasee" <pavan.deolasee@gmail.com> writes:
> Btw, I noticed that the toast_insert_or_update() is re-entrant.
> toast_save_datum() calls simple_heap_insert() which somewhere down the
> line calls toast_insert_or_update() again.

The toast code takes pains to ensure that the tuples it creates won't be
subject to re-toasting.  Else it'd be an infinite recursion.

I think I found it. The toast_insert_or_update() function gets into an unnecessary
recursion because of alignment issues. It thus toasts already toasted data. This
IMHO might be causing unnecessary overheads for each toast operation.

The default value of TOAST_TUPLE_THRESHOLD is 2034 (assuming 8K block size)

TOAST_MAX_CHUNK_SIZE is defined as below:

#define TOAST_MAX_CHUNK_SIZE    (TOAST_TUPLE_THRESHOLD -            \
             MAXALIGN(                                               \
                MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) +   \
                sizeof(Oid) +                                       \
                sizeof(int32) +                                     \
                VARHDRSZ))

So the default value of TOAST_MAX_CHUNK_SIZE is set to 1994.

When toast_insert_or_update() returns a tuple for the first chunk, t_len
is set to 2034 (TOAST_MAX_CHUNK_SIZE + tuple header + chunk_id
+ chunk_seqno + VARHDRSZ)

In heap_insert(), we MAXALIGN(tup->t_len) before comparing it with
TOAST_TUPLE_THRESHOLD to decide whether to invoke TOAST or not.
In this corner case, MAXALIGN(2034) = 2036 > TOAST_TUPLE_THRESHOLD
and so TOAST is invoked again.

Fortunately, we don't get into infinite recursion because reltoastrelid is set to
InvalidOid for toast tables and hence TOASTing is not invoked in the second
call.

Attached is a patch which would print the recursion depth for
toast_insert_or_update() before PANICing the server to help us
examine the core.

Let me know if this sounds like an issue and  I can work out a patch.

Thanks,
Pavan

--

EnterpriseDB     http://www.enterprisedb.com

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

Предыдущее
От: Heikki Linnakangas
Дата:
Сообщение: Re: crash on 8.2 and cvshead - failed to add item to the
Следующее
От: "Pavan Deolasee"
Дата:
Сообщение: Re: stack usage in toast_insert_or_update()