GaussDB分区表自动新增分区

时间:2024-03-26 09:40:24

前言

GaussDB是华为自主研发的企业级分布式关系型数据库,支持集中式和分布式两种部署方式。为企业提供了高可用,高可靠,高安全等能力,其产品全栈自研,并且具有完善生态工具和开源社区。在实际去O的项目过程,经常会遇到分区表的迁移,本文为大家介绍GaussDB分区表设置自动新增分区。

分区表及其语法介绍

Oracle的分区表,应该是我们使用频率比较高的数据库对象,目前GaussDB已经支持了分区表的功能,但是存在分布式不支持分区表设置自动新增分区,对于用户的体验不是很友好。

分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储。这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。分区表和普通表相比具有以下优点:

1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索效率。

2、增强可用性:如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。

3、方便维护:如果分区表的某个分区出现故障,需要修复数据,只修复该分区即可。

分区表目前支持常见的范围分区表、间隔分区表、列表分区表、哈希分区表等,其创建语法如下:

CREATE TABLE [ IF NOT EXISTS ] partition_table_name
( [
{ column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
| table_constraint
| LIKE source_table [ like_option [...] ] }[, ... ]
] )
[ AUTO_INCREMENT [ = ] value ]
[ WITH ( {storage_parameter = value} [, ... ] ) ]
[ COMPRESS | NOCOMPRESS ]
[ TABLESPACE tablespace_name ]
PARTITION BY {
{RANGE [COLUMNS] (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name
[, ... ] ) ] ] [ PARTITIONS integer ] ( partition_less_than_item [, ... ] )} 
} [ { ENABLE | DISABLE } ROW MOVEMENT ];

如上述语法结构,集中式建设置分区表自动新增分区的功能为INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ], interval_expr表示自动创建分区的间隔,例如:1 day、1 month。另外对于指定了INTERVAL子句的语法格式,范围分区策略的分区键仅支持1列。

二、分区表自动新增验证

1、主备集群验证分区表自动新增分区

1) 创建测试用例的业务表。

CREATE TABLE css_ss_channelflow(
"id" VARCHAR(32)  NOT NULL,
"create_time" timestamp  NOT NULL DEFAULT CURRENT_TIMESTAMP,
"net_check_flag" INT4  NULL,
"ip_flag" VARCHAR(20)  NULL
) 
 PARTITION BY RANGE("create_time") interval ('1 month')
(
 PARTITION IBIS_P_FLOW_04 VALUES LESS THAN (' 2017-04-01 00:00:00'),
 PARTITION SYS_P24777 VALUES LESS THAN (' 2024-01-01 00:00:00'))

2)插入数据验证分区是否自动递增。

 有当前分区时,插入成功。

insert into css_ss_channelflow values (1,now(),null,null);
insert into css_ss_channelflow values (2,now(),null,null);
insert into css_ss_channelflow values (3,'2023-12-14 15:34:21' :: timestamp,null,null);
select * from css_ss_channelflow;

当有新分区列的数据插入后,会自动分区,数据插入成功,也可以查询到。

insert into css_ss_channelflow values (4,'2024-01-02 11:52:01' :: timestamp,null,null);
insert into css_ss_channelflow values (5,'2024-03-02 11:52:01' :: timestamp,null,null);

3)查询表结构,发现没有分区信息。

select  pg_catalog.pg_get_tabledef('css_ss_channelflow') ;
SET search_path = wangcxyh;
CREATE TABLE css_ss_channelflow (
    id character varying(32) NOT NULL,
    create_time timestamp without time zone DEFAULT pg_systimestamp() NOT NULL,
    net_check_flag integer,
    ip_flag character varying(20)
)
WITH (orientation=row, compression=no)
PARTITION BY RANGE (create_time)
INTERVAL ('1 month')
( 
    PARTITION ibis_p_flow_04 VALUES LESS THAN (' 2017-04-01 00:00:00') TABLESPACE pg_default,
    PARTITION sys_p24777 VALUES LESS THAN (' 2024-01-01 00:00:00') TABLESPACE pg_default
)
ENABLE ROW MOVEMENT;

4)通过核实系统字典表,该分区确认已经新增,该问题为已知问题。

select * from pg_catalog.pg_partition t where parentid  in (select relfilenode from pg_catalog.pg_class pc where pc.relname  ='css_ss_channelflow');
--查询分区信息,sys_p1、sys_p2为自增分区
relname           |parttype|parentid|rangenum|intervalnum|partstrategy|
------------------|--------|--------|--------|-----------|------------|
css_ss_channelflow|r       |38465545|       0|          0|i           |
ibis_p_flow_04    |p       |38465545|       0|          0|r           |
sys_p24777        |p       |38465545|       0|          0|r           |
sys_p1            |p       |38465545|       0|          0|i           |
sys_p2            |p       |38465545|       0|          0|i           |

2、分布式集群验证分区表自动新增分区

1)创建测试用例的业务表。

CREATE TABLE "wangcxyh"."css_ss_channelflow" (
"id" VARCHAR(32)  NOT NULL,
"create_time" timestamp  NOT NULL DEFAULT CURRENT_TIMESTAMP,
"net_check_flag" INT4  NULL,
"ip_flag" VARCHAR(20)  NULL
) 
 PARTITION BY RANGE("create_time") interval ('1 month')
(
 PARTITION IBIS_P_FLOW_04 VALUES LESS THAN (' 2017-04-01 00:00:00'),
 PARTITION SYS_P24777 VALUES LESS THAN (' 2024-01-01 00:00:00'))
;

添加interval后,在分布式数据库下执行ddl语句。

SQL 错误 [5171] [42P16]: ERROR: Interval partitioned table is only supported in single-node mode.

确实目前分布式集群下仍然不支持分区设置自动新增分区的功能。

2)去掉interval关键字后,再次执行创建表。

CREATE TABLE "wangcxyh"."css_ss_channelflow" (
"id" VARCHAR(32)  NOT NULL,
"create_time" timestamp  NOT NULL DEFAULT CURRENT_TIMESTAMP,
"net_check_flag" INT4  NULL,
"ip_flag" VARCHAR(20)  NULL
) 
 PARTITION BY RANGE("create_time") 
(
 PARTITION IBIS_P_FLOW_04 VALUES LESS THAN (' 2017-04-01 00:00:00'),
 PARTITION SYS_P24777 VALUES LESS THAN (' 2024-01-01 00:00:00'))
;

3)手动新增分区。

alter table css_ss_channelflow   ADD PARTITION csc_202403 VALUES LESS THAN (' 2024-04-01 00:00:00');
--该语句执行

4)插入数据。

--该语句执行成功
insert into css_ss_channelflow values (5,'2024-03-02 11:52:01' :: timestamp,null,null); 

5)对于不存在的分区进行插入数据,提示保存 inserted partition key does not map to any table partition。

insert into css_ss_channelflow values (6,'2024-07-02 11:52:01' :: timestamp,null,null);

三、总结

目前GaussDB对于集中式的分区表兼容还是比较好,但是对于分布式的分区表不支持设置自动新增分区,需要运维人员手动新增分区。由于近年来信创产业缘故,开始接触国产数据库并且从事过国产数据库的安装部署、数据迁移、运维开发,故障处理等。

在工作中使用GuassDB数据库,对于遇到一些案例做了总结及记录,希望能够把经验分享给更多的小伙伴,为国产信创版块贡献绵薄之力。

四、本文作者

本文内容来自于从事数据库运维的墨竹老师,拥有近10年的数据库开发和管理经验,擅长Oracle数据库开发及常规的运维、性能优化等。由于近年来信创产业缘故,开始接触国产数据库并且从事过国产数据库的安装部署、数据迁移、运维开发,故障处理等。目前工作中使用GuassDB数据库,对于遇到一些案例做了总结及记录,希望能够把经验分享给更多的小伙伴,为国产信创版块贡献绵薄之力。

欢迎小伙伴交流~