Berkeley DB的锁占用困惑?
作者:熊蛙
链接:https://www.zhihu.com/question/22522986/answer/23672417
这个问题是典型的防止写线程(或进程)被读共享锁霸占导致饿死的问题。主流数据库都有对应的策略,一般情况下不会出现写操作饿死,不需要额外的干预。
链接:https://www.zhihu.com/question/22522986/answer/23672417
Berkeley DB的锁是基于数据页(Page)为单位的,允许多个事务并发执行。在数据库外人为增加的队列、文件锁等行为,相当于加了一把全局锁,对数据库的并发性能有影响。一般情况下不建议这样做。
此外,对于并发读写数据库,还需要充分考虑和避免死锁情况。参考:
http://docs.oracle.com/cd/E17076_03/html/gsg_txn/C/blocking_deadlocks.html#deadlocks以下是对Berkeley DB锁系统防止写请求饿死的简要原理描述,实际实现涉及到很多细致的优化实现,会比原理描述复杂。
==================
数据库系统的性能至关重要,为了减轻锁粒度、提高并发性能,其内部锁系统设计相当复杂精巧。以Berkeley DB为例,锁系统中包括锁(Lock)、锁持有者(Locker)和被锁对象(Object)。可简单地认为锁持有者对应于读写事务,被锁对象对应于数据页。
Berkeley DB设计文档(src/lock/Design)指明:内部锁系统,对于被锁对象(Object),维护着holders和waiters两个链表。
OBJECT -----------------------
HASH | |
----|------------- |
________ _______ | | ________ | |
| |-->| O1 |--|---|-->| O2 | | |
|_______| |_____| | | |______| V |
| | W H--->L1->L2 W H--->L5 | holders
|_______| | | | | V
| | ------->L3 \ ------->L6------>L7 waiters
|_______| / \ \
. . / \ \
. . | \ \
. . | \ -----------
|_______| | -------------- |
| | ____|____ ___|_____ _|______
|_______| | | | | | |
| | | LID1 | | LID2 | | LID3 |
|_______| |_______| |_______| |______|
^ ^ ^
| | |
___|________________________|________|___
LOCKER | | | | | | | | |
HASH | | | | | | | | |
| | | | | | | | |
|____|____|____|____|____|____|____|____|
相关文章