zoukankan      html  css  js  c++  java
  • MySQL timed_mutexes

    提要:

      MySQL 5.5.39 Release版本正式从源码里删除了全局参数timed_mutexes。timed_mutexes原本用来控制是否对Innodb引擎的mutex wait进行 计时统计,以方便进行性能诊断。为什么要删除这个参数呢? 下面介绍下相关背景:

    Innodb的同步锁机制:

      Innodb封装了mutex和rw_lock结构来保护内存的变量和结构进行多线程同步,考虑可移植性, mutex使用lock_word或者OS mutex来保证原子操作,并使用event条件变量进行阻塞和唤醒操作。

        os_event_t event;
        volatile lock_word_t lock_word;
        os_fast_mutex_t os_fast_mutex;


    Innodb同步锁引入的数据结构和开销

      

    1. 全局mutex链表

      Innodb引入了一个全局的链表ut_list_base_node_t mutex_list,并使用一个单独的mutex来保护链表。 所有的mutex在create或者free的时候来修改链表,有了全局链表,也使统计汇总有了可能性,参考命令“show engine innodb mutex”. 虽然需要维护一个全局的链表,但这并不会影响太多的性能,因为大部分的mutex的生命周期都是从Innodb启动一直到shutdown。

    2. 统计信息

      mutex的结构中,有几个统计信息:

    count_os_wait:请求mutex进入等待的次数
    count_using: 请求mutex的次数
    count_spin_loop: 请求mutex时spin的轮数
    count_spin_rounds: 请求mutex的spin次数
    count_os_yield:请求mutex spin失败后os等待次数
    lspent_time: 统计等待mutex的时间

    lock mutex的主要步骤:
      1. 首先trylock mutex,如果没有获取到mutex,并不马上进行wait,而是进行spin。
      2. 尝试spin,如果在SYNC_SPIN_ROUNDS次后,仍然没有lock,那么就进入等待队列,等待唤醒。

      在MySQL5.5的版本里,非UNIV_DEBUG模式下,Innodb仅仅保留了count_os_wait的次数,这也是为了性能的考虑。所以5.5的版本后, timed_mutexes在Release下,其实已经不再起作用,所以5.5.39,以及5.6以后,源码里都不再保留timed_mutexes。 要么在debug模式下,启用这些统计,但上线版本又不可能使用DEBUG模式,所以对于mutex的统计,MySQL在后面的版本中使用了performance_schema的等待事件来代替,即:

     mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
     -> WHERE TABLE_SCHEMA = 'performance_schema'
     -> AND TABLE_NAME LIKE '%instances';
     +------------------+
     | TABLE_NAME       |
     +------------------+
     | cond_instances   |
     | file_instances   |
     | mutex_instances  |
     | rwlock_instances |
     +------------------+

    3. 全局等待队列

      Innodb为所有的等待状态的线程准备了一个队列,如果获取mutex失败,那么就申请一个cell,进入阻塞状态,等待signal。 sync_primary_wait_array,有了这个全局的队列,Innodb就可以对这些wait的线程进行统计,比如long semaphore waits就是 根据这个队列进行的查询。

    4. signal丢失

    这里再讨论下signal丢失的情况,我们重新再看下lock mutex的步骤:

     线程1:
     1. try lock mutex
     2. fail,然后spin
     3. fail,然后进入队列,然后wait event
     线程2:
     1.own mutex
     2.free mutex
     3.signal event

      如果按照这个时序,在线程2 signal event后,线程1才进入队列,那么线程1就永远处在阻塞状态,无法唤醒。为了解决signal丢失的情况, Innodb启动了一个后台线程:sync_arr_wake_threads_if_sema_free,每隔1s就轮询wait数组,如果可以lock,就signal这个event来唤醒线程。

      

      从上面来看,Innodb为了mutex和rwlock的移植性,以及为了监控和诊断,添加了多个全局的数据结构,这样实时的统计才有可能,但也带来了维护数据结构的开销。 而timed_mutexes控制的mutex wait时间统计,因为只在debug模式下进行编译,而且5.6以后使用performance schema的等待事件进行替代,所以参数做了删除处理。

  • 相关阅读:
    WEB安全第二篇--用文件搞定服务器:任意文件上传、文件包含与任意目录文件遍历
    WEB安全第一篇--对服务器的致命一击:代码与命令注入
    python的内存管理与垃圾回收机制学习
    java反序列化漏洞的检测
    python epoll实现异步socket
    Python class的属性访问控制和内建函数重写实现高级功能以及@property
    weblogic新漏洞学习cve-2017-10271
    PHP后门的eval类和system类 函数到底有哪些区别
    JS 转整型
    .NET MVC model数据验证
  • 原文地址:https://www.cnblogs.com/xpchild/p/3906041.html
Copyright © 2011-2022 走看看