【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 当前预判出的大请求个数。
相关推荐
m0_748248021 小时前
Redis 简介与安装指南
数据库·redis·缓存
Elastic 中国社区官方博客6 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
编程爱好者熊浪7 小时前
两次连接池泄露的BUG
java·数据库
TDengine (老段)9 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
qq7422349849 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
姚远Oracle ACE10 小时前
Oracle 如何计算 AWR 报告中的 Sessions 数量
数据库·oracle
Dxy123931021610 小时前
MySQL的SUBSTRING函数详解与应用
数据库·mysql
码力引擎10 小时前
【零基础学MySQL】第十二章:DCL详解
数据库·mysql·1024程序员节
杨云龙UP10 小时前
【MySQL迁移】MySQL数据库迁移实战(利用mysqldump从Windows 5.7迁至Linux 8.0)
linux·运维·数据库·mysql·mssql
l1t10 小时前
利用DeepSeek辅助修改luadbi-duckdb读取DuckDB decimal数据类型
c语言·数据库·单元测试·lua·duckdb