有朋友问分区表的计算原理,粗翻一下代码写此文,部分内容可能有误,仅供参考。
1、创建分区表示例:
CREATE TABLE orders (
order_id bigint not null,
cust_id bigint not null,
status text
) PARTITION BY HASH (order_id, cust_id);
2、分区信息系统表 pg_partitioned_table
flying=# select * from pg_partitioned_table; partrelid | partstrat | partnatts | partdefid | partattrs | partclass | partcollation | partexprs
-----------+-----------+-----------+-----------+-----------+-------------+---------------+-----------
24767 | h | 2 | 0 | 1 2 | 10029 10029 | 0 0 |
(1 row)
建表时没有指定 opclass,使用默认操作符类10029:
flying=# select * from pg_opclass where oid=10029;
opcmethod | opcname | opcnamespace | opcowner | opcfamily | opcintype | opcdefault | opckeytype
-----------+----------+--------------+----------+-----------+-----------+------------+------------
405 | int8_ops | 11 | 10 | 1977 | 20 | t | 0
(1 row)
3、操作符类的选择
系统表 pg_opclass
对于哈希分区,访问方法是 HASH_AM_OID(405),其他方式选择BTREE_AM_OID(403),所以上边例子中类型bigint(OID 20)会使用操作符类 10029:
flying=# select oid,* from pg_opclass where opcmethod in (403,405) and opcintype=20;
oid | opcmethod | opcname | opcnamespace | opcowner | opcfamily | opcintype | opcdefault | opckeytype
-------+-----------+----------+--------------+----------+-----------+-----------+------------+------------
3124 | 403 | int8_ops | 11 | 10 | 1976 | 20 | t | 0
10029 | 405 | int8_ops | 11 | 10 | 1977 | 20 | t | 0
(2 rows)
PG允许建表时指定 opclass,要求二进制兼容,更多信息查看文档和代码(src/backend/commands/indexcmds.c中函数ResolveOpClass)注释的说明。
操作符类的选择代码位于 src/backend/commands/tablecmds.c 中的 ComputePartitionAttrs
4、操作符族(operator family)的选择
系统表并没有具体的计算方法(不知道为什么这么做,甚至我也不知道为什么有class和family,文档有详细介绍,看过也没记住。),它是在创建系统缓存(system cache)条目时生成(见src/backend/utils/cache/partcache.c 中的 RelationBuildPartitionKey)。
flying=# select * from pg_amproc where amprocfamily in (1976,1977) and amproclefttype=20 and amprocrighttype=20;
amprocfamily | amproclefttype | amprocrighttype | amprocnum | amproc
--------------+----------------+-----------------+-----------+---------------------
1976 | 20 | 20 | 1 | btint8cmp
1976 | 20 | 20 | 2 | btint8sortsupport
1976 | 20 | 20 | 3 | pg_catalog.in_range
1977 | 20 | 20 | 1 | hashint8
1977 | 20 | 20 | 2 | hashint8extended
(5 rows)
这是 bigint 对应的操作符族,HASH分区时procnum使用HASHEXTENDED_PROC(2),否则使用BTORDER_PROC(1),计算函数分别是 btint8cmp 和 hashint8extended。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




