Thread

  1. Harden internal_load_library() against transient errors

    Mark Dilger <mark.dilger@enterprisedb.com> — 2026-02-27T16:43:39Z

    Hackers,
    
    During stress testing on macOS of a table access method loaded from
    a shared library, after rapidly killing and restarting the postgres server
    multiple times, postgres can fail to load the shared library for the
    table access method and fail.  This same problem can likely be hit
    for other libraries, though that was not tried in the course of
    debugging this problem.
    
    The problem seems to stem from several factors.  First, when the
    library is loaded in response to the postgresql.conf entry
    
      shared_preload_library = 'mytam'
    
    the library name gets expanded to the full path /path/to/mytam.dylib
    and that gets stored.  Later, when the access method handler is
    called, it uses $libdir/mytam.  The $libdir/ prefix gets stripped in
    load_external_function, and it searches for just "mytam".  The call
    to expand_dynamic_library_name("mytam") tries to find it, but
    pg_file_exists() can get a spurious failure from macOS despite the
    file existing.  In that case, pg_file_exists() fails and
    internal_load_libary("mytam") gets called without the full path,
    leading to a strcmp for "mytam" to fail, because it doesn't match
    "/path/to/mytam.dylib".  Then stat("mytam") gets called, which fails
    with ENOENT.
    
    The real bug here appears to be in macOS file system incorrectly
    returning ENOENT, but this is highly reproducible for me, and we
    should be able to harden postgres to handle it.
    
    I propose that we modify internal_load_library() in dfmgr.c to have
    a fallback when the matching fails to check whether the library was
    already loaded during server startup.
    
    Thoughts?
    
    
    
    -- 
    
    *Mark Dilger*