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

标签 c postgresql docker

我尝试关注this简单的例子。因此,我创建了一个包含四个文件的文件夹 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在那儿。那么,这有什么问题,我该如何解决呢?非常感谢!

PS。这是我的 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,这是我从here获取的。我使用 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
    • 入口点.sh
    • 添加我
      • addme--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 而不是手动复制文件。

关于在 "could not access file $libdir/..."中为 Postgres 11 结果创建扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59172757/

相关文章:

sql - 使用 WHERE、AND 和 ILIKE 查询

postgresql - 查找每天的最小值和日期时间

postgresql - postgres 中的时间旅行 - 违反 PRIMARY KEY 约束

macos - Docker 容器中本地模式的 PySpark 出现奇怪的异常

docker - docker :构建图像并启动容器后了解图像层

windows - Windows 上的 boot2docker 缺少 apt-get/包管理器

C 头文件 - 包含的正确方法

c - 在 DFS 实现中使用程序堆栈

c++ - CreateProcess后如何实时获取内存?

c - MPI:Printf 语句未在正确的时间执行