A.INSERT
插入操作在函数btr_cur_optimistic_insert->btr_cur_ins_lock_and_undo->lock_rec_insert_check_and_lock这里进行锁的判断,我们简单的看看这个函数的流程:
1.首先先看看欲插入记录之后的数据上有没有锁,
? ?next_rec = page_rec_get_next_const(rec);
? ?next_rec_heap_no = page_rec_get_heap_no(next_rec);
? ?lock = lock_rec_get_first(block, next_rec_heap_no);
如果lock为空的话,对于非聚集索引,还需要更新page上的最大事务ID。
实际上这里是比较松散的检查,大并发插入的时候,可以大大的降低创建锁开销。
那么其他事务如何发现这些新插入的记录呢(重复插入同一条记录显然应该被阻塞),这里会有个判断,其他事务去看看
新插入记录的事务是否还是活跃的,如果还是活跃的,那么就为这个事务主动增加一个锁记录(所谓的隐式锁就是么有锁。。。。),这个判断是在检查是否存在冲突键的时候进行的(row_ins_duplicate_error_in_clust->row_ins_set_shared_rec_lock->lock_clust_rec_read_check_and_lock->lock_rec_convert_impl_to_expl
row_ins_set_shared_rec_lock的目的是为了向记录上加一个LOCK_REC_NOT_GAP的LOCK_S锁,也就是非GAP的记录S锁,如果发现记录上有X锁(隐式锁转换为LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP),显然是需要等待的(返回DB_LOCK_WAIT)