c语言 - 在"could not access file $libdir/..."中为 Postgres 11 结果创建扩展



我尝试遵循这个简单的例子。因此,我创建了一个包含四个文件的文件夹addme。Makerfile 看起来像:

MODULES = addme
EXTENSION = addme
DATA = addme--0.0.1.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)

addme.control 文件看起来像

comment = 'Simple number add function'
default_version = '0.0.1'
relocatable = true
module_pathname = '$libdir/addme'

addme.c 非常简单:

#include "postgres.h"
#include "fmgr.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(addme);
Datum addme(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 + arg2);
}

最后addme--0.0.1.sql看起来像:

CREATE OR REPLACE FUNCTION
addme(int, int) RETURNS int AS 'MODULE_PATHNAME','addme'
LANGUAGE C STRICT;

在 docker 中,我安装了 Postgres 11 以及所有必要的库和依赖项:

FROM ubuntu:latest
....
....
RUN ... apt-get install -y postgresql-11 postgresql-client-11 postgresql-contrib-11

还安装了postgresql-server-dev-allpostgresql-common。PATH 的设置如下:

ENV PATH="/usr/lib/postgresql/11/bin:${PATH}"

此外,我像这样编译addme扩展:

RUN cd /usr/src/addme && 
make clean && make PG_CONFIG=/usr/bin/pg_config && make install PG_CONFIG=/usr/bin/pg_config && 
cp ./addme.control /usr/share/postgresql/11/extension/addme.control && 
cp ./addme--0.0.1.sql /usr/share/postgresql/11/extension/addme--0.0.1.sql && 
cp ./addme.o /usr/lib/x86_64-linux-gnu/addme.o && 
cp ./addme.so /usr/lib/x86_64-linux-gnu/addme.so 

一切看起来都不错。我构建并运行容器,我看到 Postgres 正在工作,我可以列出它的数据库等等。但是,当我尝试创建扩展addme时,出现错误。这是来自 docker shell 内部的完整堆栈跟踪:

[root@localhost ~]# docker exec -it 7e9f9c331351 /bin/bash
root@7e9f9c331351:/# su postgres
postgres@7e9f9c331351:/$ psql
psql (11.6 (Ubuntu 11.6-1.pgdg18.04+1))
Type "help" for help.
postgres=# c test
You are now connected to database "test" as user "postgres".
test=# create extension addme;
ERROR:  could not access file "$libdir/addme": No such file or directory
test=# q
postgres@7e9f9c331351:/$ pg_config --libdir
/usr/lib/x86_64-linux-gnu
postgres@7e9f9c331351:/$ ls /usr/src/addme
addme--0.0.1.sql  addme.bc  addme.c  addme.control  addme.o  addme.so  Makefile
postgres@7e9f9c331351:/$ cd /usr/share/postgresql/11/extension/
postgres@7e9f9c331351:/usr/share/postgresql/11/extension$ find . -name "addme*"
./addme--0.0.1.sql
./addme.control

如您所见,它找不到"$libdir/addme"。但问题是$libdir是/usr/lib/x86_64-linux-gnuaddme.oaddme.so都在那里。那么,这有什么问题,我该如何解决呢?提前非常感谢!

附言。这是我的 Dockerfile:

FROM ubuntu:latest
ENV OS_LOCALE="en_US.UTF-8" 
DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE}
ENV LANG=${OS_LOCALE} 
LANGUAGE=${OS_LOCALE} 
LC_ALL=${OS_LOCALE} 
PG_VERSION=11 
PG_USER=postgres 
PG_HOME=/var/lib/postgresql 
PG_RUN_DIR=/run/postgresql 
PG_LOG_DIR=/var/log/postgresql 
PATH="/usr/lib/postgresql/11/bin:${PATH}"
ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" 
PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" 
PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main"
# Install basic libraries
RUN apt-get update && 
apt-get -y install gcc 
libprotobuf-dev protobuf-compiler 
git build-essential 
wget checkinstall zlib1g-dev 
make automake autoconf cmake
# Install Postgresql
RUN dpkg-reconfigure locales && apt-get install -y sudo gnupg 
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - 
&& echo 'deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main' > /etc/apt/sources.list.d/pgdg.list 
&& apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 
# Cleaning
&& apt-get purge -y --auto-remove gnupg 
&& rm -rf ${PG_HOME} 
&& rm -rf /var/lib/apt/lists/* 
&& touch /tmp/.EMPTY_DB
COPY entrypoint.sh /sbin/entrypoint.sh
RUN chmod 755 /sbin/entrypoint.sh
# Install Postgresql Rabbitmq extension
RUN apt-get update && apt-get install -y --no-install-recommends 
python-psycopg2 libpq-dev 
postgresql-server-dev-all postgresql-common && 
mkdir /usr/src/addme
COPY ./addme /usr/src/addme
#RUN cd /usr/src/addme && 
#    make clean && make PG_CONFIG=/usr/bin/pg_config && make install PG_CONFIG=/usr/bin/pg_config && 
#    cp ./addme.control /usr/share/postgresql/11/extension/addme.control && 
#    cp ./addme--0.0.1.sql /usr/share/postgresql/11/extension/addme--0.0.1.sql && 
#    cp ./addme.o /usr/lib/x86_64-linux-gnu/addme.o && 
#    cp ./addme.so /usr/lib/x86_64-linux-gnu/addme.so 
RUN cd /usr/src/addme && 
make && make install
EXPOSE 5432/tcp
VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"]
CMD ["/sbin/entrypoint.sh"]

它使用 entrypoint.sh,这是我从这里获取的。我使用 docker-compose.yml 构建和运行 Docker:

version: '3.7'
services:
postgres_db:
build: ./Database
environment:
- DB_USER=test
- DB_NAME=test
- DB_PASS=test
restart: always
ports:
- "5432:5432"
volumes:
- "./postgres-data:/var/lib/postgresql"

因此,我的文件夹结构最终如下所示:

  • docker-compose.yml
  • 数据库
    • Dockerfile
    • entrypoint.sh
    • 添加我
      • 添加--0.0.1.sql
      • addme.c
      • addme.control
      • 生成文件

您在错误的位置安装了共享库addme.so

它应该安装在PostgreSQL库目录中,而不是/usr/lib/x86_64-linux-gnu。PostgreSQL 库目录可以找到

pg_config --libdir

并且可能/usr/share/postgresql/11/lib.

为避免此类问题,建议您使用make install而不是手动复制文件。

最新更新