分区表锁粒度差异 - pg_pathman VS native partition table

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
PolarDB Agent Express,2核4GB
RDS AI 助手,专业版
简介:

标签

PostgreSQL , 锁 , 粒度 , pg_pathman , 内置分区


背景

PostgreSQL 内置分区相比pg_pathman分区插件性能要差一大截:

《PostgreSQL 10 内置分区 vs pg_pathman perf profiling》

主要原因:

1、与优化器有关,内置分区表,plan\bind时需要分析所有子表,所以子表越多,性能会越差。例如下面这个CASE就是分区过多引起的性能问题。

《PostgreSQL 查询涉及分区表过多导致的性能问题 - 性能诊断与优化(大量BIND, spin lock, SLEEP进程)》

PPAS 10和pg_pathman插件都没有这个问题。

我们也可以通过这个profiling来对比 pg_pathman和内置分区的性能差异。

《PostgreSQL 10 内置分区 vs pg_pathman perf profiling》

除了性能差异,实际上还有一个问题是锁的差异。

分区表锁粒度差异 - pg_pathman VS native partition table

观察锁

1、pg_pathman,仅锁目标分区。对非目标分区执行DDL,不需要等待。

create table tbl_range(id int not null, info text, crt_time timestamp);      
select create_range_partitions('tbl_range', 'id', 0, 100, 128);     
  
begin;  
insert into tbl_range values (1, 'test', now()) returning tableoid::regclass,*;  
  
  tableoid   | id | info |          crt_time            
-------------+----+------+----------------------------  
 tbl_range_1 |  1 | test | 2018-02-06 20:15:23.305754  
(1 row)  
  
INSERT 0 1  
postgres=# select relation::regclass,* from pg_locks ;  
  relation   |   locktype    | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction |  pid  |       mode       | granted | fastpath   
-------------+---------------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-------+------------------+---------+----------  
 pg_locks    | relation      |    20699 |    11577 |      |       |            |               |         |       |          | 4/18               | 41234 | AccessShareLock  | t       | t  
             | virtualxid    |          |          |      |       | 4/18       |               |         |       |          | 4/18               | 41234 | ExclusiveLock    | t       | t  
 tbl_range_1 | relation      |    20699 |    44464 |      |       |            |               |         |       |          | 3/8819             | 41174 | RowExclusiveLock | t       | t  
 tbl_range   | relation      |    20699 |    44456 |      |       |            |               |         |       |          | 3/8819             | 41174 | RowExclusiveLock | t       | t  
             | virtualxid    |          |          |      |       | 3/8819     |               |         |       |          | 3/8819             | 41174 | ExclusiveLock    | t       | t  
             | transactionid |          |          |      |       |            |     227217433 |         |       |          | 3/8819             | 41174 | ExclusiveLock    | t       | f  
(6 rows)  

2、native partition table,锁所有分区。导致对任意分区执行DDL都需要等待。

CREATE TABLE orders (      
    order_id     bigint not null,      
    cust_id      bigint not null,      
    status       text      
) PARTITION BY HASH (order_id);      
CREATE TABLE orders_p1 PARTITION OF orders      
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);      
CREATE TABLE orders_p2 PARTITION OF orders      
    FOR VALUES WITH (MODULUS 4, REMAINDER 1);      
CREATE TABLE orders_p3 PARTITION OF orders      
    FOR VALUES WITH (MODULUS 4, REMAINDER 2);      
CREATE TABLE orders_p4 PARTITION OF orders      
    FOR VALUES WITH (MODULUS 4, REMAINDER 3);         
begin;  
insert into orders values (1, 1, 'test') returning tableoid::regclass,*;  
  
 tableoid  | order_id | cust_id | status   
-----------+----------+---------+--------  
 orders_p1 |        1 |       1 | test  
(1 row)  
  
INSERT 0 1  
postgres=# select relation::regclass,* from pg_locks ;  
    relation    |   locktype    | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction |  pid  |           mode           | granted | fastpath   
----------------+---------------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-------+--------------------------+---------+----------  
 orders_p4      | relation      |    16461 | 75121104 |      |       |            |               |         |       |          | 3/57883            | 41256 | RowExclusiveLock         | t       | t  
 orders_p3      | relation      |    16461 | 75121098 |      |       |            |               |         |       |          | 3/57883            | 41256 | RowExclusiveLock         | t       | t  
 orders_p2      | relation      |    16461 | 75121092 |      |       |            |               |         |       |          | 3/57883            | 41256 | RowExclusiveLock         | t       | t  
 orders_p1      | relation      |    16461 | 75121086 |      |       |            |               |         |       |          | 3/57883            | 41256 | RowExclusiveLock         | t       | t  
 orders         | relation      |    16461 | 75121080 |      |       |            |               |         |       |          | 3/57883            | 41256 | AccessShareLock          | t       | t  
 orders         | relation      |    16461 | 75121080 |      |       |            |               |         |       |          | 3/57883            | 41256 | RowExclusiveLock         | t       | t  
                | virtualxid    |          |          |      |       | 3/57883    |               |         |       |          | 3/57883            | 41256 | ExclusiveLock            | t       | t  
 pg_locks       | relation      |    16461 |    11621 |      |       |            |               |         |       |          | 4/58165            | 41325 | AccessShareLock          | t       | t  
                | virtualxid    |          |          |      |       | 4/58165    |               |         |       |          | 4/58165            | 41325 | ExclusiveLock            | t       | t  

维护子表

在对主表有查询、插入时,维护子表,看看子表的反应。

insert into 主表 values (1,xxx);  -- 写入A子表  

1、TRUNCATE 非A子表

内置分区,锁冲突。

pg_pathman,无冲突。

2、detach 非A子表

内置分区,锁冲突。

pg_pathman,无冲突。

小结

内置分区表,只要操作主表,就需要对所有子表加锁(加相应的锁,例如sharedLock).

pg_pathman,仅仅对主表,以及被访问调度子表加锁。

因此,当我们需要使用DDL来维护子表时(例如truncate, attach, detach子表),使用pg_pathman不会与操作主表的SQL冲突,而使用内置分区的话,读主表由于锁所有子表,所以与子表DDL操作会发生冲突。需要特别注意。

参考

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

《PostgreSQL 10 内置分区 vs pg_pathman perf profiling》

《PostgreSQL 商用版本EPAS(阿里云ppas) - 分区表性能优化 (堪比pg_pathman)》

《PostgreSQL 查询涉及分区表过多导致的性能问题 - 性能诊断与优化(大量BIND, spin lock, SLEEP进程)》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
编解码 监控 数据可视化
一文带你快速设计精美可视化大屏
可视化大屏👉数据可视化大屏是将一些业务的关键指标通过数据可视化的方式展示到一块或多块LED大屏上,以大屏为主要展示载体的数据可视化设计。数据可视化大屏可以用于信息展示、数据分析、监控预警等多种场景,帮助用户快速了解数据的价值和意义。可视化大屏的优点1️⃣操作灵活:数据可视化大屏可以支持智能化布局和组件的自由排版,可以根据不同的需求和场景进行个性化的设计和展示。2️⃣信息展示更加全面。
一文带你快速设计精美可视化大屏
|
数据库 UED Python
1、基于python多进程+pyqt5开发流畅界面程序
使用python+pyqt5开发界面程序,利用多进程分离界面和任务执行功能,达到界面流畅不卡顿的要求。 本文程序示例:https://github.com/AlvinsFish/UiExample
2940 0
1、基于python多进程+pyqt5开发流畅界面程序
|
5月前
|
人工智能 自然语言处理 关系型数据库
Pipeline AI Agent - 让数据管道听懂人话
TIS v5.0推出国内首个大数据原生Pipeline AI Agent,通过自然语言对话实现数据管道智能创建。告别繁琐配置,AI自动完成插件选择、参数填充与任务执行,支持MySQL、Paimon等主流数据源,结合SSE实时推送与Plan-and-Execute架构,3分钟极速构建同步链路,大幅降低使用门槛,开启数据集成“对话时代”。
554 1
|
2月前
|
Python Windows
Python 3.9.0安装教程 Windows版:详细步骤+安装路径修改+桌面快捷方式创建指南
Python是语法简洁、可读性强的面向对象编程语言。本文详解Python 3.9.0离线安装全流程:下载压缩包→解压→以管理员身份运行安装程序→勾选PATH和全局安装→自定义路径→创建IDLE快捷方式→验证成功。
|
JSON Unix Linux
Elasticsearch如何安装
Elasticsearch如何安装
|
人工智能 自然语言处理 算法
如何学习AIGC
【1月更文挑战第21天】如何学习AIGC
977 1
如何学习AIGC
|
机器学习/深度学习 人工智能 自然语言处理
基于星海智算云平台部署 DeepSeek-R1系列 70b 模型全攻略(附平台福利)
本文介绍了如何在星海智算云平台上部署DeepSeek-R1系列70B模型,解决官网访问不畅的问题。通过云端部署,用户可以按需付费,避免本地部署高昂成本(高达两百多万)。文章详细讲解了从实例创建到开始使用DeepSeek的八个步骤,并提供了成本优化技巧和新手注意事项。推荐使用双A100显卡,每小时费用仅13.32元。新用户还可领取福利,享受高性价比服务。立即注册体验:[星海智算云平台](https://gpu.spacehpc.com/user/register?inviteCode=52872508)。
1240 1
基于星海智算云平台部署 DeepSeek-R1系列 70b 模型全攻略(附平台福利)
|
人工智能 自然语言处理 Linux
5分钟Deepseek R1本地化部署
DeepSeek R1 是一款基于Transformer架构的先进大语言模型,以其强大的自然语言处理能力和高效的推理速度著称。本文介绍如何通过开源框架Ollama在本地快速部署DeepSeek R1。Ollama简化了大型语言模型的部署过程,支持多种操作系统和模型格式,提供便捷的安装、启动及API接口,使得研究人员和开发者能轻松运行和定制模型。通过简单的命令行操作和HTTP API,用户可以在本地环境中高效利用DeepSeek R1的强大功能。
1235 5