作家
登录

MySQL引擎特性:InnoDB同步机制

作者: 来源: 2017-12-15 11:37:56 阅读 我要评论

基于以上几点,InnoDB基于体系的前提变量和体系互斥锁本身实现了一套前提通知机制。重要在文件os0sync.cc中实现,相干数据构造以及接口进一层的包装在头文件os0sync.h中。应用办法如下:

InnoDB前提变量核心数据构造为os_event_t,类似pthread_cont_t。如不雅须要创建和烧毁则分别应用os_event_create和os_event_free函数。须要等待某个前提变量,先调用os_event_reset(原因见下一段),然后应用os_event_wait,如不雅须要超时等待,应用os_event_wait_time调换os_event_wait即可,os_event_wait_XXX这两个函数,解决了弊病1和弊病2,此外,建议把os_event_reset返回值传给他们,如许能防止多线程情况下的无穷等待(详见下下段)。如不雅须要发出一个前提通知,应用os_event_set。这个几个函数,琅绫擎都插入了一些监控信息,便利InnoDB上层治理。怎么样,便利多了吧~

多线程情况下可能产生的问题

总结一下, InnoDB前提变量能便利InnoDB上层做监控,也简化了前提变量应用的办法,然则调用者上层逻辑必须包管前提通知不克不及过早的发出,不然就会有无穷等待的可能。

互斥锁

互斥锁包管一段法度榜样同时只能一个线查拜访,包管临界区获得精确的序列化拜访。同前提变量一样,InnoDB对Pthread的mutex简单包装了一下,供给给其他模块用(主如果帮助其他本身实现的数据构造,不消InnoDB本身的互斥锁是为了防止递归引用,详见帮助构造这一节)。但与前提变量不合的是,InnoDB本身实现的一套互斥锁并没有依附Pthread库,而是依附上述的原子操作(如不雅平台不支撑原子操作则应用Pthread库,然则这种情况不太会产生,因为gcc在4.1就支撑原子操作了)和上述的InnoDB前提变量。

体系互斥锁

比拟与体系前提变量,体系互斥锁除了包装Pthread库外,还做了一层简单的监控统计,构造名为os_mutex_t。在文件os0sync.cc中,os_mutex_create创建mutex,并调用os_fast_mutex_init_func创建pthread的mutex,值得一提的是,创建pthread mutex的参数是my_fast_mutexattr的器械,其在MySQL server层函数my_thread_global_init初始化 ,只要pthread库支撑,则默认成初始化为PTHREAD_MUTEX_ADAPTIVE_NP和PTHREAD_MUTEX_ERRORCHECK。前者表示,当锁释放,之前在等待的锁进行公平的竞争,而不是按照默认的优先级模式。后者表示,如不雅产生了递归的加锁,即同一个线程对同一个锁持续加锁两次,第二次加锁会报错。别的三个有效的函数为,烧毁锁os_mutex_free,加锁os_mutex_enter,解锁os_mutex_exit。

一般来说,InnoDB上层模块不须要直接与体系互斥锁打交道,须要用锁的时刻一般用InnoDB本身实现的一套互斥锁。体系互斥锁主如果用来帮助实现一些数据构造,例如最后一节提到的一些帮助构造,因为这些帮助构造可能本身就要供给给InnoDB自旋互斥锁用,为了防止递归引用,就临时用体系互斥锁来代替。

InnoDB自旋互斥锁

InnoDB自旋互斥锁的实现重要在文件sync0sync.cc和sync0sync.ic中,头文件sync0sync.h定义了核心数据构造ib_mutex_t。应用办法很简单,mutex_create创建锁,mutex_free释放锁,mutex_enter测验测验获得锁,如不雅已经被占用了,则等待。mutex_exit释放锁,同时唤醒所有等待的线程,拿到锁的线程开端履行,其余线程持续等待。mutex_enter_nowait这个函数类似pthread的trylock,只要已检测到锁不消,就直接返回缺点,一向行自旋等待。总体来说,InnoDB自旋互斥锁的用法和语义跟体系互斥锁一模一样,然则底层实现却大年夜相径庭。

在ib_mutex_t这个核心数据构造中,最重要的是前面两个变量:event和lock_word。lock_word为0表示锁余暇,1表示锁被占用,InnoDB自旋互斥锁应用__sync_lock_test_and_set这个函数对lock_word进行原子操作,加锁的时刻,测验测验把其设置为1,函数返回值不指导是否成功,指导的是测验测验设置之前的值,是以如不雅返回值是0,表示加锁成功,返回是1表示掉败。如不雅加锁掉败,则会自旋一段时光,然后等待在前提变量event(os_event_wait)上,当锁占用者释放锁的时刻,会应用os_event_set来唤醒所有的等待者。简单的来说,byte类型的lock_word基于平台供给的原子操作来实现互斥拜访,而event是InnoDB前提变量类型,用来实现锁释放后唤醒等待线程的操作。

mutex_enter的伪代码如下:

自旋锁 :传统的互斥锁,只要一检测到锁被其他线程所占用了,就急速放弃cpu时光片,把cpu留给其他线程,这就会产生一次高低文切换。当体系压力大年夜的时刻,频繁的高低文切换会导致sys值过高。自旋锁,在检测到锁弗采取的时刻,起首cpu忙等一小会儿,如不雅照样发明弗采取,再放弃cpu,进行切换。互斥锁消费cpu sys值,自旋锁消费cpu usr值。

  1. if (__sync_lock_test_and_set(mutex->lock_word, 1) == 0) { 
  2.  
  3.     get mutex successfully; 
  4.  
  5.     return
  6.  
  7.  
  8. loop1: 
  9.  
  10.     i = 0; 
  11.  
  12. loop2: 
  13.  
  14.     /*指导点1*/ 
  15.  
  16.     while (mutex->lock_word ! = 0 && i < SPIN_ROUNDS) { 

      推荐阅读

      海尔王养浩:让IT成为业务和创新的赋能者

    数字化转型已成为趋势,然而既然是转型则必定会带来阵痛,新技巧在带来新的颠覆的同时,也给IT运维治理带来新的挑衅,包含稳定性、扩大性、灵活性、成本、投资回报率等等。对于IT治理者而言,若何经由过程大年夜数据>>>详细阅读


    本文标题:MySQL引擎特性:InnoDB同步机制

    地址:http://www.17bianji.com/lsqh/39799.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)