暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

开讲了O | OBCP高分上岸第2课,学学SQL引擎与调优

OceanBase 数据库的存储引擎基于 LSM-Tree 结构,LSM-Tree 是日志结构的一个归并函数,核心特点是利用顺序写来提高写性能。


它将某个对象(Partition)中的数据按照“key-value”形式在磁盘上有序存储到 SSTable 中。数据更新先记录在 MemStore 中的 MemTable 里,然后再合并(Merge)到底层的 SSTable 里。SSTable 和 MemTable 之间可以有多级中间数据,同样以 key-value 形式保存在磁盘上,逐级向下合并。


图片


OceanBase MemTable 采用双索引结构,即 B+ 树索引和哈希索引。B+ 树索引能够更好地支持范围查找,而哈希索引是针对单行查找的一种优化。每次执行事务时,MemTable 会自动维护 B+ 树索引与哈希索引之间的一致性。如果要读取更老的历史快照,只需要顺着内存中的反向指针往前回溯即可,相当于在内存中执行数据库 Undo 操作。


图片

基于 LSM Tree 的实践:合并


1、合并触发方式


合并的触发方式有三种,分别是定时合并、自动合并和手动合并。


定时合并由 major_freeze_duty_time 参数控制定时合并时间,可以修改参数控制合并时间。


alter system set major_freeze_duty_time='02:00';


当租户的 MemStore 内存使用率达到 freeze_trigger_percentage 参数的值,并且转储的次数已经达到了 minor_freeze_times 参数的值,会自动触发合并。


在" root@sys "用户下,可以通过以下命令发起手动合并(忽略当前 MemStore 的使用率):


alter system major freeze;


合并发起以后,可以通过以下两种命令,在 OceanBase 数据库里查看合并状态:


select * from __all_zone;


select * from __all_zone where name = 'merge_status';


2、合并的过程


OceanBase 中最简单的 LSM-Tree 只有 C0 层(MemTable)和 C1 层(SSTable)。两层数据的合并过程如下:


① 将所有 observer 上的 MemTable 数据做大版本冻结(Major Freeze),其余内存作为新的 MemTable 继续使用;


② 将冻结后的 MemTable 数据合并(Merge)到 SSTable 中,形成新的 SSTable,并覆盖旧的 SSTable;


③ 合并完成后,冻结的 MemTable 内存才可以被清空并重新使用。


图片


图片

基于 LSM-Tree 的实践:转储


当 MemTable 的大小超过一定阈值时,就需要将 MemTable 中的数据转存到 SSTable 中以释放内存,我们将这一过程称之为转储。转储解决了合并操作引发的一系列问题,诸如:



  • 资源消耗高,对在线业务性能影响较大


  • 单个租户 MemStore 使用率高会触发集群级合并,其它租户成为受害者


  • 合并耗时长,MemStore 内存释放不及时,容易造成 MemStore 满而数据写入失败的情况



1、分层转储


为了优化转储越来越慢的问题,引入了“分层转储”机制。分层转储采用错层 compaction 策略,新增 L0 层,被冻结的 MemTable 会直接 flush 为 Mini SSTable,可同时存在多个 Mini SSTable。L0 层是 size-tiered Compaction,内部继续根据不同场景分裂多层,L1 和 L2 层基于宏块粒度来维持 Leveled compaction。


每次转储会将 MemTable 数据与前一次转储的数据合并(Merge),转储文件最终会合并到 SSTable 中。


图片


2、转储的触发方式


转储有两种触发方式:自动触发与手动触发。


当一个租户的 MemTable 内存的使用量达到 memstore_limit_percentage * freeze_trigger_percentage 所限制使用的值时,就会自动触发冻结(转储的前置动作),然后系统内部再调度转储。


也可以通过以下的运维命令手动触发转储。


ALTER SYSTEM MINOR FREEZE[{TENANT[=] (‘tt1' [, 'tt2'...]) | PARTITION_ID [=] 'partidx%partcount@tableid‘}]   [SERVER [=] ('ip:port' [, 'ip:port'...])];
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论