一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

mysql中innodb_thread_concurrency的作用与改良

时间:2016-10-22 编辑:简简单单 来源:一聚教程网

innodb_thread_concurrency
如果参数设置大于0,则表示检查机制开启,允许进入的线程数就是参数的值.
在新的MySQL线程调用Innodb接口前,Innodb会检查已经接受的请求线程数;
如已经超过innodb_thread_concurrency设置的限制,则该请求线程会等待innodb_thread_sleep_delay微秒后尝试重新请求,如果第二次请求还是无法获得,则该线程会进入FIFO队列休眠。重试两次的机制是为了减少CPU的上下文切换的次数,以降低CPU消耗。
如果请求被Innodb接受,则会获得一个次数为innodb_concurrency_tickets(默认500次)的通行证,在次数用完之前,该线程重新请求时无须再进行前面的检查
--代码结构如下
if (thread->n_tickets_to_enter_innodb  > 0)
  {
    thread->n_tickets_to_enter_innodb--;
    ENTER;
  }
retry:
  if (entered_thread < innodb_thread_concurrency)
  {
    entered_threads++;
    thread->n_tickets_to_enter_innodb = innodb_concurrency_tickets;
    ENTER;
  }
  if (innodb_thread_sleep_delay  > 0)
  {
    thread_sleep(innodb_thread_sleep_delay);
  }
  goto retry; // (only once)
  WAIT_IN_FIFO_QUEUE;
  thread->n_tickets_to_enter_innodb = innodb_concurrency_tickets;
  ENTER;
源文件为srv_conc_enter_innodb (innobase/srv/srv0srv).
如果是一个已经持有lock的线程,则通过调用srv_conc_force_enter_innodb函数可以无视该检查,这是为了避免线程长时间持有锁影响性能,且可能增加死锁的机率。除此之外,slave线程也是有无视检查直接通行的权限;
不足:采用os_event_t管理入队和出队,虽可以防止饥饿等待,但管理开销比较大,;
改进:采用busy polling投票获取slot,没获取的则睡眠等待;可为了减轻排队开销,但有可能导致饥饿等待;
为此新引入参数
Innodb_adaptive_sleep_delay:布尔型,用于激活或关闭adaptive sleep delay
Innodb_adaptive_max_sleep_delay:以微秒为单位,定义最大睡眠delay
adaptive 的算法是:
  如果sleep了当前值以后还是不能进入,就把sleep时间+1.
  如果还有线程在sleep时,已经有了空闲线程,就把当前值的sleep 时间减半
innodb_thread_concurrency限制行的并发度,但是在提交阶段innodb的结构和锁争用很严重的。MySQL从5.0就开始引进的innodb_commit_concurrency,这个参数设置了同一时刻允许同时commit的线程数。默认是0即不限制,取值范围0-1000,不可动态修改。

热门栏目