原创水平有限请谅解
虽然这几个参数我以前也有学习过,但是一直没有在源码级别进行证明,所以一直也没有写,但是今天群里有
朋友问到,所以先按照官方手册的加上我自己的理解进行一下解释,以后一定要在源码级别进行下补充
使用MYSQL版本:5.7.14
OS平台: CentOS release 6.5 (Final) 64bit
一、理论基础
首先要理解几个参数我们必须要先知道下面的内容,注意下面内容并不深入,而且只是我自己的理解
1、什么是多线程
实际上MYSQL中的多线程就是POSIX那一套,比如也就是我们说的pthread族函数比如pthread_create、pthread_join、pthread_mutex_lock等等,相信有多线程编程基础
的朋友不会陌生,线程也叫轻量级进程(LWP)那么多线程有什么好处,相对于进程而言多线程共享了很多东西比如
1.文件描述符表
2.每种信号的处理方式
3.当前工作目录
4.用户ID和组ID
5.除栈以外的内存空间
其实我们在编程的时候多线程通信都是通过非栈以外的内存进程的,比如堆空间,既然线程能够共享这麽多资源,不管是线程的创建、上下文切换、线程间通信都
变得方便了(注意共享是方便了但是对临界区的管理需要使用类似mutex rwlock之类的锁来实现)。接下来我们就要来讲讲线程间上下文切换
同时要记住一点线程是CPU调度的最小单位、进程是资源分配的最小单位。配上一张图
2、线程的上下文切换
我们知道LINUX是一个多批道多用户分时操作系统,它允许多个任务同时进入内存CPU通过时间轮片的方式进行调度,我们举例如果我有2核的CPU,但是我当前有4
个同等优先级的MYSQL线程进入了就绪队列,那么我们同一时刻能够并行(注意用词的准确性不是并发是并行)执行的MYSQL线程其实是2个,另外2个呢?当然就处
于就绪队列,等待获得CPU时间来完成工作,等到正在执行的2个线程时间轮片用完以后这个时候需要保留处理器现场,其实就是保存寄存器的值到内存,然后放弃
CPU,进入就绪态,这个时候在就绪队列的2个线程可以进入CPU进行工作了,这种4个线程并发执行但是只有2个线程获得时间轮片并行执行(获得CPU轮片)在这种不断
需要获得CPU轮片-->>工作-->>保存寄存器值到内存-->>放弃CPU轮片的方式中我们将保存寄存器值到内存这种动作叫做线程上下文切换,这是有一定代价的,当然
我的理解也许很片面因为我毕竟不是搞LINUX内核的。如果同时需要并发执行的线程越多这种上下文切换的频率就越大,这也是为什么我们在LINUX负载高的时候能够观察
到更多上下文切换的原因(vmstat就可以看到),那么我们说如果限制同一时刻并发执行的线程数上下文切换将会减少,某种意义说就是长痛不如短痛,与其让你不断的
进行上文切换还不如把你处于睡眠态放弃CPU使用权
这里简单说一下线程的缺点:
线程不稳定(库函数实现)
线程调试比较困难(gdb支持不好)
信号使用非常困难
3、小事物线程饥饿问题
如果有过多线程编程使用过MUTEX,这种抢占试锁的朋友,一定不会忘记在某个线程释放MUTEX后,其他线程会以抢占的方式来获得,某些线程可能运气不好老是抢不到,如果换成
同优先级线程之间,OS在调度的时候如果不均衡,那么某些可能任务量小的线程老是得不到CPU轮片,而大任务线程老是获得CPU轮片,这依赖于OS的线程调度策略,这样就可能形成小
任务线程饥饿问题,与其依赖OS的调度策略不如自己设置一种规则,让用到了一定时间轮片的线程先处于睡眠态放弃CPU的使用。
二、参数解释
好了有了上面的理论知识可以进行这几个参数的解释了
其实这三个参数就是来解决上面的问题
1、innodb_thread_concurrency
同一时刻能够进入innodb层次并发执行的线程数(注意是并发不是并行),如果超过CPU核数,某些线程可能处于就绪态而没有获得CPU时间轮片,如果SERVER层的线程大于这个值,对不起多余的
线程将会被放到一个叫做wait queue的队列中,而不能进入INNODB层次,进不到innodb层当然也就不能干活了,谈不上获得CPU。既然是一个队列那么它必然满足先进入先出的原则。这也是前面说的长痛不如短痛,与其让你不断的进行上文切换还不如把你处于睡眠态放弃CPU使用权,默认这个值是0,代表不限制。
2、innodb_concurrency_