我尝试遵循这个简单的例子。因此,我创建了一个包含四个文件的文件夹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-all
和postgresql-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-gnu
,addme.o
和addme.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
而不是手动复制文件。