PostgreSQL 9.5, 9.6, 10, 11, 12, 13
支持range和hash分区
可按表达式和复合键分区
可以自动或者手动分区管理
支持整数、浮动点、日期和其他类型,包括domains
实现了分区表JOIN,子查询过滤分区
使用RuntimeAppend和RuntimeMergeAppend custom plan nodes实现了动态分区选择。
分区过滤器:替代插入触发器,性能提升
用于跨分区更新查询的PartitionRouter and PartitionOverseer(而不是使用触发器)
为新插入的数据(仅用于范围分区)自动创建分区,建议关闭,插入一个很大的值,会造成创建很多分区表
COPY 能够直接操作分区,提升效率
用于分区创建事件处理的用户定义回调
通过partition_table_concurrently进行非阻塞,并发的数据迁移
支持FDW
从10版本支持部分分区命令,如ATTACH PARTITION, DETACH PARTITION and CREATE TABLE … PARTITION OF
git clone https://github.com/postgrespro/pg_pathman.git
make install USE_PGXS=1
PG配置文件添加:
shared_preload_libraries = 'pg_pathman'
#创建schema并赋权,然后创建该插件
CREATE SCHEMA pathman;
GRANT USAGE ON SCHEMA pathman TO PUBLIC;
CREATE EXTENSION pg_pathman WITH SCHEMA pathman;
分区创建函数:
hash分区
create_hash_partitions(parent_relid REGCLASS, --主表OID
expression TEXT, --指定分区键,分区键可以是列,也可以是一个表达式
partitions_count INTEGER, --分区数量
partition_data BOOLEAN DEFAULT TRUE, --是否立即从父表迁移数据到子表,建议关闭,因为表会被锁到数据迁移结束
partition_names TEXT[] DEFAULT NULL, --可以指定分区名称
tablespaces TEXT[] DEFAULT NULL) --可以指定表空间
范围分区
create_range_partitions(parent_relid REGCLASS, -- 主表OID
expression TEXT, -- 分区列名或者表达式
start_value ANYELEMENT, --开始值
p_interval ANYELEMENT, --指定间隔
p_count INTEGER DEFAULT NULL --指定分区数量
partition_data BOOLEAN DEFAULT TRUE) --是否立即从父表迁移数据到子表,建议关闭,因为表会被锁到数据迁移结束
create_range_partitions(parent_relid REGCLASS,
expression TEXT,
start_value ANYELEMENT,
p_interval INTERVAL,
p_count INTEGER DEFAULT NULL,
partition_data BOOLEAN DEFAULT TRUE)
create_range_partitions(parent_relid REGCLASS,
expression TEXT,
bounds ANYARRAY,
partition_names TEXT[] DEFAULT NULL,
tablespaces TEXT[] DEFAULT NULL,
partition_data BOOLEAN DEFAULT TRUE)
在create_range_partitions()的时候,可通过以下函数构建边界
generate_range_bounds(p_start ANYELEMENT,
p_interval INTERVAL,
p_count INTEGER)
generate_range_bounds(p_start ANYELEMENT,
p_interval ANYELEMENT,
p_count INTEGER)
非阻塞迁移数据,通过短事物,批量从父表迁移数据,如果不能获取到batch_size相关行的锁,那么会休眠sleep_time,循环尝试60次后如果还不能获取锁,那么退出。
partition_table_concurrently(relation REGCLASS,
batch_size INTEGER DEFAULT 1000,
sleep_time FLOAT8 DEFAULT 1.0)
停止非阻塞并发迁移数据任务
stop_concurrent_part_task(relation REGCLASS)
替换指定的分区,lock_parent参数可以防止操作(INSERT/UPDATE/ALTER)父表
replace_hash_partition(old_partition REGCLASS,
new_partition REGCLASS,
lock_parent BOOLEAN DEFAULT TRUE)
分离一个range分区
split_range_partition(partition_relid REGCLASS,
split_value ANYELEMENT,
partition_name TEXT DEFAULT NULL,
tablespace TEXT DEFAULT NULL)
合并多个邻近的分区,所有数据合并至第一个分区
merge_range_partitions(variadic partitions REGCLASS[])
按pathman_config.range_interval设置,在末尾追加一个新的范围分区
append_range_partition(parent_relid REGCLASS,
partition_name TEXT DEFAULT NULL,
tablespace TEXT DEFAULT NULL)
按pathman_config.range_interval设置,在头分区添加一个新的范围分区
prepend_range_partition(parent_relid REGCLASS,
partition_name TEXT DEFAULT NULL,
tablespace TEXT DEFAULT NULL)
指定一个范围边界,添加范围分区
add_range_partition(parent_relid REGCLASS,
start_value ANYELEMENT,
end_value ANYELEMENT,
partition_name TEXT DEFAULT NULL,
tablespace TEXT DEFAULT NULL)
删除范围分区
drop_range_partition(partition TEXT, delete_data BOOLEAN DEFAULT TRUE)
将已有的表绑定到分区父表
attach_range_partition(parent_relid REGCLASS,
partition_relid REGCLASS,
start_value ANYELEMENT,
end_value ANYELEMENT)
将表从父表解绑
detach_range_partition(partition_relid REGCLASS)
针对单个主表禁用分区表插件
disable_pathman_for(parent_relid REGCLASS)
删除所有分区,指定数据是否迁移至主表
drop_partitions(parent_relid REGCLASS,
delete_data BOOLEAN DEFAULT FALSE)
要完全删除分区表以及所有分区,请使用DROP table cascade。但是在逻辑复制环境中,发布端发出drop table后,是通过pathman_ddl_trigger事件触发器触发的,但是默认订阅端不会生效,需要在订阅端也配置该触发器:
ALTER EVENT TRIGGER pathman_ddl_trigger ENABLE ALWAYS;
更新时间范围间隔,TIMESTAMP类型最小时间为1毫秒,DATE至少是1天
set_interval(relation REGCLASS, value ANYELEMENT)
在查询的时候,执行计划是否禁用主表
set_enable_parent(relation REGCLASS, value BOOLEAN)
是否自动扩展分区,注意只限范围分区。比如新插入的数据不在已有的分区范围内,会自动创建分区
set_auto(relation REGCLASS, value BOOLEAN)
回调函数是创建或者绑定分区的时候触发的函数
set_init_callback(relation REGCLASS, callback REGPROC DEFAULT 0)
比如part_init_callback(args JSONB) RETURNS VOID,args参数是一个JSONB类型,因分区类型不同,由以下不同分区类型对应的字段组成。
/* RANGE-partitioned table abc (child abc_4) */
{
"parent": "abc",
"parent_schema": "public",
"parttype": "2",
"partition": "abc_4",
"partition_schema": "public",
"range_max": "401",
"range_min": "301"
}
/* HASH-partitioned table abc (child abc_0) */
{
"parent": "abc",
"parent_schema": "public",
"parttype": "1",
"partition": "abc_0",
"partition_schema": "public"
}
当INSERT的新数据超出分区范围时,是否使用SpawnPartitionsWorker在单独的事务中创建新分区
set_set_spawn_using_bgw(relation REGCLASS, value BOOLEAN)
pathman_config 存放分区表列表
CREATE TABLE IF NOT EXISTS pathman_config (
partrel REGCLASS NOT NULL PRIMARY KEY,
expr TEXT NOT NULL,
parttype INTEGER NOT NULL,
range_interval TEXT,
cooked_expr TEXT);
pathman_config_params这张表存储的参数设置将覆盖标准配置
CREATE TABLE IF NOT EXISTS pathman_config_params (
partrel REGCLASS NOT NULL PRIMARY KEY,
enable_parent BOOLEAN NOT NULL DEFAULT TRUE,
auto BOOLEAN NOT NULL DEFAULT TRUE,
init_callback TEXT DEFAULT NULL,
spawn_using_bgw BOOLEAN NOT NULL DEFAULT FALSE);
pathman_concurrent_part_tasks当前正在运行的数据迁移任务
-- helper SRF function
CREATE OR REPLACE FUNCTION show_concurrent_part_tasks()
RETURNS TABLE (
userid REGROLE,
pid INT,
dbid OID,
relid REGCLASS,
processed INT,
status TEXT)
AS 'pg_pathman', 'show_concurrent_part_tasks_internal'
LANGUAGE C STRICT;
CREATE OR REPLACE VIEW pathman_concurrent_part_tasks
AS SELECT * FROM show_concurrent_part_tasks();
pathman_partition_list 列出了所有分区表,包括他们的父表和范围边界
-- helper SRF function
CREATE OR REPLACE FUNCTION show_partition_list()
RETURNS TABLE (
parent REGCLASS,
partition REGCLASS,
parttype INT4,
expr TEXT,
range_min TEXT,
range_max TEXT)
AS 'pg_pathman', 'show_partition_list_internal'
LANGUAGE C STRICT;
CREATE OR REPLACE VIEW pathman_partition_list
AS SELECT * FROM show_partition_list();
pathman_cache_stats 显示cache的使用情况
-- helper SRF function
CREATE OR REPLACE FUNCTION @extschema@.show_cache_stats()
RETURNS TABLE (
context TEXT,
size INT8,
used INT8,
entries INT8)
AS 'pg_pathman', 'show_cache_stats_internal'
LANGUAGE C STRICT;
CREATE OR REPLACE VIEW @extschema@.pathman_cache_stats
AS SELECT * FROM @extschema@.show_cache_stats();
https://github.com/postgrespro/pg_pathman#custom-plan-nodes
https://github.com/digoal/blog/blob/master/201610/20161024_01.md