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

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

标签

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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
关系型数据库 数据库 PostgreSQL
PostgreSQL分区表(Table Partitioning)应用
一、简介   在数据库日渐庞大的今天,为了方便对数据库数据的管理,比如按时间,按地区去统计一些数据时,基数过于庞大,多有不便。
1592 0
|
SQL 算法 关系型数据库
PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
2457 0
|
SQL 分布式计算 并行计算
PostgreSQL 并行计算解说 之25 - parallel FDW scan (并行访问多个外部表) with parallel append (FDW must with IsForeignScanParallelSafe)
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan
287 0
|
SQL 人工智能 分布式计算
PostgreSQL 并行计算解说 之20 - parallel partition table wise join
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan
399 0
|
SQL 分布式计算 并行计算
PostgreSQL 并行计算解说 之28 - parallel CREATE INDEX CONCURRENTLY - 不堵塞读写
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan parallel index scan parall
316 0
|
SQL 分布式计算 并行计算
PostgreSQL 并行计算解说 之5 - parallel create table as
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan parallel index scan
1053 0
|
SQL 分布式计算 并行计算
PostgreSQL 并行计算解说 之21 - parallel partition table wise agg
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan
256 0
|
关系型数据库 PostgreSQL 机器学习/深度学习
PostgreSQL 12: 新增 pg_partition_tree() 函数显示分区表信息
PostgreSQL 12 新增三个分区查询函数,如下: pg_partition_tree(regclass): 返回分区表详细信息,例如分区名称、上一级分区名称、是否叶子结点、层级,层级 0 表示顶层父表。
6137 0