Re: Weirdness using Executor Hooks

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Eric Ridge <eebbrr(at)gmail(dot)com>
Cc: Andres Freund <andres(at)anarazel(dot)de>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Weirdness using Executor Hooks
Date: 2015-06-18 22:04:01
Message-ID: 4702.1434665041@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Eric Ridge <eebbrr(at)gmail(dot)com> writes:
> On Thu, Jun 18, 2015 at 5:30 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>>> As a data point, that might be interesting to know, but I'd still be
>>> scratching my head about how it happened. Postgres doesn't load an
>>> extension library more than once per backend session, does it?

>> It's not supposed to, and AFAICS internal_load_library() will treat
>> either an exact pathname match or an inode-number match as being
>> "already loaded". I wonder if you might be doing something that
>> confuses those checks. It does not look like we try terribly hard
>> to canonicalize library pathnames --- might you have some references
>> under different relative paths, for instance? The inode number
>> check would perhaps fail if you'd installed a new library version,
>> but it's unclear to me why the pathname check would fail.

> According to the docs, anything listed in 'local_preload_libraries'
> has to be in $libdir/plugins (whereas extensions just go to $libdir),
> so rather than duplicate the .so, the "copy" in $libdir/plugins is
> just a symlink to ../my_extension.so.

> Could that be confusing things?

Hm, maybe. The scenario that had occurred to me is like this: suppose
the declaration of C-language function f1() refers to the shlib by
an absolute pathname, while function f2() refers to the same shlib by
a relative pathname, or maybe one with some extra ".." maneuvering.
Then what would happen if f1() is called first in a session is that
the shlib would get loaded under f1's name for it. Each time f2()
is called after that, internal_load_library() doesn't see a match
on pathname, but it does see a match on inode, so it doesn't perform
an extra dlopen() and all is well. Then by and by you replace the
library file, so now it has a new inode number. The next f2() call
will see neither a pathname nor an inode match, so the new library
file gets dlopen'd, and kaboom.

However, based on your comment above, I'm betting that the initial
reference is via the $libdir/plugins symlink, but you have functions
that name the library via the shorter direct path, and it's a call
of one of those that fails.

What we were expecting I guess is that such functions would be declared
to reference the library underneath $libdir/plugins, not that you'd use
a symlink.

We could conceivably forestall such problems if we were willing to
chase/expand symlinks every time we generate a candidate library
pathname; but that would be extremely expensive so I'm disinclined
to add it to the critical path for calling extension functions.

Probably the best thing is to call this pilot error and add a
documentation note warning against doing it that way.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Petr Jelinek 2015-06-18 22:38:21 Re: Inheritance planner CPU and memory usage change since 9.3.2
Previous Message Eric Ridge 2015-06-18 21:45:37 Re: Weirdness using Executor Hooks