适用版本
OceanBase 数据库 V2.x、V3.x 版本。
问题描述
前端请求到后端 OBServer 并发太大,导致租户正常的业务 SQL 都很慢。
可以用以下脚本复现问题。
#cat /root/sleep.sh
mysql -h100.xx.xxx.xx -P2881 -uroot@sys -p -c -A -D oceanbase -e 'select sleep(10)'
运行以下命令即可。
for i in $(seq 1 150); do nohup sh sleep.sh & done
问题原因
查看日志发现租户有队列等待,关键词为 req_queue:total_size=133。
[2023-04-12 13:40:28.881354] INFO [SERVER.OMT] ob_multi_tenant.cpp:812 [55420][0][Y0-0000000000000000-0-0] [lt=10] [dc=0] dump tenant info(tenant={id:1, compat_mode:0, unit_min_cpu:"2.500000000000000000e+00", unit_max_cpu:"5.000000000000000000e+00", slice:"0.000000000000000000e+00", slice_remain:"0.000000000000000000e+00", token_cnt:20, sug_token_cnt:20, ass_token_cnt:20, lq_tokens:6, used_lq_tokens:6, stopped:false, idle_us:7910391, recv_hp_rpc_cnt:27294, recv_np_rpc_cnt:135896, recv_lp_rpc_cnt:0, recv_mysql_ps_close_cnt:5, recv_mysql_cnt:2492193, recv_task_cnt:615076, recv_large_req_cnt:264, tt_large_quries:1432, pop_normal_cnt:247941054, actives:32, workers:32, nesting workers:7, lq waiting workers:12, req_queue:total_size=133 queue[0]=0 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=133 queue[5]=0 , large queued:0, reserve queued:0, multi_level_queue:total_size=0 queue[0]=0 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=0 queue[5]=0 queue[6]=0 queue[7]=0 , recv_level_rpc_cnt:cnt[0]=0 cnt[1]=0 cnt[2]=0 cnt[3]=0 cnt[4]=0 cnt[5]=28764 cnt[6]=0 cnt[7]=0 , group_map:, rpc_stat_info: pcode=0x119:cnt=68 pcode=0x51f:cnt=21 pcode=0x11b:cnt=19 pcode=0x1516:cnt=10 pcode=0x518:cnt=3})
产生队列积压的原因为消费速度 < 生产速度,最终原因还是处理的慢(sleep 10)。 租户的活跃会话个数跟租户的 CPU 个数有关,如果一个租户有 n 个 CPU,通常该租户最多有 10n 个用户会话是同时活动的,有 4n 个线程是同时活动的。当租户的活跃会话、线程数超过限制时,新的会话与 SQL 执行就会加入队列等待。
解决方法
增加租户的 CPU 个数。
减少业务 SQL 并发。