当前位置: 首页 > news >正文

【OceanBase诊断调优】—— KVCache 排查手册

原文链接:OceanBase分布式数据库-海量数据 笔笔算数

本文介绍 KVcache 相关问题的排查方法。

KVCache 相关概念

在进行排查前,需要了解几个概念。

  • pin

    一个 cache 块 ( memblock ) 被 pin 住,表示它正在被引用。

    cache 的由多个定长的块组成,每个块称为一个 memblock 。每个 memblock 中存放了多个 KV ,使用者通过 KV 指针来读取 KV 。容易理解,在使用指针的过程中,需要保证指针的安全,也即需要 pin 住存放 KV 的 memblock ,保证它不被释放。cache 内部通过引用计数来实现,cache 每向外吐出一个 KV 指针,都要对 KV 所在的 memblock 的引用计数加 1 ( pin 住这个 memblock ) ,当不再使用 KV 指针时,引用计数减 1 。也就是说,当引用计数大于 0 时,说明有人正在读其中的内存,那这个 memblock 就不能被释放,反之如果等于 0 ,则释放是安全的。

    简而言之,如果一个 memblock 被 pin 住,那么它不能被释放。

  • sync wash

    sync wash 指 cache 腾出自身内存给租户使用的过程。 从 1 可知,如果一个 memblock 没有被 pin ,那么它是可以被释放的。sync wash 就是 cache 找到没有被 pin 的 memblock ,释放内存,腾给租户使用。

  • cache 大小无上限

    cache 的大小在一个租户内是无上限的。 为了最大化利用租户内存,在租户内不限制 cache 的大小,理论上 cache 最大可以占满一个租户的内存。但是 cache 的内存比较特殊,在租户需要内存时,会触发 cache 的 sync wash ,腾出内存给租户使用。

常见问题

ret=-4273 can not find enough memory block to wash

首先 4273 不是 cache 的问题,4273 报错表示在 sync wash 过程中发现 cache 中所有的 memblock 都被 pin 了,没有内存可以释放。 导致 4273 的原因可能有:

  • cache 本身已经被榨干了,没有内存可以 wash ,所以就找不到不被 pin 的 memblock。

  • cache 本身还有内存,但是都被 pin 住了,无法 wash 出来;这个原因又分为两种情况:

    • 确实有需要较多 cache 的 SQL 在执行。
    • cache handle 引用计数有泄漏。

排查的思路就是逐步确认是哪个原因导致的 4273 ,步骤如下:

  1. 查看当时 cache 的大小。

    * 通过 MEMORY 日志,memory 日志可以看到租户的 cache_hold ,这个字段记录了 cache 的总大小。
    * 通过 CACHE 日志,可以看到当时各个 cache 的大小。
    * 通过虚拟表 `__all_virtual_kvcache_info`,各版本都有,但是是实时数据,需要在案发时查询。
    

    如果此时 cache 大小很少,说明此时 cache 本身已经被榨干,wash 不出内存符合预期,应该查看当时租户的内存分布,看看其他 mod 是否符合预期,否则进入第二步。

  2. 判断是否存在泄漏。

    这一步是通过查看 cache 的大小能否降下来,来区分是 cache handle 引用计数有泄漏还是确实有需要较多 cache 的 SQL 在执行。

    对于 OceanBase 数据库 V4.0 及以后版本,可以停止所有查询后尝试手动 flush cache ,如果 cache 能降下来,则说明没有泄漏,是确实有需要较多 cache 的 SQL 在执行导致。

    手动 flush 需要直连到 OBServer 节点上执行,如果可以 flush 干净 ( 可能需要手动 flush 多次 ) ,则表示没有泄漏,对比 flush 前后 __all_virtual_kvcache_info 表中 size 的变化来判断。也可以通过查询 __all_virtual_kvcache_store_memblock 虚拟表来直接查看所有 memblock 引用计数,看是否有异常。

    select * from __all_virtual_kvcache_store_memblock where ... order by ref_count desc limit 10;
    

    对于 OceanBase 数据库 V4.0 之前版本,只能通过日志查看在 4273 报错后,cache 的大小是否降下去过,如果能降下去,则说明一定没有泄漏,如果没降下去过,则无法判断。( 因为之前版本手动 flush 并不会立即释放 cache 的内存,而是通过降低其访问热度,通过后台 wash 线程慢慢刷出去。 )

    如果是较多 cache 的 SQL 在执行导致,规避方案是,将 cache 用量较大的操作分散在租户内存压力较小的时候执行,如果仍有报错,尝试对租户内存进行扩容,增大内存。 如果是 cache handle 引用计数有泄漏导致,则需要复现问题,排查泄漏的路径。

cache 占用内存较高

如前文所述,cache 在租户内是无上限的,所以理论上无论 cache 占多大内存,只要能被 sync wash ,就是符合预期的。 判断能否 sync wash 出来需要参考问题 1 中判断 cache 大小能否降下来的方法,能降下来就是能 sync wash 出来。

cache 预热

OceanBase 数据库 V4.0 及以后的版本支持 cache 预热功能,之前版本没有此功能。 为缓解 compaction 后的性能抖动,在 compaction 时会将新生成的微块放入 cache 中,进行预热。 预热并不会将所有新生成的微块都预热进 cache ,而是根据租户的内存情况进行预热。现有策略下,data block cache 使用租户空闲内存的 5% ,index block 使用租户空闲内存的 2% 。 data block 和 index block 按照不同的优先级被预热进 cache ,按照中间层索引树的等级分配不同的优先级,越接近根节点的 block 优先级越高。

wash

cache 腾出自身内存的过程称为 wash ,cache 的 wash 行为分为同步 wash 和异步 wash 两种。 同步 wash 就是上文提到的 sync wash,同步腾出内存,这里不再赘述。 异步 wash 由一个后台 wash 线程完成,wash 线程会定期地根据每个租户的内存压力 ( 包括租户大小、当前 cache 大小、租户当前空闲内存等 ) 计算出租户应该 wash 出的 cache size ,然后再根据每个 memblock 的访问热度从低到高 wash 。如果压力不大,计算结果可能是 0,不做 wash ,可以根据如下日志来判断,如果有则表示 wash 线程异步 wash 了 memblock。

COMMON_LOG(INFO, "Wash memory, ","tenant_id", wash_iter->first,"cache_size", tenant_wash_info->cache_size_,"lower_mem_limit", tenant_wash_info->lower_limit_,"upper_mem_limit", tenant_wash_info->upper_limit_,"min_wash_size", tenant_wash_info->min_wash_size_,"max_wash_size", tenant_wash_info->max_wash_size_,"mem_usage", lib::get_tenant_memory_hold(wash_iter->first),"reserve_mem", static_cast<int64_t>((static_cast<double>(tenant_wash_info->upper_limit_)) * tenant_reserve_mem_ratio_),"wash_size", tenant_wash_info->wash_size_);

wash 线程的异步 wash 实际上是减去 memblock 原始的引用计数,等待引用计数减为 0 时执行释放,因此:

  • 异步 wash 并不能立即释放 memblock ,需要等待不被 pin 。
  • 如果有引用计数泄漏泄漏,wash 线程一样不能 wash memblock。

手动 flush

手动 flush cache 表示手动清理指定 cache , 命令如下,目前只能在 sys 租户下执行,需要直连要 flush 的 OBServer 节点。

alter system flush kvcache [tenant tenant_name [cache 'cache_name']];

cache_name 可以在 __all_virtual_kvcache_info 中查到,常用的 cache_name 有 :user_block_cache、index_block_cache、user_row_cache、fuse_row_cache、bf_cache。

OceanBase 数据库 V4.0 及以后版本,flush 包含了立即清空的功能,预期情况下,flush 之后 cache 应该是立即被清空(若内存占用太多,flush 只清理一部分内存)。如果发生 4274 的报错,是 cache 较多导致的超时问题,再次 flush 即可。

OceanBase 数据库 V4.0 之前版本,手动 flush 只会清除指定 cache 中 KV 的索引,索引删除后,对应的 KV 就无法再被访问到,其所在的 memblock 的热度就会持续降低,等待 wash 线程将其 wash 出去。

判断手动 flush 是否生效

无论新老版本,手动 flush 一定会清理掉全部的 kv_cnt ,可以观察 flush 前后 kv_cnt 是否清零过来判断手动 flush 是否生效。

select * from __all_virtual_kvcache_info where cache_name = '<cache_name>';

监控 cache handle ,排查引用计数泄漏

OceanBase 数据库 V4.0 及之后版本,如果怀疑或确认 cache 引用计数有泄漏,可以通过如下方法诊断。

  1. binary 需要启用 ENABLE_DEBUG_LOG 编译选项。

  2. 打开监控,指定监控的 cache name 。

    alter system set leak_mod_to_check = 'cache_name';
    
  3. 查看泄漏 backtrace 。

    select * from __all_virtual_kvcache_handle_leak_info where tenant_id = tenant_id order by hold_count desc limit 10;
    

    在 OceanBase 数据库 V4.3 及以后版本虚拟表更名为 __all_virtual_storage_leak_info,并且新增配置项 _storage_leak_check_mod 用于指定泄漏监控的内容。

    这里简单介绍一下监控的实现方法。cache 对外吐出的引用计数都包含在 cache_handle 中,一个 cache_handle hold 住 1 个引用计数,所以在 cache 对外吐出 cache_handle 时,记录一条 backtrace ,在 cache_handle reset 时,消除记录。所以最后遗留下来未释放的 backtrace 很大可能就是泄漏的 backtrace 。

    根据记录方式可以知道,只要当前 cache 外部有 cache_handle ,那就会被记录 backtrace ,所以任何路径在持有 cache_handle 期间都会被记录,需要抓到持有时间过长或不符合预期的堆栈才是泄漏的堆栈。

    如果事先没有开启 cache handle 监控,可以通过 __all_virtual_kvcache_store_memblock 虚拟表简要确认一下问题,这张表会输出当前 server 上所有 memblock 的信息。 (OceanBase 数据库 V 4.3 及以后版本使用新的虚拟表)

    select * from __all_virtual_kvcache_store_memblock where ... order by ref_count desc limit 10;
    

    关注 ref_count 列,这一列表示 memblock 的当前的引用计数,目前当 memblock 没有被引用时,这里拿到的引用计数为 2 ( 初始引用计数为 1 ,查 memblock 信息时需要先加引用计数做保护,因此为 2 ) 。在确保某 memblock 当前不会被 pin 的前提下,ref_count 大于 2 的 memblock 都可以认为有引用计数泄漏。

泄漏检测扩展 (OceanBase 数据库 V4.3 及以后版本)

OceanBase 数据库 V4.3 及以后版本,新增存储层的泄漏检测功能,目前支持的检测内容有 cache handle、io handle、storage iter ,同时,新增配置项 _storage_leak_check_mod 用于配置泄漏检测的内容,有效值分别为 cache_name / all_cache / io_handle / storage_iter ,默认为空串,设定成空串或其他值时,关闭监控。

同时,__all_virtual_kvcache_handle_leak_info 虚拟表更名为 __all_virtual_storage_leak_info

检测步骤使用新的配置和虚拟表即可:

  1. binary 需要启用 ENABLE_DEBUG_LOG 编译选项。

  2. 打开监控,指定监控的内容。

    alter system set _storage_leak_check_mod = 'cache_name' | 'all_cache' | 'io_handle' | 'storage_iter' ;
    
  3. 查看泄漏 backtrace。

    select * from __all_virtual_storage_leak_info where ... order by hold_count desc limit 10;

相关文章:

【OceanBase诊断调优】—— KVCache 排查手册

原文链接&#xff1a;OceanBase分布式数据库-海量数据 笔笔算数 本文介绍 KVcache 相关问题的排查方法。 KVCache 相关概念 在进行排查前&#xff0c;需要了解几个概念。 pin 一个 cache 块 ( memblock ) 被 pin 住&#xff0c;表示它正在被引用。 cache 的由多个定长的块组成…...

核函数的介绍

1.核函数的介绍&#xff1a; 1、用线性核等于没有用核。 2、多项式核&#xff1a;随着d越大&#xff0c;则 fai(X) 对应的维度将越高。&#xff08;可以通过d得到对应的fai(X)函数&#xff09;。 3、高斯核函数&#xff1a;无限维度。 4、tanh核。 2.如何选择核函数的参数&am…...

使用pytorch写一个简单的vae网络用于生成minist手写数字图像

文章目录 代码结果代码 import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from torch.utils.data import DataLoader from torchvision impo...

Windows平台让标准输入(stdin)的阻塞立即返回

文章目录 背景介绍代码示例版本1-基本命令处理版本2-多线程命令处理&#xff0c;不阻塞主函数版本3-即使没有用户输入&#xff0c;也能立即退出 背景介绍 在开发命令行工具或控制台应用程序时&#xff0c;经常需要处理用户输入。常规做法是使用标准输入&#xff08;stdin&…...

Spring中的Aware接口

Spring中的Aware接口 Aware接口介绍 Aware是Spring中的接口&#xff0c;它的作用是可以让Bean获取到运行环境的相关信息。比如获取到上下文、Bean在容器中的名称等。 Spring中提供了很多Aware接口的子类&#xff0c;具体如下&#xff1a; 常用接口的作用如下&#xff1a; …...

FFmpeg滤镜完整列表

FFmpeg滤镜完整列表 滤镜名称 用途 acompressor 压缩音频信号,当输入信号超过某个预设阈值时&#xff0c;压缩器就会开始工作。该滤镜使音量大的部分变得不那么响亮&#xff0c;而音量小的部分相对变得响亮&#xff0c;这样就可以使整体听起来更加均衡&#xff0c;常用于音乐…...

深入探索Python基础:两个至关重要的函数

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、初学者的基石&#xff1a;print与input函数 二、类型转换&#xff1a;从字符串到浮点数…...

探索集合python(Set)的神秘面纱:它与字典有何不同?

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、集合&#xff08;Set&#xff09;与字典&#xff08;Dictionary&#xff09;的初识 1. …...

火山引擎“奇袭”阿里云

图片&#xff5c;电影《美国队长3》剧照 ©自象限原创 作者丨程心 编辑丨罗辑 大模型价格战&#xff0c;已经不是什么新闻。 从OpenAI发布GPT-4o&#xff0c;将API价格下调50%&#xff0c;并宣布面向普通用户免费开始&#xff0c;就标志着大模型的竞争从性能进入到了成本…...

牛客网刷题 | BC94 反向输出一个四位数

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 将一个四位数&…...

记一次MySQL执行修改语句超时问题

异常问题 原因分析 这个问题发生在开发环境&#xff0c;怀疑是提交事务时终止项目运行&#xff0c;没有提交该事务&#xff0c;造成死锁 调试该事务时时间太长&#xff0c;为什么说有这个原因呢&#xff0c;因为通过查找日志显示 The client was disconnected by the server …...

linux fork()函数调用原理

在Linux中,fork函数用于创建一个新的进程,该进程是调用进程的子进程。fork函数的实现涉及用户态和内核态之间的交互。下面我将详细说明fork函数在代码流程中的原理和用户态与内核态的交互过程。 用户态调用fork函数: 用户程序调用fork函数,该函数是libc库提供的一个封装函数…...

【电控笔记5.9】编码器脉冲计算速度MT法

总结 编码器的脉冲计算速度可以使用多种方法,其中一种常用的方法是“MT法” (Measuring Time Method),即测量时间法。该方法通过测量编码器脉冲间的时间来计算速度。这种方法在高精度速度测量中非常有效,特别是在速度较低时。 MT法计算速度的基本原理 MT法的基本原理是通过…...

go-zero 实战(4)

中间件 在 userapi 项目中引入中间件。go项目中的中间可以处理请求之前和之后的逻辑。 1. 在 userapi/internal目录先创建 middlewares目录&#xff0c;并创建 user.go文件 package middlewaresimport ("github.com/zeromicro/go-zero/core/logx""net/http&q…...

go语言泛型Generic最佳实践 --- slices包

在go的内置包slices中&#xff0c; 所有的函数函数都使用了泛型&#xff0c; 各种各样的泛型&#xff0c; 可以说这个包绝对是go语言泛型学习的最佳实践之一&#xff01; 来&#xff0c;先来瞄一眼&#xff0c;看看这个slices包里面的函数原型定义&#xff1a; func BinarySe…...

【神经网络结构可视化】使用 Visualkeras 可视化 Keras / TensorFlow 神经网络结构

文章目录 Visualkeras介绍下载安装代码示例1、导入必要的库2、创建VGG16神经网络模型3、可视化神经网络结构4、完整代码5、使用教程 可视化自己创建的神经网络结构1、导入要的库2、创建自己的神经网络模型3、可视化神经网络结构图4、完整代码 Visualkeras介绍 Visualkeras是一…...

nvm安装nodejs/npm/nvm笔记

1 安装nvm, 指定路径nvm路径&#xff1a; D:\Program_Files\nvm\nvm指定路径nodejs 路径&#xff1a; D:\Program_Files\nvm\nodejs 2 进入nvm安装路径找到settings.xml文件,追加2行&#xff0c;设置镜像 node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: ht…...

微信小程序源码-基于Java后端的小区租拼车管理信息系统毕业设计(附源码+演示录像+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设…...

嵌入式进阶——LED呼吸灯(PWM)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 PWM基础概念STC8H芯片PWMA应用PWM配置详解占空比 PWM基础概念 PWM全称是脉宽调制&#xff08;Pulse Width Modulation&#xff09…...

一文读懂:http免费升级https

背景&#xff1a; 随着现在全民网络安全意识的日益提升&#xff0c;各个网站需要实现的https数量也随之提升&#xff0c;那么如何将原本网站的http访问方式升级为https呢&#xff1f; 该内容为如何免费将网站的http访问升级为https访问 论https的加密逻辑&#xff1a; 步骤 …...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...