在 Docker 中搭建带有 pg_partman 插件的 PostGIS 环境并自动管理分区表

304 阅读2分钟

1、新建Dockerfile文件

# 使用官方 PostGIS 镜像(前提是你的先pull好)
FROM postgis/postgis:latest

# 安装 PostgreSQL 插件的依赖(包括 git, clang 和 PostgreSQL 开发包)
USER root
RUN apt-get update && \
    apt-get install -y postgresql-server-dev-17 gcc make git clang-13 && \
    apt-get clean

# 安装分区自动生成插件(例如 pg_partman)
RUN git clone https://github.com/pgpartman/pg_partman.git /tmp/pg_partman \
    && cd /tmp/pg_partman && make && make install

# 复制初始化 SQL 脚本(如果需要)
#COPY init.sql /docker-entrypoint-initdb.d/

# 设置环境变量
ENV POSTGRES_DB=gisdb
ENV POSTGRES_USER=postgres

# 端口配置
EXPOSE 5432

# 容器启动时执行的默认命令
CMD ["postgres"]

2、构建镜像

在Dockerfile文件的目录下打开cmd

docker build -t postgis-with-partman .

3、启动容器

启动时设置密码

docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=123456 postgis-with-partman

或无密码启动

docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgis-with-partman

4、进入容器

docker exec -it <container_id_or_name> psql -U postgres

5、 检查 pg_partman 插件是否安装

SELECT * FROM pg_extension WHERE extname = 'pg_partman';

如果安装成功,会显示如下类似结果:

6、 创建父表,确保主键包含 created_at

CREATE TABLE public.parent_table (
    id SERIAL,
    name TEXT,
    created_at TIMESTAMPTZ NOT NULL,
    PRIMARY KEY (id, created_at)  -- 包含分区键 created_at
)
PARTITION BY RANGE (created_at);  -- 使用 RANGE 分区

7、 验证分区表

SELECT tablename
FROM pg_tables
WHERE tablename LIKE 'parent_table%';

8、 使用 pg_partman 管理分区

SELECT public.create_parent(
    p_parent_table := 'public.parent_table',
    p_control := 'created_at',
    p_interval := '1 month',
    p_type := 'range',
    p_automatic_maintenance := 'on'
);

或更详细指定参数

SELECT public.create_parent(
    p_parent_table := 'public.parent_table',
    p_control := 'created_at',
    p_interval := '1 month',
    p_type := 'range',
    p_premake := 1,  -- 设置预创建一个分区
    p_automatic_maintenance := 'on',
    p_start_partition := '2025-01-01'  -- 设置分区的起始日期
);

9、查看未插入数据前的分区表

SELECT tablename
FROM pg_tables
WHERE tablename LIKE 'parent_table%';

10、插入数据验证

INSERT INTO parent_table (name, created_at)
VALUES 
    ('Data 1', '2025-01-15'),
    ('Data 2', '2025-02-10'),
    ('Data 3', '2025-03-25');

查看分区表

SELECT tablename
FROM pg_tables
WHERE tablename LIKE 'parent_table%';

如果分区表创建成功,你应该能够看到类似于 parent_table_2025_01, parent_table_2025_02 等表名,其中数字部分代表不同的分区。

确保数据按日期被分配到正确的分区。如果你插入了 2025 年 1 月的数据,它应该出现在 parent_table_2025_01 中,而 2025 年 2 月的数据应该出现在 parent_table_2025_02 中。