达梦数据库的堆表概念中与Oracle不同的是在建表过程中可以指定并发分支和非并发分支。那么并发分支和非并发分支是什么呢?我们先从堆表建表语句如何指定并发和非并发属性开始。
堆表带并发分支参数建表样例:
create table "TEST1"."T1"
(
"ID" INT,
"name" VARCHAR(29)
)
storage(initial 1, next 1, minextents 1, fillfactor 0, on "TEST", branch 4)
;
其中在storage部分的branch关键字就是指明该表为堆表且并发分支配置为4个。
在达梦中,堆表的数据保存是无序的。唯一标识一行数据的属性是物理ROWID,物理ROWID是由使用的文件号、页号和页内偏移通过算法获取的唯一值。数据页则是通过链表的形式储存,一个堆表以扁平B树的形式最多可以支持128个数据页链表进行并发写入,这128个数据页链表分为最多64个并发分支和最多64个非并发分支。
这里就要说到关键,什么是并发分支写入机制?
当对于同一个堆表的多个并发事务的写入请求发生时,会依据其事务号随机分配一条链表来对该堆表进行写入操作。上面的样例表中branch值为4,那么允许有4个事务同时通过不同链表对T1表进行写入操作。同时发生的并发写入事务超过4个时,多于4个的事务会在随机的某个链表上产生写入队列,需要等待该链表上的上一个事务写入完成并释放锁后才能通过该链表写入数据。以上过程简要示意图如下:
堆表带并发分支和非并发分支建表样例:
create table "TEST1"."T1"
(
"ID" INT,
"name" VARCHAR(29)
)
storage(initial 1, next 1, minextents 1, fillfactor 0, on "TEST", branch(4,2))
;
其中在storage部分的branch关键字就是指明该表为堆表且并发分支配置为4个,非并发分支为2个。我个人在达梦可查阅资料中没有找到独立设置非并发分支的语法和解释,因此我认为非并发分支是达梦对于堆表高并发写入时,并发分支模式基于并发写入性能提升的一个补充机制。
那么什么是非并发分支呢?
非并发分支写入就是在大量并发事务发生时,事务按分支号从小到大依次选择一个可用的空闲分支来进行数据写入的机制。写入过程中如果所有分支都忙,那么后续事务会按照分支号依次在各分支上进行排队,等前一个事务写入完成并释放锁后,再进行写入操作。以上过程简要示意图如下:
此外,一个堆表配置了并发分支和非并发分支后,其生效我理解是优先走并发分支,当并发分支排队严重时(应该达梦有内容评估机制),新增的并发事务使用非并发机制进行写入。
以上是我个人结合官方文档对于达梦堆表的并发分支和非并发分支的理解,如有谬误,欢迎指正。