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
设置的限制。由于 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 节,“连接接口”.