【OceanBase 诊断调优】—— 大查询线程的管理和调度机制

适用版本:V2.1.x、V2.2.x、V3.1.x、V3.2.x、V4.1.x、V4.2.x内容类型:TechNote

当数据库系统中同时存在 OLTP 与 OLAP 两种业务场景时,可能会出现一种极端的场景,执行较慢的 OLAP 业务把所有的工作线程都给占用了,导致执行较快的 OLTP 业务无法获得工作线程而排队。OceanBase 数据库可以识别大查询,并限制大查询的线程数,从而避免这种问题的发生。

适用版本

OceanBase 数据库 V2.x、V3.x、V4.x 版本。

大查询的定义

OceanBase 数据库中耗时长的 SQL 被称为大查询。

系统参数 large_query_threshold 定义了以查询时长作为维度的大查询判别方式,默认值为 5s,即查询时间超过 5s 的查询被认为是大查询。

大查询线程分配机制

默认情况下,OceanBase 数据库会把 30% 的 CPU 时间用于处理大查询。OceanBase 数据库 V4.0 之前的版本,还不能精确控制大查询的 CPU 占用,observer 进程实际上是控制用来处理大查询的活跃线程数以限制 CPU 使用。大查询只能使用这个租户活跃线程的 30%。

系统参数 large_query_worker_percentage 定义了大查询可以使用的工作线程数量,默认为 30%。

租户的工作线程可能是正常执行的状态,也可能是被挂起的状态,没有挂起的线程就是活跃线程。例如,活跃线程 A 由于执行大查询被挂起,这时活跃线程就少了一个,作为补充,这个租户会额外再创建一个活跃线程。 ​ 在任一 OBServer 中,一个租户的工作线程数量由以下公式计算:

  • 最大线程数 = unit_max_cpu * worker_per_cpu_quota
  • 活跃线程数 = unit_min_cpu * cpu_quota_concurrency
  • 大查询线程数 = 活跃线程数 * large_query_worker_percentage

其中,unit_max_cpu 代表了租户资源规格的 max_cpu,unit_min_cpu 代表了租户资源规格的 min_cpu。

dump tenant info

OBServer 每隔 10s 会在日志中打印队列的统计信息,在 observer.log 中搜索 dump tenant info 关键字,可以获得大查询线程的调度统计信息。

[admin@hostname ~]$ cd /home/admin/oceanbase/log
[admin@hostname log]$ grep 'dump tenant.*tenant={id:1002' observer.log| sed "s/,/\n/g" 

日志信息实例如下。

[2020-12-16 15:29:24.640442] INFO  [SERVER.OMT] ob_multi_tenant.cpp:806 [31771][3104][Y0-0000000000000000] [lt=24] [dc=0] dump tenant info(tenant={id:1002
compat_mode:0
unit_min_cpu:"3.000000000000000000e+00"
unit_max_cpu:"3.000000000000000000e+00"
slice:"0.000000000000000000e+00"
slice_remain:"0.000000000000000000e+00"
token_cnt:12
ass_token_cnt:12
lq_tokens:3
used_lq_tokens:0
stopped:false
idle_us:1709164
recv_hp_rpc_cnt:2
recv_np_rpc_cnt:2
recv_lp_rpc_cnt:0
recv_mysql_cnt:314
recv_task_cnt:11
recv_large_req_cnt:0
tt_large_quries:12
actives:12
workers:12
nesting workers:7
lq waiting workers:0
req_queue:total_size=0 queue[0]=0 queue[1]=0 queue[2]=0 queue[3]=0 queue[4]=0 queue[5]=0
large 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]=0 cnt[6]=0 cnt[7]=0 })

字段含义

字段 含义
id 租户 ID。
unit_min_cpu 保证为租户提供的最小 CPU 核数。
unit_max_cpu 限制租户最大 CPU 核数上限。
slice 无意义。
slice_remain 无意义。
token_cnt 调度器分配的 token 数,一个 token 会转换为一个工作线程。
ass_token_cnt 租户当前确认的 token 数(根据 token_cnt 确定,一般两者相等)。
lq_tokens Large Query token 个数,根据 token_cnt 乘以大请求比例设置。
used_lq_tokens 当前持有 LQ Token 的 Worker 数。
stopped 租户 unit 是否正在删除。
idle_us 一轮日志 dump(10 秒)中工作线程空闲的总时间和。 只统计等待队列的时间。
recv_hp_rpc_cntrecv_np_rpc_cntrecv_lp_rpc_cnt 租户累计收到不同级别的 rpc 请求数,其中 hp 表示 Highnp, Normallp 表示 Low。
recv_mysql_cnt 租户累计收到的 MySQL 请求数。
recv_task_cnt 租户累计收到的内部任务数。
recv_large_req_cnt 租户累计预判的大请求数,只会递增,不会清零。实际是重试的时候递增的。
tt_large_quries 租户累计处理的大请求数, 只会递增,不会清零。实际是打点 check 的时候递增的。
actives 活跃工作线程数,一般和 workers 相等。actives 与 workers 的差表示租户工作线程缓存带工作线程的大请求缓存。
workers 租户持有的工作线程数,实际就是 workers 列表的大小。
lq waiting workers 处于等待调度的工作线程。
req_queue 不同优先级的工作队列,数字越小优先级越高。
large queued 当前预判出的大请求个数。
相关推荐
不爱学习的YY酱12 分钟前
【Linux】<共享内存应用>——模拟实现不同进程把hello字符对<共享内存文件对象>的放入和取出操作
linux·数据库·nosql
OceanBase数据库官方博客15 分钟前
OceanBase 中常用的查询语句
sql·oceanbase·分布式数据库·查询语句
网络安全指导员26 分钟前
SQL注入的那些面试题总结
数据库·sql·安全·web安全·系统安全
奈斯ing38 分钟前
【Oracle篇】SQL性能优化实战案例(从15秒优化到0.08秒)(第七篇,总共七篇)
运维·数据库·sql·oracle·性能优化
Karoku0661 小时前
【企业级分布式系统】ELK-企业级日志分析系统
运维·数据库·redis·mysql·elk·缓存
小小宇宙中微子1 小时前
mysql 命名约束
数据库·sql·oracle
linweidong1 小时前
MariaDB面试题及参考答案
linux·运维·数据库·负载均衡·dba·mariadb·后端面试
PGCCC3 小时前
【PGCCC】Postgresql 缓存替换算法
数据库·缓存·postgresql
盖盖衍上3 小时前
4. SQL视图
数据库·sql