Oracle表并发插入时位图索引引发死锁的原因咨询
Oracle并发插入时位图索引引发死锁的原因
要搞懂这个问题,得先从位图索引的底层逻辑和插入时的锁机制说起:
位图索引的结构特性
位图索引里,每个唯一键值对应一个独立的位图段。比如某表的gender列有'男'、'女'两个值,索引里就会有两个位图段:一个标记所有'男'的行位置,另一个标记所有'女'的行位置。
插入操作的锁行为
当你插入一行数据时,Oracle需要找到对应键值的位图段,把新行对应的位从0改成1。这个过程中,Oracle会给整个位图段加排他锁——注意,不是锁单行,是锁这个键值对应的所有行的位图标记集合。
死锁的触发场景
死锁不会发生在单一键值的并发插入(比如两个会话都插'男'),这种情况只会出现锁等待:一个会话先拿到'男'的位图锁,另一个等着,等前者提交/回滚后再执行。
真正的死锁出现在多键值交叉插入且锁获取顺序相反的场景:
- 会话A:先插入一条'男'的记录,拿到'男'的位图锁;接着插入一条'女'的记录,需要获取'女'的位图锁。
- 会话B:先插入一条'女'的记录,拿到'女'的位图锁;接着插入一条'男'的记录,需要获取'男'的位图锁。
此时会话A握着'男'的锁等'女'的锁,会话B握着'女'的锁等'男'的锁,双方形成循环等待,Oracle就会触发死锁,终止其中一个会话的操作。
和B树索引的区别
对比常用的B树索引:插入时锁的是对应的索引条目或块,即使是相同键值,不同行的索引条目是独立的(或锁粒度更细),不会出现“一个键值对应一个全局锁”的情况,因此很难出现这种交叉等待的死锁。
内容的提问来源于stack exchange,提问作者Sai Prasanth
相关产品推荐
相关产品推荐

