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
。这种动态调整有助于线程调度机制在系统负载较轻时和接近满负荷运行时都能顺利工作。
innodb_thread_concurrency
的默认值以及对并发线程数量的隐含默认限制在 MySQL 和 InnoDB
的不同版本中有所改变。innodb_thread_concurrency
的默认值为 0
,因此默认情况下没有并发执行线程数量的限制。
InnoDB
仅在并发线程数量有限制时才使线程休眠。当没有线程数量限制时,所有线程都会平等地竞争调度。也就是说,如果 innodb_thread_concurrency
为 0
,则 innodb_thread_sleep_delay
的值会被忽略。
当线程数量有限制时(当 innodb_thread_concurrency
> 0 时),InnoDB
通过允许在执行 单个 SQL 语句 时做出的多个请求进入 InnoDB
,而无需遵守 innodb_thread_concurrency
设置的限制,从而减少了上下文切换开销。由于 SQL 语句(例如联接)可能包含 InnoDB
中的多个行操作,因此 InnoDB
会分配指定数量的 “票证”,允许线程以最小的开销重复调度。
当一个新的 SQL 语句开始时,线程没有票,它必须遵守 innodb_thread_concurrency
。一旦线程有资格进入 InnoDB
,它将被分配一定数量的票,这些票可以用于随后进入 InnoDB
执行行操作。如果票用完,线程将被驱逐,并且再次观察 innodb_thread_concurrency
,这可能会将线程放回等待线程的先进先出队列中。当线程再次有资格进入 InnoDB
时,将再次分配票。分配的票数由全局选项 innodb_concurrency_tickets
指定,默认值为 5000。等待锁的线程在锁可用时将获得一张票。
这些变量的正确值取决于您的环境和工作负载。尝试一系列不同的值以确定哪些值适用于您的应用程序。在限制并发执行线程的数量之前,请查看可能提高 InnoDB
在多核和多处理器计算机上的性能的配置选项,例如 innodb_adaptive_hash_index
。
有关 MySQL 线程处理的常规性能信息,请参阅 第 7.1.12.1 节,“连接接口”。