代码改变世界

InnoDB的并发线程配置

2023-06-14 18:02  abce  阅读(89)  评论(0编辑  收藏  举报


InnoDB使用操作系统线程来处理用户事务的请求。(事务在提交或回滚之前可能会向InnoDB发出许多请求)在具有多核处理器的现代操作系统和服务器上,上下文切换非常高效,大多数工作负载都可以很好地运行,而不会限制并发线程的数量。

在有助于最小化线程之间的上下文切换的情况下,InnoDB可以使用一些技术来限制并发执行的操作系统线程的数量(从而限制任何时候正在处理的请求的数量)。当InnoDB从一个用户会话接收到一个新的请求时,如果并发执行的线程数量超过预先定义的设置数量,这个新的请求在再次尝试之前会休眠一小段时间。在休眠之后无法重新调度的请求,会放入先进先出队列并最终处理。等待锁的线程不计入并发执行线程的数量。

可以通过设置配置参数innodb_thread_concurrency来限制并发线程的数量。一旦执行线程的数量达到了这个限制,额外的线程在进入队列之前会睡眠数微秒,睡眠时间由配置参数innodb_thread_sleep_delay设置。

你可以将配置选项innodb_adaptive_max_sleep_delay设置为允许innodb_thread_sleep_delay的最大值,InnoDB会根据当前的线程调度活动自动调整innodb_thread_sleep_delay的上下浮动。这种动态调整有助于线程调度机制在系统轻载和接近满负荷运行时平稳地工作。

在MySQL和InnoDB的不同版本中,innodb_thread_concurrency的默认值和默认的并发线程数限制都发生了变化。innodb_thread_concurrency的默认值是0,所以默认情况下没有并发执行线程的数量限制。

InnoDB只在并发线程数量受限时才会让线程休眠。当线程数量没有限制时,所有线程都平等地竞争调度。也就是说,如果innodb_thread_concurrency为0,那么innodb_thread_sleep_delay的值将被忽略。

当有线程数限制时(当innodb_thread_concurrency为>0时),InnoDB通过允许在单个SQL语句执行期间产生的多个请求进入InnoDB,而不遵守innodb_thread_concurrency设置的限制来减少上下文切换开销。由于在InnoDB中,一条SQL语句(例如join)可能包含多个行操作,因此InnoDB会分配指定数量的"tickets",允许以最小的开销重复调度一个线程。

当一个新的SQL语句启动时,线程没有ticket,它必须观察innodb_thread_concurrency。一旦线程有权进入InnoDB,它会被分配一些tickets,用于随后进入InnoDB执行行操作。如果tickets用完,线程会被移除,然后再次观察innodb_thread_concurrency,这可能会将线程放回到等待线程的先进/先进队列中。当线程再次有权进入InnoDB时,tickets再次被分配。分配的tickets数量由全局选项innodb_concurrency_tickets指定,默认为5000。一旦锁可用,等待锁的线程就会得到一个ticket。

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