14.8.5 为 InnoDB 配置线程并发

InnoDB使用 osthreads处理来自用户事务的请求。 (事务在提交或回滚之前可能会向InnoDB发送许多请求.)在具有多核处理器的现代 os 和服务器上,上下文切换是高效的,大多数工作负载运行良好,并且并发线程数没有任何限制。 MySQL 5.5 及更高版本中的可伸缩性改进减少了限制InnoDB内并发执行线程数的需求。

在有助于最大程度地减少线程之间的上下文切换的情况下,InnoDB可以使用多种技术来限制同时执行的 os 线程的数量(以及因此限制在任何时间处理的请求的数量)。当InnoDB接收到来自用户会话的新请求时,如果同时执行的线程数处于 sched 义的限制内,则新请求将休眠一小段时间,然后再次尝试。睡眠后无法重新安排的请求被放入先进/先出队列,并最终得到处理。await 锁的线程不计入同时执行的线程数。

您可以通过设置配置参数innodb_thread_concurrency限制并发线程数。一旦执行线程的数量达到此限制,其他线程就会休眠数微秒(由配置参数innodb_thread_sleep_delay设置),然后再放入队列。

以前,需要进行实验以找到innodb_thread_sleep_delay的最佳值,并且该最佳值可能会根据工作负载而变化。在 MySQL 5.6.3 和更高版本中,可以将配置选项innodb_adaptive_max_sleep_delay设置为允许innodb_thread_sleep_delay的最大值,并且InnoDB会根据当前线程调度活动自动向上或向下调整innodb_thread_sleep_delay。这种动态调整有助于线程调度机制在系统轻负载和接近满负荷运行时平稳运行。

innodb_thread_concurrency的默认值和并发线程数的默认默认限制在 MySQL 和InnoDB的各个发行版中均已更改。 innodb_thread_concurrency的默认值为0,因此默认情况下并发执行的线程数没有限制。

InnoDB仅在限制并发线程数时使线程休眠。当线程数没有限制时,所有线程都平等地争用调度。也就是说,如果innodb_thread_concurrency0,则忽略innodb_thread_sleep_delay的值。

当线程数受到限制时(当innodb_thread_concurrency> 0 时),InnoDB通过允许在执行单个 SQL 语句时发出的多个请求 ImportingInnoDB而不遵守innodb_thread_concurrency设置的限制,从而减少了上下文切换开销。由于 SQL 语句(例如连接)可能在InnoDB内包含多个行操作,因此InnoDB分配了指定数量的“票证”,这些票证允许以最小的开销重复调度线程。

当新的 SQL 语句启动时,线程没有票证,并且必须遵守innodb_thread_concurrency。一旦线程有权 ImportingInnoDB,便为其分配了多个票证,可将其用于随后 ImportingInnoDB来执行行操作。如果票证用完,线程将被逐出,并再次观察到innodb_thread_concurrency,这可能会将线程放回到 await 线程的先进先出队列中。当线程再次有权 ImportingInnoDB时,将再次分配票证。分配的票证数量由全局选项innodb_concurrency_tickets指定,默认情况下为 5000.一旦锁可用,await 锁的线程将获得一张票证。

这些变量的正确值取决于您的环境和工作量。尝试各种不同的值,以确定哪种值适用于您的应用程序。在限制并发执行线程的数量之前,请查看可提高InnoDB在多核和 multiprocessing 器计算机(例如innodb_adaptive_hash_index)上的性能的配置选项。

有关 MySQL 线程处理的一般性能信息,请参见第 5.1.11.1 节“连接接口”