作家
登录

MySQL引擎特性:InnoDB同步机制

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

接下来,我们来具体介绍一下lock_word的变更规矩:

1. 当有一个读请求加锁成功时,lock_word原子递减1。

3. 如不雅读写锁支撑递归写,那么第一个递归写锁加锁成功时,lock_word依然原子递减X_LOCK_DECR,而后续的递归写锁加锁成功是,lock_word只是原子递减1。

在上述的变更规矩束缚下,lock_word会形成以下几个区间:

  • lock_word == X_LOCK_DECR: 表示锁余暇,即当前没有线程获得了这个锁。
  • 0 < lock_word < X_LOCK_DECR: 表示当前有X_LOCK_DECR – lock_word个读锁
  • lock_word == 0: 表示当前有一个写锁
  • -X_LOCK_DECR < lock_word < 0: 表示当前有-lock_word个读锁,他们还没完成,同时后面还有一个写锁在等待
  • lock_word <= -X_LOCK_DECR: 表示当前处于递归锁模式,同一个线程加了2 – (lock_word + X_LOCK_DECR)次写锁。

别的,还可以得出以下结论

1. 因为lock_word典范围被限制(rw_lock_validate)在(-2X_LOCK_DECR, X_LOCK_DECR]中,结合上述规矩,可以揣摸出,一个读写锁最多能加X_LOCK_DECR个读锁。在开启递归写锁的模式下,一个线程最多同时加X_LOCK_DECR+1个写锁。

2. 在读锁释放之前,lock_word必定处于(-X_LOCK_DECR, 0)U(0, X_LOCK_DECR)这个范围内。

3. 在写锁释放之前,lock_word必定处于(-2*X_LOCK_DECR, -X_LOCK_DECR]或者等于0这个范围内。

4. 只有在lock_word大年夜于0的情况下才可以对它递减。有一个例外,就是同一个线程须要加递归写锁的时刻,lock_word可以在小于0的情况下递减。

接下来,举个读写锁加锁的例子,便利读者懂得读写锁底层加锁的道理。假设有读写加锁请求按照以下次序依次达到:R1->R2->W1->R3->W2->W3->R4,个中W2和W3是属于同一个线程的写加锁请求,其他所有读写请求均来自不合线程。初始化后,lock_word的值为X_LOCK_DECR(十进制值为1048576)。R1读加锁请求起首到,其发明lock_word大年夜于0,表示可以加读锁,同时lock_word递减1,结不雅为1048575,R2读加锁请求接着来到,发明lock_word依然大年夜于0,持续加读锁并递减lock_word,最终结不雅为1048574。留意,如不雅R1和R2几乎是同时达到,即使时序上是R1先请求,然则并不包管R1起首递减,有可能是R2起首拿到原子操作的履行权限。如不雅在R1或者R2释放锁之前,写加锁请求W1到来,他发明lock_word依旧大年夜于0,于是递减X_LOCK_DECR,并把本身的线程id记录在writer_thread这个变量里,再检查lock_word的值(此时为-2),因为结不雅小于0,表示前面有未完成的读加锁请求,于是其等待在wait_ex_event这个前提变量上。后续的R3, W2, W3, R4请求发明lock_word小于0,则都等待在前提变量event上,并且设置waiter为1,表示有等待者。假设R1先释放读锁(lock_word递增1),R2后释放(lock_word再次递增1)。R2释放后,因为lock_word变为0了,其会在wait_ex_event上调用os_event_set,如许W3就被唤醒了,他可以履行临界区内的代码了。W3履行完后,lock_word被恢复为X_LOCK_DECR,然后其发明waiter为1,表示在厥后面有新的读写加锁请求在等待,然后在event上调用os_event_set,如许R3, W2, W3, R4同时被唤醒,进行原子操作履行权限争抢(可以简单的懂得为谁先获得cpu调剂)。假设W2起首抢到了履行权限,其会把lock_word再次递减为0并本身的线程id记录在writer_thread这个变量里,当检查lock_word的时刻,发明值为0,表示前面没有读请求了,于是其就进入临界区履行代码了。假设此时,W3获得了cpu的调剂,因为lock_word只有在大年夜于0的情况下才能递减,所以其递减lock_word掉败,然则其经由过程比较writer_thread和本身的线程id,发明前面的写锁是本身加的,如不雅这个时刻开启了递归写锁,即recursive值为true,他把lock_word再次递减X_LOCK_DECR(如今lock_word变为-X_LOCK_DECR了),然落后入临界区履行代码。如许就包管了同一个线程多次加写锁也不二逝世活锁,也就是递归锁的概念。后续的R3和R4发明lock_word小于等于0,就直接等待在event前提变量上,并设置waiter为1。直到W2和W3都释放写锁,lock_word又变为X_LOCK_DECR,最后一个释放的,检查waiter变量发明非0,就会唤醒event上的所有等待者,于是R3和R4就可以履行了。

读写锁的核心函数函数构造跟InnoDB自旋互斥锁的基本相同,重要的差别就是用rw_lock_x_lock_low和rw_lock_s_lock_low调换了__sync_lock_test_and_set原子操作。rw_lock_x_lock_low和rw_lock_s_lock_low就按照上述的lock_word的变更规矩来原子的改变(依然应用了__sync_lock_test_and_set)lock_word这个变量。

在MySQL 5.7中,读写锁除了可以加读锁(Share lock)要乞降加写锁(exclusive lock)请求外,还可以加share exclusive锁请求,锁兼容性如下:

  1. LOCK COMPATIBILITY MATRIX 
  2.  
  3.     S SX  X 
  4.  
  5. S  +  +  - 
  6.  
  7. SX +  -  - 
  8.  
  9. X  -  -  - 

按照WL#6363的说法,是为了修复index->lock这个锁的冲突。

帮助构造

InnoDB同步机制中,还有很多应用的帮助构造,他们的感化主如果为了监控便利和逝世锁的预防和检测。这里重要介绍sync array, sync thread level array和srv_error_monitor_thread。

内存模型 :重要分为说话级其余内存模型和硬件级其余内存模型。说话级其余内存模型,C/C++属于weak memory model,简单的说就是编译器在进行编译优化的时刻,可以对指令进行重排,只须要包管在单线程的情况下,优化前和优化后履行结不雅一致即可,履行中心过程不包管跟代码的语义次序一致。所以在多线程的情况下,如不雅依附代铝闼殇过程的履行次序,法度榜样就会出现问题。硬件级其余内存模型,我们常用的cpu,也属于弱内存模型,即cpu在履行指令的时刻,为了晋升履行效力,也会对某些履行进行乱序履行(按照wiki供给的材料,在x86 64情况下,只会产生读写乱序,即读操作可能会被乱序到写操作之前),如不雅在编程的时刻不做一些办法,同样轻易造成缺点。


  推荐阅读

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

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


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

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

关键词: 探索发现

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

网友点评
自媒体专栏

评论

热度

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