作家
登录

MySQL引擎特性:InnoDB同步机制

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

sync array重要的数据构造是sync_array_t,可以把他懂得为一个数据,数组中的元素为sync_cell_t。当一个锁(InnoDB自旋互斥锁或者InnoDB读写锁,下同)须要产生os_event_wait等待时,就须要在sync array中申请一个sync_cell_t来保存当前的信息,这些信息包含等待锁的指针(便于逝世锁检测),在哪一个文件以及哪一行产生了等待(也就是mutex_enter, rw_lock_s_lock或者rw_lock_x_lock被调用的处所,只在debug模式下有效),产生等待的线程(便于逝世锁检测)以及等待开端的时光(便于统计等待的时光)。当锁释放的时刻,就把相接洽关系的sync_cell_t重置为空,便利复竽暌姑。sync_cell_t在sync_array_t中的个数,是在初始化同步模块时刻就指定的,其个数一般为OS_THREAD_MAX_N,而OS_THREAD_MAX_N是在InnoDB初始化的时刻被计算,其包含了体系后台开启的所有线程,以及max_connection指定的个数,还预留了一些。因为一个线程在某一个时刻最多只能产生一个锁等待,所以不消担心sync_cell_t不敷用。大年夜膳绫擎也可以看出,在每个锁进行等待和释放的时刻,都须要对sync array操作,是以在高并发的情况下,单一的sync array可能成为瓶颈,在MySQL 5.6中,惹人了多sync array, 个数可以经由过程innodb_sync_array_size进行控制,这个值默认为1,在高并发的情况下,建议调高。

InnoDB作为一个成熟的存储引擎,包含了完美的逝世锁预防机制和逝世锁检测机制。在每次须要锁等待时,即调用os_event_wait之前,须要启动逝世锁检测机制来包管不会出现逝世锁,大年夜而造成无穷等待。在每次加锁成功(lock_word递减后,函数返回之前)时,都邑启动逝世锁预防机制,降低逝世锁出现的概率。当然,因为逝世锁预防机制和逝世锁检测机制须要扫描比较多的数据,算法上也有递归操作,所以只在debug模式下开启。

逝世锁检测机制重要依附sync array中保存的信息以及逝世锁检测算法来实现。逝世锁检测机制经由过程sync_cell_t保存的等待锁指针和产生等待的线程以及教科书上的有向图环路检测算法来实现,具体实如今sync_array_deadlock_step和sync_array_detect_deadlock中实现,细心研究后发明个小问题,因为sync_array_find_thread函数仅仅在当前的sync array中遍历,当有多个sync array时(innodb_sync_array_size > 1),如不雅逝世锁产生在不合的sync array上,现有的逝世锁检测算法将无法发明这个逝世锁。

逝世锁预防机制是由sync thread level array和全局锁优先级合营包管的。InnoDB为了降低逝世锁产生的概率,上层的每种类型的锁都有一个优先级。例如回滚段锁的优先级就交手件体系page页的优先级高,固然两者底层都是InnoDB互斥锁或者InnoDB读写锁。有了这个优先级,InnoDB规定,每个锁创建是必须制订一个优先级,同一个线程的加锁次序必须大年夜优先级高到低,即如不雅一个线程今朝已经加了一个低优先级的锁A,在释放锁A之前,不克不及再请求优先级比锁A高(或者雷同)的锁。形成逝世锁须要四个须要前提,个一一个就是不合的加锁次序,InnoDB经由过程锁优先级来降低逝世锁产生的概率,然则不克不及完全清除。原因是可以把锁设置为SYNC_NO_ORDER_CHECK这个优先级,这是最高的优先级,表示一向行逝世锁预防检查,如不雅上层的法度榜样员把本身创建的锁都设置为这个优先级,那么InnoDB供给的┞封套机制将完全掉效,所以要养成给锁设定优先级的好习惯。sync thread level array是一个数组,每个线程零丁一个,在同步模块初始化时分派了OS_THREAD_MAX_N个,所以不消担心不敷用。这个数组中记录了某个线程当前锁拥有的所有锁,当新加了一个锁B时,须要扫描一遍这个数组,大年夜而肯定今朝线程所持有的锁的优先级都比锁B高。

最后,我们来讲讲srv_error_monitor_thread这个线程。这是一个后台线程,在InnoDB启动的时刻启动,每隔1秒钟履行一下指定的操作。跟同步模块相干的操作有两点,去除无穷等待的锁和申报长时光等待的异常锁。

去除无线等待的锁,如上文所属,就是sync_arr_wake_threads_if_sema_free这个函数。这个函数经由过程遍历sync array,如不雅发明锁已经可用(sync_arr_cell_can_wake_up),然则依然有等待者,则直接调用os_event_set把他们唤醒。这个函数是为懂得决因为cpu乱序履行或者编译器指令重排导致锁无穷等待的问题,然则可以经由过程内存樊篱技巧来避免,所以可以去掉落。

申报长时光等待的异常锁,经由过程sync_cell_t琅绫擎记录的锁开端等待时光,我们可以很便利的统计锁等待产生的时光。在今朝的实现中,当锁等待跨越240秒的时刻,就会在缺点日记中看到信息。如不雅同一个锁被检测到比及跨越600秒且持续10次被检测到,则InnoDB会经由过程assert来自杀。。。信赖当做运维DBA的同窗必定看到过如下的报错:

  1. InnoDB: Warning: a long semaphore wait: 
  2.  
  3. --Thread 139774244570880 has waited at log0read.h line 765 for 241.00 seconds the semaphore: 
  4.  
  5. Mutex at 0x30c75ca0 created file log0read.h line 522, lock var 1 
  6.  
  7. Last time reserved in file /home/yuhui.wyh/mysql/storage/innobase/include/log0read.h line 765, waiters flag 1 
  8.  
  9. InnoDB: ###### Starts InnoDB Monitor for

      推荐阅读

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

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


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

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

关键词: 探索发现

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

网友点评
自媒体专栏

评论

热度

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