
O PostgreSQL↳PostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data → tem três parâmetros para pré-carregar bibliotecas compartilhadas em um backend↳Back-end49 conteúdosIntegração front-end com backend: 7 decisões que evitam caos entre APIs, BFF e GraphQLDev (Back & Front) · abr 2026Como criar uma FAKE API REST para testes — JSONPlaceholderDev (Back & Front) · set 2025Construindo um aplicativo de bate-papo de IA simples com Spring AI e AngularDev (Back & Front) · jul 2025Ver tudo em Dev (Back & Front) →, e o menos usado deles é justamente o tema de mais uma edição da série "All Your GUCs in a Row", de Christophe Pettus. Em seu texto no The Build (republicado no Planet PostgreSQL), Pettus descreve o local_preload_libraries sem meias palavras: é "o parâmetro de preload para pessoas que não têm permissão de usar os outros dois". Vale entender exatamente o que ele faz, por que existe e em que raro cenário ele é a ferramenta correta, porque, segundo o mecanismo de falha que a fonte descreve mais adiante, a confusão em torno dele pode impedir até superusuários de se conectar.
O que ele faz e como difere dos outros
O PostgreSQL oferece três GUCs de preload:
shared_preload_libraries: carrega no processo postmaster, exige restart, contextopostmaster;session_preload_libraries: carrega em cada backend na conexão, só para superusuário, lê de qualquer lugar de$libdir;local_preload_libraries: carrega em cada backend na conexão, qualquer role pode definir, mas só lê de um único diretório, o$libdir/plugins.
O local_preload_libraries funciona quase igual ao session_preload_libraries, com duas diferenças cruciais: qualquer role pode configurá-lo e, em troca dessa liberdade, ele fica restrito a $libdir/plugins, um diretório que em uma instalação padrão está vazio (quando existe). Seu valor padrão é vazio e seu contexto é user, o que permite defini-lo no postgresql.conf, via ALTER ROLE ... SET, via ALTER DATABASE ... SET ou na própria conexão com PGOPTIONS="-c local_preload_libraries=mylib".
O SET que não faz nada
Um detalhe traiçoeiro apontado por Pettus: é possível executar um SET local_preload_libraries no meio da sessão. O comando tem sucesso, o SHOW passa a reportar o novo valor, e nada é carregado. A lista é lida uma única vez, durante a inicialização do backend, e nunca mais. Nas palavras do autor, é um dos poucos GUCs em que um SET bem-sucedido é "puramente decorativo".
Por baixo dos panos, após a autenticação e depois de aplicadas as configurações de role e database (pg_db_role_setting), o backend percorre primeiro session_preload_libraries e depois local_preload_libraries, fazendo o equivalente a um LOAD para cada entrada. Para a lista local, um nome simples como mylib é reescrito para $libdir/plugins/mylib. Qualquer coisa que não tenha exatamente a forma $libdir/plugins/, sem separadores de diretório adicionais (o que bloqueia truques com ..), é rejeitada com access to library "..." is not allowed. O dynamic_library_path não entra na jogada: o caminho é fixo.
O diretório é todo o modelo de segurança
Esse ponto merece atenção de qualquer DBA preocupado com governança. O $libdir/plugins é o único modelo de segurança do parâmetro. O PostgreSQL nunca coloca nada ali por conta própria. Um administrador precisa, deliberadamente, instalar cada biblioteca, e a partir do momento em que ela está no diretório, toda role do servidor pode carregá-la em suas próprias sessões. A documentação atribui ao administrador a responsabilidade de instalar apenas bibliotecas "seguras", e é justamente por causa dessa responsabilidade que o diretório está vazio em praticamente todos os lugares.
Um parâmetro à procura de um caso de uso
A história explica muito. O parâmetro nasceu no PostgreSQL 8.2, no mesmo commit que renomeou preload_libraries para shared_preload_libraries e inventou o diretório de plugins. O motivador era o depurador de PL/pgSQL da EDB, que queria permitir a não superusuários carregar um hook de instrumentação em seus próprios backends. Só que o depurador migrou para shared_preload_libraries poucas versões depois (breakpoints globais exigem isso), e o local_preload_libraries ficou segurando um caso de uso que ninguém tinha.
Pior: da 8.2 até a 9.4, ele tinha contexto de backend, configurável apenas via postgresql.conf ou PGOPTIONS, enquanto a documentação recomendava alegremente ALTER ROLE SET, que nunca havia funcionado. A 9.4 trouxe o session_preload_libraries, que era o que os DBAs realmente queriam: restrito a superusuário, carregando de qualquer lugar de $libdir e funcionando com ALTER ROLE. Só na 9.5 o local_preload_libraries passou a contexto user, fazendo o ALTER ROLE finalmente cumprir o que o manual prometia havia anos. Como resume Pettus, ele tem um trabalho, "só que é um trabalho que quase ninguém o contratou para fazer".
O modo de falha que derruba conexões
Aqui está o risco operacional concreto. Como toda a família de preload, se uma biblioteca listada não for encontrada, a conexão falha com FATAL. Nada valida o nome na hora de configurar. Um ALTER ROLE developer SET local_preload_libraries = 'auto_explian' (repare no erro de digitação) é aceito sem reclamação, e o developer descobre o problema no próximo login, precisando que um superusuário rode ALTER ROLE developer RESET local_preload_libraries para deixá-lo entrar de volta.
Se o erro de digitação estiver no postgresql.conf, ninguém consegue conectar, nem superusuários. Como o contexto não é postmaster, corrigir o arquivo e recarregar resolve, sem restart. Mas você não terá uma sessão para rodar pg_reload_conf(), então a saída é pg_ctl reload pelo shell. Para diagnóstico, no PostgreSQL 18 o pg_get_loaded_modules() informa o que de fato foi carregado na sessão (a coluna útil é file_name); antes da 18 não há resposta no nível SQL, e resta ler /proc//maps.
Quando (não) usar
A orientação de Pettus é direta: se você é o DBA e quer uma biblioteca em algumas sessões, este não é o seu parâmetro. Use session_preload_libraries com ALTER ROLE, que carrega de $libdir sem exigir a curadoria de um diretório, e cujo gate por superusuário é o gate correto.
O único trabalho que o local_preload_libraries faz e nada mais faz é permitir que roles se habilitem por conta própria, por conexão, sem abrir um chamado. O exemplo prático que fecha o texto: fazer um symlink de auto_explain.so para $libdir/plugins/, conceder GRANT SET ON PARAMETER auto_explain.log_min_duration, auto_explain.log_analyze TO developers (o GRANT SET exige a versão 15 ou superior, pois os parâmetros auto_explain.* têm contexto de superusuário), e então um desenvolvedor pode ligar o log de planos para uma única sessão de psql apenas com PGOPTIONS, sem depender de ninguém. É uma conveniência real, ainda que estreita.
Se você está recorrendo a esse parâmetro por qualquer outra razão, provavelmente é porque o session_preload_libraries é restrito a superusuário e você não é um, e isso, conclui Pettus, é o parâmetro funcionando exatamente como projetado.
Fonte 1: Planet PostgreSQL (https://postgr.es/p/9sY)
Fonte: Planet PostgreSQL
Este artigo foi escrito por Roberto Diniz, colunista de banco de dados do iMasters, um agente de inteligência artificial com revisão editorial humana. Publicado sob revisão editorial de Rafael Chinaglia - iMasters. Saiba como produzimos no expediente.











Comentários
Ninguém comentou ainda. Começa a conversa?