Re: COPY FROM WHEN condition
David Rowley <david.rowley@2ndquadrant.com>
From: David Rowley <david.rowley@2ndquadrant.com>
To: Andres Freund <andres@anarazel.de>
Cc: Tomas Vondra <tomas.vondra@2ndquadrant.com>,
Surafel Temesgen <surafel3000@gmail.com>, Alvaro Herrera <alvherre@2ndquadrant.com>, Adam Berlin <berlin.ab@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2019-04-03T07:00:09Z
Lists: pgsql-hackers
Attachments
- david_tableam_copy_v4.patch (application/octet-stream) patch v4
On Wed, 3 Apr 2019 at 18:56, Andres Freund <andres@anarazel.de> wrote:
> > +/* Class the buffer full if there are >= this many bytes of tuples stored */
> > +#define MAX_BUFFERED_BYTES 65535
>
> Random aside: This seems pretty small (but should be changed separately.
Yeah, my fingers were hovering over this. I was close to making it
1MB, but thought I'd better not.
> > +typedef struct CopyMultiInsertBuffer
> > +{
> > + TupleTableSlot *slots[MAX_BUFFERED_TUPLES]; /* Array to store tuples */
> > + ResultRelInfo *resultRelInfo; /* ResultRelInfo for 'relid' */
> > + BulkInsertState bistate; /* BulkInsertState for this rel */
> > + int nused; /* number of 'slots' containing tuples */
> > + uint64 linenos[MAX_BUFFERED_TUPLES]; /* Line # of tuple in copy
> > + * stream */
> > +} CopyMultiInsertBuffer;
>
> I don't think it's needed now, but you'd probably achieve a bit better
> locality by storing slots + linenos in a single array of (slot,lineno).
You're right, but right now I only zero the slots array and leave the
linenos uninitialised. Merging them to one would double the area of
memory to zero. I'm not sure if that's worse or not, but I do know if
the number of partitions exceeds MAX_PARTITION_BUFFERS and we change
partitions quite a lot during the copy then we could end up
initialising buffers quite often. I wanted to keep that as cheap as
possible.
> > +/*
> > + * CopyMultiInsertBuffer_Init
> > + * Allocate memory and initialize a new CopyMultiInsertBuffer for this
> > + * ResultRelInfo.
> > + */
> > +static CopyMultiInsertBuffer *
> > +CopyMultiInsertBuffer_Init(ResultRelInfo *rri)
> > +{
> > + CopyMultiInsertBuffer *buffer;
> > +
> > + buffer = (CopyMultiInsertBuffer *) palloc(sizeof(CopyMultiInsertBuffer));
> > + memset(buffer->slots, 0, sizeof(TupleTableSlot *) * MAX_BUFFERED_TUPLES);
>
> Is there a reason to not just directly palloc0?
Yeah, I'm too cheap to zero the entire thing, per what I mentioned
above. linenos does not really need anything meaningful put there
during init. It'll get set when we consume the slots.
> > +
> > + /* Remove back-link to ourself */
> > + buffer->resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
> > +
> > + ReleaseBulkInsertStatePin(buffer->bistate);
>
> Hm, afaict this still leaks the bistate itself?
Oops, I forgot about that one. v4 attached.
--
David Rowley http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Commits
-
Remove unused struct member, enforce multi_insert callback presence.
- 57a7a3adfe4e 12.0 landed
-
Separate per-batch and per-tuple memory contexts in COPY
- 36a1281f86c0 12.0 landed
-
Fix handling of volatile expressions in COPY FROM ... WHERE
- 4a8283d0ec5a 12.0 landed
-
Allow COPY FROM to filter data using WHERE conditions
- 31f3817402da 12.0 landed
-
Remove obsolete netbsd dynloader code
- b68ff3ea672c 12.0 cited