From: | Justin Pryzby <pryzby(at)telsasoft(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Andres Freund <andres(at)anarazel(dot)de>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org |
Subject: | Re: Backpatch b61d161c14 (Introduce vacuum errcontext ...) |
Date: | 2020-06-22 22:53:01 |
Message-ID: | 20200622225301.GH17995@telsasoft.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Mon, Jun 22, 2020 at 06:15:27PM -0400, Tom Lane wrote:
> Andres Freund <andres(at)anarazel(dot)de> writes:
> > No, I don't think that's a solution. I think it's wrong to have
> > something like olderrinfo in the first place. Using a struct with ~25
> > members to store the current state of three variables just doesn't make
> > sense. Why isn't this just a LVSavedPosition struct or something like
> > that?
>
> That seems like rather pointless micro-optimization really; the struct's
> not *that* large. But I have a different complaint now that I look at
> this code: is it safe at all? I see that the indname field is a pointer
> to who-knows-where. If it's possible in the first place for that to
> change while this code runs, then what guarantees that we won't be
> restoring a dangling pointer to freed memory?
I'm not sure it addresses your concern, but we talked a bunch about safety
starting here:
https://www.postgresql.org/message-id/20200326150457.GB17431%40telsasoft.com
..and concluding with an explanation about CHECK_FOR_INTERRUPTS.
20200326150457(dot)GB17431(at)telsasoft(dot)com
|And I think you're right: we only save state when the calling function has a
|indname=NULL, so we never "put back" a non-NULL indname. We go from having a
|indname=NULL at lazy_scan_heap to not not-NULL at lazy_vacuum_index, and never
|the other way around. So once we've "reverted back", 1) the pointer is null;
|and, 2) the callback function doesn't access it for the previous/reverted phase
|anyway.
When this function is called by lazy_vacuum_{heap,page,index}, it's also called
a 2nd time to restore the previous phase information. When it's called the
first time by lazy_vacuum_index(), it does errinfo->indname = pstrdup(indname),
and on the 2nd call then does pfree(errinfo->indame), followed by
errinfo->indname = NULL.
|static void
|update_vacuum_error_info(LVSavedPosition *errinfo, int phase, BlockNumber blkno,
| char *indname)
|{
| errinfo->blkno = blkno;
| errinfo->phase = phase;
|
| /* Free index name from any previous phase */
| if (errinfo->indname)
| pfree(errinfo->indname);
|
| /* For index phases, save the name of the current index for the callback */
| errinfo->indname = indname ? pstrdup(indname) : NULL;
|}
If it's inadequately clear, maybe we should do:
if (errinfo->indname)
+ {
pfree(errinfo->indname);
+ Assert(indname == NULL);
+ }
--
Justin
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2020-06-22 23:03:08 | Re: Backpatch b61d161c14 (Introduce vacuum errcontext ...) |
Previous Message | David Rowley | 2020-06-22 22:50:16 | Re: Parallel Seq Scan vs kernel read ahead |