MySQL并發(fā)和innodb_thread_concurrency參數(shù)理解
測(cè)試環(huán)境:
CPU:2顆8核
內(nèi)存:16GB
OS:CentOS Linux release 7.5.1804 (Core)
磁盤:6塊300G SAS盤做的raid10,IO性能較差
innodb_buffer_pool_size = 2G
并發(fā)相關(guān)參數(shù):
相關(guān)參數(shù):
innodb_thread_concurrency=0(default)蔫敲,限制innodb內(nèi)部行的并發(fā)度,但是在提交階段(innodb的結(jié)構(gòu)和鎖爭用很嚴(yán)重的)盈匾,卻沒有得到很好的保護(hù),所以MySQL從5.0開始引進(jìn)innodb_commit_concurrency參數(shù)
innodb_commit_concurrency=0(default 不限制),從5.0就開始引進(jìn)
innodb_thread_sleep_delay=10000 μs(default)咬像,當(dāng)innodb_thread_concurrency=0時(shí)乖杠,該值不生效
innodb_adaptive_max_sleep_delay=150000 μs(default)
innodb_concurrency_tickets=5000(default)
機(jī)器邏輯CPU是8顆狭魂,設(shè)置innodb_thread_concurrency=6阅茶,觀察InnoDB 內(nèi)部并發(fā)和邏輯CPU的使用情況。
用sysbench --threads=100 壓測(cè)
1)InnoDB 內(nèi)部并發(fā)最高能到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都能用上萝玷,因?yàn)镃PU時(shí)間片輪轉(zhuǎn)的時(shí)間很短,我是以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)設(shè)置innodb_thread_concurrency=0時(shí)昆婿,InnoDB內(nèi)部并發(fā)數(shù)可超過6 queries球碉。
結(jié)合官方文檔得到以下結(jié)論:
- server層:sql開始執(zhí)行時(shí)。 MySQL在5.6后仓蛆,在server層引入了thread pool進(jìn)行并發(fā)控制睁冬。
- Innodb層:記錄查找和記錄更新時(shí)。Innodb存儲(chǔ)引擎多律,使用innodb_thread_concurrency參數(shù)進(jìn)行并發(fā)控制
相關(guān)的參數(shù)還有innodb_thread_sleep_delay和innodb_concurrency_tickets痴突。
1)當(dāng)innodb_thread_concurrency=0時(shí)搂蜓,innodb_thread_sleep_delay參數(shù)不起作用狼荞,引擎層不控制并發(fā)數(shù)辽装,這時(shí)由參數(shù)innodb_concurrency_tickets=5000(default)來限制query的并發(fā)數(shù),直到tickets用完相味,線程進(jìn)入等待或清理不活躍的線程拾积。
2)當(dāng)innodb_thread_concurrency>0時(shí),超過了innodb_thread_concurrency的值,首先要等innodb_thread_sleep_delay ms后嘗試再次進(jìn)入工作線程丰涉,如果失敗拓巧,則會(huì)進(jìn)入到FIFO隊(duì)列等待喚醒。如果一個(gè)線程能夠進(jìn)到innodb層一死,則會(huì)發(fā)放一個(gè)innodb_concurrency_tickets票(默認(rèn)5000)肛度,下次的時(shí)候如果在有效期內(nèi),則不會(huì)檢查tickets投慈。
也就是說innodb_concurrency_tickets才是真正控制并發(fā)承耿,innodb_thread_concurrency只是延緩取票速度。
innodb_thread_concurrency>0時(shí)伪煤,可通過show engine innodb status\G;的ROW OPERATIONS段來觀察query隊(duì)列(M queries inside InnoDB, N queries in queue)加袋。
innodb_thread_concurrency=0時(shí),innodb status不再采集并發(fā)信息抱既,ROW OPERATIONS 狀態(tài)輸出為:0 queries inside InnoDB, 0 queries in queue职烧。