技术开发 频道

MySQL锁机制 你所不了解的一些事儿

  7.表级table-level锁

  主要源代码见:sql/lock.cc,mysys/thr_lock.cc。mysql_lock/unlock_tables()(SQL层操作)和thr_multi_lock()/thr_lock()(锁兼容逻辑lock-compatibility logic)

  表是以打开着被加锁的。被加锁的对象被句柄关联着;存储引擎会调整锁的类型。如innodb/bdb,事实上大量的对象被加锁的,如merge/partition,见handler::store_lock()方法。

  使用锁等级避免死锁。所有表一次性加锁;如果存储引擎调整锁造成死锁,由存储引擎负责

  在一些情况下,表会更早地被解锁

  8 .预加锁(pre-locking)

  历史上避免死锁方案用于表级table-level数据锁,是要求一次性加锁一个语句内的所有表

  因此,对语句使用的函数/触发,我们不得不打开所有直接地或间接地用到的表,且对它们加锁。为这个,我们建立一个被使用表的可传送闭包

  为了有效实现,我们混合层次和访问(layers and access)成某些解析/语句上下文(parser/statement context),这些上下文来自主要处理表的模板

  9.全局读锁(global read lock)

  实现为FLUSH TABLES WITH READ LOCK,用来备份

  从执行上防止DDL和DML

  劝告:每个DDL/DML语句检查是否有一个正挂着的全局读锁和停止是否有任何一个。通过直接调用wait_if_global_read_lock()(在这个情况我们会设置来自全局读锁的保护,且只有调用start_waiting_global_read_lock()来消除这个保护,通常在这情况下没有打开的表);或者通过mysql_lock_tables()(在后一种情况下,我们还重新打开表)

  线程操作FLUSH TABLES WITH READ LOCK来设置一个全局读锁的标识,初始一个FLUSH TABLES语句。然后等待直到所有的表都清空(flush)

0
相关文章