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

Queuing 表(buffer表)的优化实践 | OceanBase 性能优化实践

案例问题描述

该案例来自一个金融行业客户的问题:他们发现某个应用对一个数据量相对较小的表(仅包含数千条记录)访问时,频繁遇到性能下降的情况。为解决此问题,客户向我们求助进行分析。我们发现这张表有频繁的批量插入与删除操作,起初,性能基本正常,但不久后性能就会出现了下降。为深入探究原因,我们通过该应用的 sql_audit 审计日志,进行进一步的分析。

问题复现

1679899488

SQL_AUDIT审计日志分析

1679899550

查询结果仅有2行数据,但访问存储路径很长,查询耗时13秒

EXECUTE_TIME: 13130625 #执行时间13秒

RETURN_ROWS: 2 #查询结果集大小

MEMSTORE_READ_ROW_COUNT: 472142 #OceanBase的内存结构读取的行数,从内存中读取了47万行

SSSTORE_READ_ROW_COUNT: 501954 #OceanBase的基线数据读取行,读取了50万条;

DATA_BLOCK_READ_CNT: 35963

DATA_BLOCK_CACHE_HIT: 21565

通过对业务场景的梳理和审计日志分析,可以初步判断,应用遇到了OB的 Queuing 表的问题,Queuing表(又称buffer表) 意为业务上"像使用 buffer一样使用一张表",即全表数据有大比例的更新或者增删。该场景具有以下特点:

  • 直接现象:表行数不大,但查询很慢
    buffer表效应的一个明显特征就是数据量很小的表(例如几千行),查询起来却非常慢。这是因为对于buffer表来说,查询的SQL在内核处理时,实际需要扫描的行数量可能远大于这个量级(可能是几百到上千万)。默认设置下,一张表中删除的行在 OB 每日合并前并不是真的删除,而只是在内存里打了个删除标记,OB major freeze/merge期间才会真正处理为删除。
  • 触发条件:表数据频繁大比例更新
    当表中大量插入的同时大量连续删除(或者大量更新,因为 OB 更新的本质也是 delete+insert )时,一张表看起来只有几千行数据,但实际上可能已经发生了几百万的插入和删除操作。
  • 产生场景
    • 业务逻辑有大量的插入、删除操作。
    • 业务代码只有插入,但是删除历史数据时,出现大量插入、删除
    • OMS数据同步Replace操作,导致buffer表
  • 问题原因:执行计划跳变,全表扫描耗时翻倍
    这种 "mark for delete" 的处理方式, 是采用了 LSM tree 架构的存储引擎的共同问题。而且因为buffer表的删除会在合并期间处理为真正的删除,而OceanBase在合并期间会收集统计信息,更新执行计划,此时部分表的数据量因为很少,OceanBase的CBO优化器可能根据代价计算而为某些SQL生成全表扫描的计划。这个执行计划在白天随着业务访问不断增加,表中的实际数据量不断加大,SQL性能会出现较大滑坡。

应急处理方案

Buffer表出现时多数情况下系统已经运行在线上,此时需要的是快速止血,常见处理方式如下:

  1. 对于存在可用索引,但OB优化器计划生成为全表扫描的场景。需要进行执行计划binding来固定计划。
  2. 如果sql查询的主要过滤字段无可用索引,此时推荐在线创建可用索引并绑定该计划。
  3. 如果业务场景暂时无法创建索引,或者执行的SQL多为范围扫描,此时可根据业务场景需要决定是否手动【触发合并】,将删除或更新的数据版本进行清理,降低全表扫描的数据量,提升速度。

注:Buffer表最快、最有效的手段还是通过索引来解决, 如果无法快速定位到有效索引,需要合并,合并一般都比较慢。 因此在合并的同时,为了尽快恢复DB, 可以有以下两个补充手段:

  • 扩容(尽可能大的规格)。
  • 对问题SQL限流(尽可能小的流量,甚至限停)。

Buffer表最有效的防止异常手段还是在事前,面对Buffer表的场景,把控SQL质量。 

历史数据删除时,需要评估是否有触发buffer表风险的SQL,如果SQL有风险,禁止做历史数据删除。 比如如下SQL:

  • Limit从大表取一条数据: select * from table_name limit 1; 
  • 全表扫描: select * from table_name;
  • 未全表扫,但执行计划不明确,走错风险大, 复杂SQL

OceanBase对Queuing表的优化

OceanBase为了优化buffer表效应,在memtable和sstable两个层面,对表数据连续删除的"空洞"设定了一个阈值(如256行),当这些空洞被查询扫描过一次时,存储层就会在上面打上"可跳过"的标记。这样就能使相同SQL下次再查询时,可以直接跳过这些无需扫描的行,实现快速查询。

默认场景下,当OB在转储/合并发生冻结的瞬间,这些空洞的range打标会失效,必须依赖下一次"成功的慢查询(全表扫描)"才能够将标记再次打上去。所以多数情况下,如果用户对buffer表的sql的执行计划创建合适的索引并且进行了执行计划绑定,后面即使不做其他干预,经历一次超长耗时的请求,后面即可恢复正常。

但是这些方法均为应急止血方案,从2.2.7版本开始,OceanBase引入了buffer minor merge设计,实现对queuing表的特殊转储机制,彻底解决无效扫描问题。对于设计阶段已经明确的Queuing表场景,推荐开启该特性作为长期解决方案

alter table user_table table_mode = 'queuing';

关于Queuing表转储

OceanBase的自适应的buffer表转储策略,由存储层在每次转储时根据转储的统计信息来自主判断是否需要对该表采用buffer表转储策略,当发现一个表存在类似buffer表行为时,接下来会尝试对这个表做buffer minor merge的调度, 对这个表基于Major SSTable和最新的增量数据以当前的读快照时间生成一个Buf Minor SSTable, 这次Compaction动作会消除掉增量数据里的所有Delete标记, 后续查询基于新生成的Buf Minor SSTable就可以避免原有的大量无效扫描动作。

客户的解决方案

1、根据业务SQL条件添加了联合索引 KEY `idx_status_gmtmodify` (`status`, `gmt_modify`) ,更好的选择度,减少回表数据,即使频繁更新,扫描存储的量级也不大,sql能在ms级响应.

2、给业务表增加queuing 标签,加快转储

#queuing打标
ALTER TABLE table_name TABLE_MODE = 'queuing'; 
手动转储操作
# 系统租户操作是全局
alter system minor freeze;
# 全部转储
ALTER SYSTEM MINOR FREEZE TENANT =ALL;
# 系统租户
ALTER SYSTEM MINOR FREEZE tenant = sys;
# 用户租户
ALTER SYSTEM MINOR FREEZE TENANT =tenant1;
# zone级
ALTER SYSTEM MINOR FREEZE ZONE = zone1;
#server级
ALTER SYSTEM MINOR FREEZE SERVER = ('10.10.10.10:2882');
# 分区级
ALTER SYSTEM MINOR FREEZE tenant = t1 tablet_id = 60000;# 普通租户触发转储,只能是自己租户的
# 本租户级
ALTER SYSTEM MINOR FREEZE;

相关文章:

Queuing 表(buffer表)的优化实践 | OceanBase 性能优化实践

案例问题描述 该案例来自一个金融行业客户的问题:他们发现某个应用对一个数据量相对较小的表(仅包含数千条记录)访问时,频繁遇到性能下降的情况。为解决此问题,客户向我们求助进行分析。我们发现这张表有频繁的批量插…...

./mysqld: error while loading shared libraries: libaio.so.1: cannot open sha

mysql:5.6 使用离线方式安装:rpm -ivh --nodeps mysql* ,执行 systemctl start mysqld.service发现启动不了,通过vi /var/log/mysql.log看到如下关键字:libraries: libaio.so.1,之前也是按照网上帖子各种修改都没有解决…...

Qt主线程把数据发给子线程,主线程会阻塞吗

演示&#xff1a; #include <QCoreApplication> #include <QThread> #include <QObject> #include <QDebug>// 子线程类 class Worker : public QObject {Q_OBJECT public slots:void processData(int data) {qDebug() << "Processing dat…...

前后端、网关、协议方面补充

这里写目录标题 前后端接口文档简介前后端视角对于前端对于后端代码注册路由路由处理函数 关于httpGET/POST底层网络关于前端的获取 路由器网关路由器的IP简介公网IP(WAN IP)私网IP(LAN IP)无线网络IP(WIFI IP)查询路由器私网IP路由器公网IP LAN口与WIFI简介基本原理 手动配置电…...

如何在Mac上切换到JDK 17开发环境

在本文中&#xff0c;我将为您介绍如何在Mac上切换到JDK 17&#xff0c;包括下载和安装JDK 17、设置环境变量、在IntelliJ IDEA中配置项目、修改Maven编译配置&#xff0c;并最终使用mvn clean install重新编译项目。通过这个流程&#xff0c;您可以顺利地将开发环境升级到JDK …...

深入探索 TypeScript:从基础到高级特性

深入探索 TypeScript&#xff1a;从基础到高级特性 一、引言 在现代软件开发领域&#xff0c;TypeScript 已经成为了一种极具影响力的编程语言。它基于 JavaScript&#xff0c;并为其添加了强大的静态类型系统&#xff0c;使得代码在开发阶段就能进行更严格的类型检查&#x…...

Leetcode:118. 杨辉三角——Java数学法求解

题目——Leetcode:118. 杨辉三角 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRow…...

SHELL脚本(Linux)

声明 学习视频来自 B 站UP主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 ✍&#x1f3fb;作者简介&#xff1a;致…...

单元测试、集成测试、系统测试、验收测试、压力测试、性能测试、安全性测试、兼容性测试、回归测试(超详细的分类介绍及教学)

目录 1.单元测试 实现单元测试的方法&#xff1a; 注意事项&#xff1a; 2.集成测试 需注意事项&#xff1a; 实现集成测试的方法&#xff1a; 如何实现高效且可靠的集成测试&#xff1a; 3.系统测试 实现系统测试的方法: 须知注意事项&#xff1a; 4.验收测试 实现验…...

低代码集成多方API的简单实现

在现代软件开发中&#xff0c;集成多个API服务提供商已成为常见需求。然而&#xff0c;不同的API认证机制和数据格式使得集成过程变得复杂且耗时。为了应对这些挑战&#xff0c;本文将介绍一种低代码解决方案&#xff0c;通过配置化管理和简化的代码逻辑&#xff0c;帮助开发者…...

【测试框架篇】单元测试框架pytest(1):环境安装和配置

一、pytest简介 Pytest是Python的一种单元测试框架&#xff0c;与Python自带的unittest测试框架类似&#xff0c;但是比 unittest框架使用起来更简洁&#xff0c;效率更高。 二、pytest特点 Pytest是一个非常成熟的Python测试框架,主要特点有以下几点&#xff1a; 非常容易…...

Python数据分析NumPy和pandas(二十九、其他Python可视化工具)

与其他开源工具一样&#xff0c;在 Python 中创建图形有很多选项&#xff08;太多了&#xff0c;无法一一列举&#xff09;。自 2010 年以来&#xff0c;主要开发工作集中在创建用于在 Web 上发布交互式图形上。例如&#xff1a; Altair、Bokeh 和 Plotly 等工具&#xff0c;可…...

Unity中HDRP设置抗锯齿

一、以前抗锯齿的设置方式 【Edit】——>【Project Settings】——>【Quality】——>【Anti-aliasing】 二、HDRP项目中抗锯齿的设置方式 在Hierarchy中——>找到Camera对象——>在Inspector面板上——>【Camera组件】——>【Rendering】——>【Pos…...

Spring Boot实现文件上传与OSS集成:从基础到应用

目录 前言1. 文件上传的基础实现1.1 前端文件上传请求1.2 后端文件接收与保存 2. 集成第三方OSS服务2.1 准备工作2.2 编写OSS集成代码2.3 修改Controller实现文件上传至OSS 3. 文件上传的扩展&#xff1a;多文件上传与权限控制结语 前言 随着互联网应用的快速发展&#xff0c;…...

Python学习26天

集合 # 定义集合 num {1, 2, 3, 4, 5} print(f"num&#xff1a;{num}\nnum数据类型为&#xff1a;{type(num)}") # 求集合中元素个数 print(f"num中元素个数为&#xff1a;{len(num)}") # 增加集合中的元素 num.add(6) print(num) # {1,2,3,4,5,6} # 删除…...

linux startup.sh shutdown.sh (kkFileView)

linux启动脚本和关闭脚本startup.sh shutdown.sh &#xff08;kkFileView&#xff09; startup.sh DIR_HOME("/opt/openoffice.org3" "/opt/libreoffice" "/opt/libreoffice6.1" "/opt/libreoffice7.0" "/opt/libreoffice7.1&q…...

[MySQL]隐式类型转换

安全等号 <> 如果有参数为NULL&#xff0c;则除了相等比较运算符()&#xff0c;比较的结果为null。对于 nullnull&#xff0c;结果为true。 在select语句中&#xff0c;使用 时&#xff0c;结果不会包含值为 null 的记录&#xff0c;但如果使用安全等号 <> 来…...

面经总结1

文章目录 如何保证批量请求失败&#xff0c;只弹出一个toast1使用计数器&#xff1a;2使用标志变量&#xff1a; 如何减少项目里的if-else1使用多态2使用策略模式3使用字典映射4使用状态模式 babel-runtime 作用是啥如何实现 PDF 预览和下载1浏览器内置PDF阅读器2使用PDF.js库3…...

Oracle19C AWR报告分析之Instance Efficiency Percentages (Target 100%)

Oracle19C AWR报告分析之Instance Efficiency Percentages 一、分析数据二、详细分析2.1 Instance Efficiency Percentages (Target 100%)各项指标及其解释2.2 分析和总结 一、分析数据 二、详细分析 在 Oracle AWR (Automatic Workload Repository) 报告中&#xff0c;每个性能…...

数据结构--数组

一.线性和非线性 线性&#xff1a;除首尾外只有一个唯一的前驱和后继。eg&#xff1a;数组&#xff0c;链表等。 非线性&#xff1a;不是线性的就是非线性。 二.数组是什么&#xff1f; 数组是一个固定长度的存储相同数据类型的数据结构&#xff0c;数组中的元素被存储在一…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

MVC 数据库

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

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

Python第七周作业

Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt&#xff0c;并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径&#xff0c;并创建logs目录&#xff08;若不存在&#xff09; 3.递归遍历目录data&#xff0c;输出所有.csv文件的路径…...

MLP实战二:MLP 实现图像数字多分类

任务 实战&#xff08;二&#xff09;&#xff1a;MLP 实现图像多分类 基于 mnist 数据集&#xff0c;建立 mlp 模型&#xff0c;实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入&#xff0c;可视化图形数字&#xff1b; 2、完成数据预处理&#xff1a;图像数据维度转换与…...