Berkeley DB 锁子系统的配置

最近小伙伴在分布式数据库(DPINM)环境下做实验,数据集比较大,分到集群中每台机器上,会报lock不够用的错。Berkeley DB在初始化的时候,就会初始化锁子系统,为锁结构分配内存空间,一旦启动,是不可以动态分配的,如果不够用,就会报错。后来调节了参数,加大了Locks,  Lockers, Locked Object 的最大数量,重启之后被惊呆了,锁子系统映射到文件系统的共享内存空间竟然有60多G,磁盘立马就不够用了(挂载目录只有100G….)。以前看到过配置锁子系统的参数该如何算,总结起来就是能大就大,毕竟不够用重启很麻烦,但万万没想到占这么大的空间,所以还是仔细看看怎么配置比较合理的好。

 概念介绍

首先要知道BDB中的Locker, Lock, Lock Object 是什么含义:

  • Locker: 持有锁的对象。如果在支持事务的情况下,就表示事务句柄(DbTxn),如果在不支持事务的情况下,就表示游标或者DB 句柄。
  • Lock:表示锁的数据结构,在数据库中,锁就代表了被锁的对象。因为一般获取一个互斥对象之前要获取锁,如果不能获得,就表示对象被锁住了。
  • Locked Object:真正想要锁住的对象,一般指的是数据库页,在数据库配置成Queue 类型的时候表示一条记录(k-v)。

估算方法

不支持事务的配置相对简单,这里介绍支持事务的 Berkeley DB Transactional Data Store。最推荐的算法是实践,让系统在负载比较极端的情况下运行,然后使用db_stat 命令去查看锁子系统的统计信息,来决定配置的数量,然后把这些数量double,基本上就够用了。但是极端这个情况不好说,所以也提供了自己估算的方法:

1 估算Locker

  • 如果使用了事务特性,Locker 的数量可以估算为系统最大同时打开的非事务游标数,打开的数据库句柄数,还有此时活动的事务数和子事务数之和。对于子事务数的估算应该到子事务的提交,而不是父事务的提交。
  • 如果没有使用事务特性,可以估算为系统最大同时打开的非事务游标数,打开的数据库句柄中非游标操作的数量(数据库句柄可以直接存取数据,也可以使用游标存取,如果不打开游标就计算数据库句柄数,否则计算游标数)。

2 估算Lock Object

  • 每次访问 non-Queue 数据库的时候,每一个数据页(默认8k)需要一个Lock Object
  • 对于Queue 数据库,每一条记录(k-v)都需要一个Lock Object。在删除记录的时候不断使用 DB_NEXT 或者 DB_PREV 获得下一条,上一条记录时,不需要额外进行计算。
  • 对于 Btree 或 Recno 类型的数据库,在更新操作导致树分裂,需要分裂阶段额外的Lock Object。
  • 对于Hash 和 Queue 数据库,每一次访问都需要在 metadata page(元数据页)上加锁,但不会一直持续到事务结束。
  • 如果事务执行了更新操作,导致需要alloc 一个新页,那么需要在 metadata page 上加锁,直到事务结束。

需要注意的是,在事务的生命周期内,总是不断的积累申请到的Lock,但是需要的Lock Object 数量就是这个事务周期内所有操作所需要的数量,也就是说如果对一个数据页(或者Queue的记录),即使多次访问,也只需要一个Lock Object。举个例子:一个事务总共需要访问10调记录,那么就需要10个Lock Object,如果有同时有10个并发的访问线程,就需要配置系统拥有100个Lock Object(因为每个线程都有一个事务)。关于Lock Object 数量多配置一点没关系,因为它的结构占用空间比较小。

3 估算 Lock

Lock的数量不太容易估算,可以使用公式:

Lock = 2 * (Locker) * (Lock Object) * 2

最后乘的2表示对每个object的读写两种加锁模式。这是比较坏的情况下估算出来的值。一般用不到这么多。

 4 锁表分区

对锁表进行分区可以充分利用多核CPU,调用函数 DB_ENV->set_lk_partitions() 完成。每一个分区都可以独立的被一个线程访问,更多的分区意味着更高的并发。默认是在环境启动的时候配置成 cpu 数量的十倍。对于单cpu系统,单个分区反而会比多个分区更有效率。分区之后,最好将Object 和 Lock 分配到各个分区中,便于并发获取。如果其中一个分区用完了Lock 或 Lock Object 资源,会从其它分区中请求,但是频繁的请求会降低效率。

 

参考:

http://docs.oracle.com/cd/E17076_04/html/programmer_reference/lock_max.html

About zhangxiaojian