首页 > MySQL > Mysql的innodb同步管理

Mysql的innodb同步管理

2010年5月2日 admin 发表评论 阅读评论

innodb的同步管理

数据库是支持多客户端同时连接和处理的, 因此多线程是必然的,多线程编码很重要的一个方面是处理同步和互斥,innodb的互斥机制有两个:mutex和rw-lock; 当某个线程需要获取一个mutex或rw-lock时,有两种结果可能发生, 一是直接获得了mutex从而继续处理;一个是无法获得mutex只得等待拥有线程释放mutex. 多线程编码技术中, 是通过信号量来通知等待线程mutex的可用性的, mysql在处理时并没有直接使用操作系统提供的信号量机制, 而是实现了自己的信号量机制,之所以不用操作系统的信号量机制而自己实现的主要原因是操作系统的信号量机制比较慢,其次一个原因是(某些)操作系统的信号量处理往往导致线程切换,而在很多时候, 有比不做线程切换更高效的事情:在多处理器系统上,通过循环等待旋转锁(spin lock), 当然, 在只有单处理器的系统上,循环等待明显是低效的事情。再一个原因是, 便于分析同步情况, 从而避免死锁, 因为当所有的同步信息交给操作系统处理时, 就难以分析死锁情况了,如果有自己的数据结构来管理这些信息, 死锁情况就容易分析。

在Innodb内部, 信号量机制是通过一个叫做等待数组的东西来管理的, 这个数组全局唯一的, 而且同时支持innodb内部两种主要的互斥工具mutex和rw-lock; 数组中的每个数组元素都与一个互斥锁或者rw-lock关联, 和一个事件对象关联; 当一个线程需要等待某一个互斥对象的时候而又无法得到时, 先预定一个元素, 然后把自己挂在这个元素关联的事件上, 直到这个事件被通知。当通过使用等待数组来控制同步时 ,拥有同步对象的线程可以知道哪些线程正待等待, 从而在条件合适的时候发出通知,到达避免死锁的母的。

innodb在互斥资源(mutex或rw-lock)获取管理机制上, 是通过一个多阶段等待机制来等待的;首先, 线程通过循环等待旋转锁来等待(即循环检查mutex是否可用, 当然每次检查是有时间间隔的,通过变量srv_spin_wait_delay控制),如果在设定的循环次数(innodb_sync_spin_loops配置变量控制)内无法得到资源,线程将会通过等待数组机制来等待:从等待数组中获取一个元素, 并把自己挂在相应的信号量上。当持有mutex的线程释放它的时候, 系统会通知等待在与这个mutex绑定的事件上的所有线程。

通过旋转锁等待机制,可以一定程度上减少线程上下文切换,但是会浪费一些cup, 对于数据库来说, 尤其是在多cup系统上,主要瓶颈在于io而不是cpu, 这种旋转锁机制的总体效率是不错的。

在show innodb status的SEMAPHORES那里看到得一些信息来印证一下innodb同步系统:

OS WAIT ARRAY INFO: reservation count 28772, signal count 28374

系统中的等待数组中有28772个元素被预定了 ,有28374过有过信号量的通知

Mutex spin waits 0, rounds 794773, OS waits 9689

在获取mutex上, 总共有0次旋转锁检验, 由于这个值只有在debug模式才有, 这里为0; 在获取mutex上, 总共上做了794773次旋转锁校验, 有9689次等待在等待数组管理的信号量上

RW-shared spins 18042, OS waits 6444; RW-excl spins 24877, OS waits 11086

在获取s-lock上,总共上做了18042轮旋转锁校验, 6444次等待在等待数组管理的信号量上;在获取x-lock上,总共上做了24877轮旋转锁校验, 11086次等待在等待数组管理的信号量上

相关日志

分类: MySQL 标签: , ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
Easy AdSense by Unreal