MySQL并发和innodb_thread_concurrency参数理解
测试环境:
CPU:2颗8核
内存:16GB
OS:CentOS Linux release 7.5.1804 (Core)
磁盘:6块300G SAS盘做的raid10,IO性能较差
innodb_buffer_pool_size = 2G
并发相关参数:
相关参数:
innodb_thread_concurrency=0(default),限制innodb内部行的并发度,但是在提交阶段(innodb的结构和锁争用很严重的),却没有得到很好的保护,所以MySQL从5.0开始引进innodb_commit_concurrency参数
innodb_commit_concurrency=0(default 不限制),从5.0就开始引进
innodb_thread_sleep_delay=10000 μs(default),当innodb_thread_concurrency=0时,该值不生效
innodb_adaptive_max_sleep_delay=150000 μs(default)
innodb_concurrency_tickets=5000(default)
机器逻辑CPU是8颗,设置innodb_thread_concurrency=6,观察InnoDB 内部并发和逻辑CPU的使用情况。
用sysbench --threads=100 压测
1)InnoDB 内部并发最高能到6queries,如下:
ROW OPERATIONS
6 queries inside InnoDB, 40 queries in queue
87 read views open inside InnoDB
Process ID=24450, Main thread ID=139692251248384, state: sleeping
Number of rows inserted 16121605, updated 682665, deleted 10473956, read 542121158
335.83 inserts/s, 618.69 updates/s, 309.35 deletes/s, 121723.64 reads/s
2)8颗逻辑CPU都能用上,因为CPU时间片轮转的时间很短,我是以1s为单位采集信息
top
top - 19:19:42 up 228 days, 37 min, 2 users, load average: 49.56, 15.24, 5.42
Tasks: 238 total, 1 running, 237 sleeping, 0 stopped, 0 zombie
%Cpu0 : 76.5 us, 19.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 4.1 si, 0.0 st
%Cpu1 : 74.3 us, 21.1 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 4.7 si, 0.0 st
%Cpu2 : 75.4 us, 18.7 sy, 0.0 ni, 0.6 id, 0.0 wa, 0.0 hi, 5.3 si, 0.0 st
%Cpu3 : 76.5 us, 19.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 4.1 si, 0.0 st
%Cpu4 : 76.5 us, 18.8 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 4.7 si, 0.0 st
%Cpu5 : 76.5 us, 17.6 sy, 0.0 ni, 0.6 id, 0.0 wa, 0.0 hi, 5.3 si, 0.0 st
%Cpu6 : 74.7 us, 19.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 5.9 si, 0.0 st
%Cpu7 : 74.4 us, 19.2 sy, 0.0 ni, 0.6 id, 0.6 wa, 0.0 hi, 5.2 si, 0.0 st
KiB Mem : 16262032 total, 170044 free, 5911864 used, 10180124 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 9059240 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
24450 mysql 20 0 7290636 1.6g 7044 S 480.7 10.2 3293:49 mysqld
3)设置innodb_thread_concurrency=0时,InnoDB内部并发数可超过6 queries。
结合官方文档得到以下结论:
- server层:sql开始执行时。 MySQL在5.6后,在server层引入了thread pool进行并发控制。
- Innodb层:记录查找和记录更新时。Innodb存储引擎,使用innodb_thread_concurrency参数进行并发控制
相关的参数还有innodb_thread_sleep_delay和innodb_concurrency_tickets。
1)当innodb_thread_concurrency=0时,innodb_thread_sleep_delay参数不起作用,引擎层不控制并发数,这时由参数innodb_concurrency_tickets=5000(default)来限制query的并发数,直到tickets用完,线程进入等待或清理不活跃的线程。
2)当innodb_thread_concurrency>0时,超过了innodb_thread_concurrency的值,首先要等innodb_thread_sleep_delay ms后尝试再次进入工作线程,如果失败,则会进入到FIFO队列等待唤醒。如果一个线程能够进到innodb层,则会发放一个innodb_concurrency_tickets票(默认5000),下次的时候如果在有效期内,则不会检查tickets。
也就是说innodb_concurrency_tickets才是真正控制并发,innodb_thread_concurrency只是延缓取票速度。
innodb_thread_concurrency>0时,可通过show engine innodb status\G;的ROW OPERATIONS段来观察query队列(M queries inside InnoDB, N queries in queue)。
innodb_thread_concurrency=0时,innodb status不再采集并发信息,ROW OPERATIONS 状态输出为:0 queries inside InnoDB, 0 queries in queue。
网友评论