OceanBase 应用实践:如何处理数据空洞,降低存储空间

news/2024/11/8 21:16:32 标签: oceanbase, 分布式数据库, 最佳实践

问题描述

某保险行业客户的核心系统,从Oracle 迁移到OceanBase之后,发现数据存储空间出现膨胀问题,数据空间 datasize=9857715.48M,实际存储占用空间17790702.00M。根据 required_mb - data_mb 值判断,数据空洞较为严重。因此客户提出需求,要降低存储空间。

上图查询sql参考:空洞情况检查方法

原因分析

OceanBase 存储出现空洞的原因:OceanBase的数据文件SSTABLE按照主键顺序进行存储,如果业务数据插入比较离散,期间有合并时,2M宏块出现分裂会导致数据空洞率提升,进而导致存储空间大于数据数据空间, 这种现象多见于业务主键非递增插入的场景。

解决方法

对空洞较大的表强制执行全量合并

强制执行全量合并,不执行渐进合并。

  • 对于新建表:set default_progressive_merge_num=1。
  • 对于现存表:ALTER TABLE $table SET progressive_merge_num=1; 这样把需要的表设置上,再进行合并。

注意:全量合并会消耗大量资源,需要设置完之后再设置回0。

progressive_merge_num值说明:

  • 0 :表示执行渐进合并,且渐进合并的次数为 100。
  • 1:表示强制执行全量合并,不执行渐进合并。
  • 大于 1 :表示发生 Schema 变更时按照指定轮次做渐进合并。

空洞情况检查方法

select avd.database_name,
avt.tenant_id,
Case avt.table_type
When 3 Then
'TABLE'
When 5 Then
'INDEX'
Else
''
End As segment_type,
Case avt.table_type
When 3 Then
Sum(avmt.row_count)
Else
''
End As row_count,
round(Sum(avmt.data_size) / 1024 / 1024, 2) As data_mb,
round(Sum(avmt.required_size) / 1024 / 1024, 2) As required_mb
From __all_virtual_table avt
Inner Join __all_virtual_partition_table avmt
On avt.tenant_id = avmt.tenant_id
And avt.table_id = avmt.table_id
Inner Join __all_virtual_database avd
On avt.database_id = avd.database_id
And avt.tenant_id = avd.tenant_id
Where avmt.role = 1
And table_type In (3, 5)
Group By avd.database_name, table_type, avt.tenant_id
Order By database_name, table_type;

/*
select table_type, index_status, index_type, part_level from __all_virtual
_table;
table_type: 系统表(0),系统视图(1),虚拟表(2),用户表(3),用户视图(4),索引表(5)
index_status: 不可用(1),可用(2)
index_type: 局部普通索引(1),局部唯一索引(2),全局普通索引(3),全局唯一索引(4),主键索
引(5)
part_level: 不分区(0),一级分区(1),二级分区(2)
__all_virtual_meta_table 是基线数据
__all_virtual_storage_stat 是基线加转储数据
*/

合并管理概述

合并操作(Major Compaction)是将动静态数据做归并,会比较费时。当转储产生的增量数据积累到一定程度时,通过 Major Freeze 实现大版本的合并。合并与转储的最大区别在于,合并是集群上所有的分区在一个统一的快照点和全局静态数据进行合并的行为,是一个全局的操作,最终形成一个全局快照。

合并分类

按照合并数据量,合并可以分为:

  • 全量合并:将静态数据全部读出并和动态数据合并为最终的静态数据。合并时间长,耗费 IO 和 CPU。
  • 增量合并:仅仅合并被修改过的宏块,没有改变的宏块进行复用。增量合并极大地减少了合并的工作量,是 OceanBase 数据库目前默认的合并算法。
  • 渐进合并:每次全量合并一部分,若干轮次后整体数据被重写一遍。
  • 并行合并:将数据划分到不同线程中并行做合并。

全量合并与渐进合并

渐近合并是什么

OceanBase在设计之初就考虑到了Online DDL的需求,目前在OceanBase中加列、减列、建索引等DDL操作都是不阻塞读写的,也不会影响到多副本间的paxos同步。加减列的DDL变更是实时生效的,OB将对存储数据的变更延后到每日合并的时候来做。和Mysql一样,对于某些DDL操作如加减列等,OB是需要将所有数据重写一遍的,如果在一次每日合并过程中完成对所有数据的重写,那么对存储空间和合并时间都会是一个比较大的考验。为了解决这个问题,OB引入了渐进合并,既然一次合并做代价太大,那就搞多次。OB会将DDL变更造成的数据重写分散到多次每日合并中去做,假设把渐进轮次设置为60,那么一次合并就只会重写60分之一的数据,在60轮合并过后,数据就被整体重写了一遍。渐进合并减轻了DBA做DDL操作的负担,同时也使得DDL变更更加平滑。

渐近合并的参数

schema中的progressive_merge_num属性来决定渐近的轮次,假设progressive_merge_num=5,表示5轮合并重写完major sstable。 schema中的progressive_merge_round表示本次合并所处的渐近合并轮次

如何指定全量合并

当progressive_merge_num=0或1时,如果发生了DDL对于存储层的变更,会在一轮合并中重写掉major sstable

全量合并与非全量合并

全量合并:所有宏块不重用,全部打开重写
非全量合并:宏块会重用,只打开有数据变更的宏块
当执行渐近合并时,只有本次渐近轮次相关的宏块会做全量合并,其他部分做非全量合并


http://www.niftyadmin.cn/n/5744447.html

相关文章

全面升级的“新清影”,给AI生成视频带来了哪些新玩法?

就在刚刚,智谱清言App上线了“新清影”,同时对外开源了智谱最新的图生视频模型CogVideoX v1.5。 3个多月前的智谱Open Day上,视频创作智能体清影正式在智谱清言上线,只需30秒即可生成时长6秒、1440x960清晰度的高精视频&#xff…

“类模板”

文章目录 一. 类模板的引入二. 类模板的格式三. 类模板的实例化注意点 一. 类模板的引入 我们曾经学习过&#xff1a;typedef STDataTy int;或者是using STDataTy int;&#xff0c;这个的作用是将使用STDataTy 的地方替换成int #include<stdio.h> using STDataTy int…

React 入门课程 - 使用CDN编程React

1. 第一个React 注意&#xff1a;在vscode里&#xff0c;使用Live Server来运行html文件。 index.html <html><head><link rel"stylesheet" href"index.css"><script crossorigin src"https://unpkg.com/react17/umd/react.de…

P11229 [CSP-J 2024] 小木棍

[CSP-J 2024] 小木棍 题目描述 小 S 喜欢收集小木棍。在收集了 n n n 根长度相等的小木棍之后&#xff0c;他闲来无事&#xff0c;便用它们拼起了数字。用小木棍拼每种数字的方法如下图所示。 现在小 S 希望拼出一个正整数&#xff0c;满足如下条件&#xff1a; 拼出这个数…

Transformer和BERT的区别

Transformer和BERT的区别比较表&#xff1a; 两者的位置编码&#xff1a; 为什么要对位置进行编码&#xff1f; Attention提取特征的时候&#xff0c;可以获取全局每个词对之间的关系&#xff0c;但是并没有显式保留时序信息&#xff0c;或者说位置信息。就算打乱序列中token…

vue 3:监听器

目录 1. 基本概念 2. 侦听数据源类型 1. 监听getter函数 2. 监听 ref 或 reactive 的引用 3. 多个来源组成的数组 4. 避免直接传递值&#xff01;&#xff01;&#xff01; 3. 深层侦听器 4. 立即回调的侦听器 5. 一次性侦听器 6. watchEffect() 7. 暂停、恢复和停止…

页面、组件、应用、生命周期(微信小程序)

文章目录 页面生命周期函数组件生命周期函数应用&#xff08;App&#xff09;生命周期函数页面与组件生命周期的执行顺序注意事项 在微信小程序中&#xff0c;生命周期函数是指页面或组件在不同阶段会被自动调用的特定函数。这些函数可以帮助开发者在适当的时机完成特定的初始化…

穿销程序之如何写停止程序

这里的停止依旧是用停止指令来进行停止的&#xff0c;只用停止开关是无法进行长时间控制的&#xff0c;停止开关是瞬时控制。