PostgreSQL 自动创建分区实践 - 写入触发器

本文涉及的产品
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介:

标签

PostgreSQL , 自动创建分区 , 触发器 , 写入 , 动态创建分区


背景

数据写入时,自动创建分区。

目前pg_pathman这个分区插件,有这个功能,如果你不是用的这个插件,可以考虑一下用触发器写入,并在触发器中实现自动创建分区。

《PostgreSQL 9.6 sharding based on FDW & pg_pathman》

《PostgreSQL 9.5+ 高效分区表实现 - pg_pathman》

例子

1、创建主表,索引

create table test(id int, info text, crt_time timestamp not null );  
create index idx_test_1 on test(id);  
create index idx_test_2 on test(crt_time);  

2、创建写入触发器,在触发器内,根据错误判断是否需要建表

长连接,使用绑定变量来写入,性能比动态SQL更好。

create or replace function ins_tg() returns trigger as $$  
declare  
  -- 分区后缀  
  suffix text := to_char(NEW.crt_time,'yyyymmdd');  
begin  
  -- 乐观实现,执行绑定变量  
  execute format('execute p%s(%s, %L, %L)', suffix, NEW.id, NEW.info, NEW.crt_time);  
  return null;  
  exception   
    when others then  
      -- 自动建分区, 有必要的话,你可以把分区表的分区键约束也在这个QUERY中添加一下。  
      execute format('create table IF NOT EXISTS test_%s (like test) inherits(test)', suffix);  
      -- 建绑定变量  
      execute format('prepare p%s (int,text,timestamp) as insert into test_%s values($1,$2,$3)', suffix, suffix);  
      -- 执行绑定变量  
      execute format('execute p%s (%s, %L, %L)', suffix, NEW.id, NEW.info, NEW.crt_time);  
      return null;  
end;  
$$ language plpgsql strict;  

如果是短连接,则没有必要使用prepare。那么触发器函数如下:

create or replace function ins_tg() returns trigger as $$  
declare  
  -- 分区后缀  
  suffix text := to_char(NEW.crt_time,'yyyymmdd');  
begin  
  -- 乐观实现,执行动态SQL  
  execute format('insert into test_%s select $1.*', suffix) using NEW;  
  return null;  
  exception   
    when others then  
      -- 自动建分区, 有必要的话,你可以把分区表的分区键约束也在这个QUERY中添加一下。  
      execute format('create table IF NOT EXISTS test_%s (like test) inherits(test)', suffix);  
      -- 执行动态SQL  
      execute format('insert into test_%s select $1.*', suffix) using NEW;  
      return null;  
end;  
$$ language plpgsql strict;  

3、在主表上创建触发器

create trigger tg before insert on test for each row execute procedure ins_tg();  

4、创建一个函数,获取随机时间

create or replace function get_rand_ts() returns timestamp as $$  
  select now()::timestamp  +  ((1000*random())::int::text||' days')::interval;            
$$ language sql strict;  

5、插入测试

vi test.sql  
  
insert into test values (1,'test',get_rand_ts());  

6、压测

pgbench -M prepared -n -r -P 1 -f ./test.sql -c 64 -j 64 -T 120  

可以达到22万行/s的写入.

progress: 113.0 s, 221725.4 tps, lat 0.289 ms stddev 0.131  
progress: 114.0 s, 222356.0 tps, lat 0.288 ms stddev 0.129  
progress: 115.0 s, 222023.3 tps, lat 0.288 ms stddev 0.129  
progress: 116.0 s, 221254.7 tps, lat 0.289 ms stddev 0.135  
progress: 117.0 s, 222377.2 tps, lat 0.288 ms stddev 0.128  
progress: 118.0 s, 221593.5 tps, lat 0.289 ms stddev 0.134  
progress: 119.0 s, 221716.1 tps, lat 0.289 ms stddev 0.131  
progress: 120.0 s, 221839.3 tps, lat 0.289 ms stddev 0.134  
.....  

7、测试数据分布均匀

 public | test             | table | postgres | 8192 bytes |   
 public | test_20180507    | table | postgres | 1920 kB    |   
 public | test_20180508    | table | postgres | 2064 kB    |   
 public | test_20180509    | table | postgres | 1816 kB    |   
 public | test_20180510    | table | postgres | 1824 kB    |   
 public | test_20180511    | table | postgres | 1800 kB    |   
 public | test_20180512    | table | postgres | 1808 kB    |   
 public | test_20180513    | table | postgres | 1736 kB    |   
 public | test_20180514    | table | postgres | 1784 kB    |   
 public | test_20180515    | table | postgres | 1872 kB    |   
 public | test_20180516    | table | postgres | 1912 kB    |   
 public | test_20180517    | table | postgres | 1584 kB    |   
 public | test_20180518    | table | postgres | 1800 kB    |   
 public | test_20180519    | table | postgres | 1912 kB    |   
 public | test_20180520    | table | postgres | 1768 kB    |   
 public | test_20180521    | table | postgres | 1720 kB    |   
 public | test_20180522    | table | postgres | 1808 kB    |   
 public | test_20180523    | table | postgres | 2056 kB    |   
 public | test_20180524    | table | postgres | 1824 kB    |   
 ..................  

其他动态分区写法

例如取模,按周,按某个自定义周期等。参考时间函数:

https://www.postgresql.org/docs/10/static/functions-datetime.html

isodow  
  
The day of the week as Monday (1) to Sunday (7)  
  
SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');  
  
Result: 7  
  
This is identical to dow except for Sunday. This matches the ISO 8601 day of the week numbering.  

其他例子

epochDay := floor(floor(extract(epoch from strSQL::timestamp)/86400)/period);  

参考

《PostgreSQL Oracle 兼容性之 - DBMS_SQL(存储过程动态SQL中使用绑定变量)》

《PostgreSQL rotate table 自动清理调度 - 约束,触发器》

《PostgreSQL 9.6 sharding based on FDW & pg_pathman》

《PostgreSQL 9.5+ 高效分区表实现 - pg_pathman》

《PostgreSQL 触发器 用法详解 2》

《PostgreSQL 触发器 用法详解 1》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
8月前
|
监控 物联网 关系型数据库
使用PostgreSQL触发器解决物联网设备状态同步问题
在物联网监控系统中,确保设备状态(如在线与离线)的实时性和准确性至关重要。当设备状态因外部因素改变时,需迅速反映到系统内部。因设备状态数据分布在不同表中,直接通过应用同步可能引入复杂性和错误。采用PostgreSQL触发器自动同步状态变化是一种高效方法。首先定义触发函数,在设备状态改变时更新管理模块表;然后创建触发器,在状态字段更新后执行此函数。此外,还需进行充分测试、监控性能并实施优化,以及在触发函数中加入错误处理和日志记录功能。这种方法不仅提高自动化程度,增强数据一致性与实时性,还需注意其对性能的影响并采取优化措施。
215 2
|
关系型数据库 数据管理 Go
《PostgreSQL数据分区:原理与实战》
《PostgreSQL数据分区:原理与实战》
263 0
|
10月前
|
自然语言处理 关系型数据库 数据库
技术经验解读:【转】PostgreSQL的FTI(TSearch)与中文全文索引的实践
技术经验解读:【转】PostgreSQL的FTI(TSearch)与中文全文索引的实践
137 0
|
11月前
|
SQL 运维 关系型数据库
基于AnalyticDB PostgreSQL的实时物化视图研发实践
AnalyticDB PostgreSQL版提供了实时物化视图功能,相较于普通(非实时)物化视图,实时物化视图无需手动调用刷新命令,即可实现数据更新时自动同步刷新物化视图。当基表发生变化时,构建在基表上的实时物化视图将会自动更新。AnalyticDB PostgreSQL企业数据智能平台是构建数据智能的全流程平台,提供可视化实时任务开发 + 实时数据洞察,让您轻松平移离线任务,使用SQL和简单配置即可完成整个实时数仓的搭建。
144062 8
|
11月前
|
弹性计算 关系型数据库 数据库
开源PostgreSQL在倚天ECS上的最佳优化实践
本文基于倚天ECS硬件平台,以自顶向下的方式从上层应用、到基础软件,再到底层芯片硬件,通过应用与芯片的硬件特性的亲和性分析,实现PostgreSQL与倚天芯片软硬协同的深度优化,充分使能倚天硬件性能,帮助开源PostgreSQL应用实现性能提升。
|
11月前
|
SQL 关系型数据库 MySQL
MySQL【实践 02】MySQL迁移到PostgreSQL数据库的语法调整说明及脚本分享(通过bat命令修改mapper文件内的SQL语法)
MySQL【实践 02】MySQL迁移到PostgreSQL数据库的语法调整说明及脚本分享(通过bat命令修改mapper文件内的SQL语法)
366 0
|
关系型数据库 测试技术 分布式数据库
PolarDB | PostgreSQL 高并发队列处理业务的数据库性能优化实践
在电商业务中可能涉及这样的场景, 由于有上下游关系的存在, 1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方, 2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列, 3、然后后台再从缓存取出订单并进行处理. 如果是高并发的处理, 因为大家都按一个顺序获取, 容易产生热点, 可能遇到取出队列遇到锁冲突瓶颈、IO扫描浪费、CPU计算浪费的瓶颈. 以及在清除已处理订单后, 索引版本未及时清理导致的回表版本判断带来的IO浪费和CPU运算浪费瓶颈等. 本文将给出“队列处理业务的数据库性能优化”优化方法和demo演示. 性能提升10到20倍.
946 4
|
存储 对象存储 块存储
|
SQL 存储 DataWorks
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版解析与实践(上)——一、产品概述
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版解析与实践(上)——一、产品概述
|
SQL 存储 Cloud Native
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版解析与实践(上)——二、产品架构及原理
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版解析与实践(上)——二、产品架构及原理

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版