myrocks记录格式分析
概况
rocksdb作为KV存储引擎,那么myrocks记录最终会以kv的形式存储在rocksdb中。MySQL中的表一般由若干索引组成, 在innodb存储引擎中,每个索引对应一颗B树,而在rocksdb存储引擎中,索引对应于rocksdb中一段连续范围的数据。
具体来说,这个范围是此索引id和id+1之间的所有数据。如果表的所有索引都在一个column family, 那表的这些索引数据在物理上基本是连续的。
可以参考之前文章中的图示
myrocks记录格式
myrocks以索引为单位,将表的所有索引分别存储在rocksdb中。
根据索引的类型,myrocks记录的格式有所不同。下面以下表不同索引类型来分别介绍
CREATE TABLE t1(a INT,
b VARCHAR(),
c char(),
d int,
pk INT AUTO_INCREMENT,
PRIMARY KEY(pk) comment 'cf_1',
unique key idx2(b) comment 'cf_2')
engine= rocksdb; INSERT INTO t1 (pk,a,b,c) VALUES (,,'bbbbbbbbbb','c');
主键
主键索引记录kv结构如下key: index_id, M(pk)
value: unpack_info, NULL-bitmap,b,c,dkey由索引id和主键组成。 index_id是索引的唯一标识占用4个字节,M(pk) 表示pk转化后的数据,此转化后的数据可以直接用于memcmp比较
rocksdb数据都是根据key排序的,为了便于比较,不同类型数据都会经过一些转化,转化后可以直接用于memcmp比较。
关于memcmp转化,下一节会详细介绍value存储unpack_info和非主键外的其他字段数据, Null-bitmap标识哪些字段为空。
unpace_info存储将M(pk)逆转化为pk的信息,如果不需要额外转换信息则unpace_info为null,此例中pk为int类型,不需要额外信息unpace_info为null二级索引 idx2
二级索引记录kv结构如下key: index_id,NULL-byte, M(b),M(pk)
value: unpack_infokey由index_id,二级索引键和主键组成, 其中NULL-byte表示b是否为空。pk为主键非空,所以不需要NULL-byte
value只有unpack_info,表示 M(b),M(pk)逆转化信息,如果不需要额外转换信息则unpace_info为null。此例中b为varchar类型,需要额外信息unpace_info不为null唯一索引和普通二级索引存储方式没有区别
联合索引每多一个字段会在字段前增加一个NULL-byte,来表示此字段是否为空
Memcomparable format
rocksdb为了比较方便,将key字段转化为可以直接memcmp比较的形式。所以MyRocks 一般建议使用sensitive collations (latin1_bin, utf8_bin, binary).
这样可以避免转化的开销。
- 整形
整形转化比较简单,但对于有符号类型需要特殊处理,如果直接存储会导致比较是负数比正数大。
这里对有符号类型处理的方式是将符号位反转,这样正数就比负数大了,
关键代码段如下
Field_long::make_sort_key: if (!table->s->db_low_byte_first)
{
if (unsigned_flag)
to[] = ptr[];
else
to[] = (char) (ptr[] ^ ); /* Revers signbit */
to[] = ptr[];
to[] = ptr[];
to[] = ptr[];
}
- 字符型
char类型直接补空格
varchar类型为了节省空间处理起来就复杂多了
以源码中的注释为例
const int VARCHAR_CMP_LESS_THAN_SPACES = ;
const int VARCHAR_CMP_EQUAL_TO_SPACES = ;
const int VARCHAR_CMP_GREATER_THAN_SPACES = ; Example: if fpi->m_segment_size=, and the collation is latin1_bin: 'abcd\0' => [ 'abcd' <VARCHAR_CMP_LESS> ]['\0 ' <VARCHAR_CMP_EQUAL> ]
'abcd' => [ 'abcd' <VARCHAR_CMP_EQUAL>]
'abcd ' => [ 'abcd' <VARCHAR_CMP_EQUAL>]
'abcdZZZZ' => [ 'abcd' <VARCHAR_CMP_GREATER>][ 'ZZZZ' <VARCHAR_CMP_EQUAL>]
字符串以m_segment_size分段存储,每段前m_segment_size-1个字符是内容,最后一个字符表示和空格比较,VARCHAR_CMP_EQUAL同时也表示字符串结束
例子中m_segment_size为5,实际实现上值为9
这里unpace_info会比较复杂,字符串collation不同unpace_info也不同,unpace_info需要保存collation之间的转换映射关系,
具体可以查看函数(rdb_init_collation_mapping)
rocksdb内部记录格式
前面为我们看到的是进入rocksdb之前记录的kv结构形式,实际上数据存储到rocksdb后key还要进一步封装
进入rocksdb之前的key称为userkey, rocksdb内部称为internalkey
internalkey=| User key (string) | sequence number ( bytes) | value type ( byte) |
其中sequence number 是记录序列号,每个记录sequence number根据是以记录进入rocksdb先后顺序递增的。
sequence number是实现rocksdb事务处理的关键,这个下次讨论。
value type是记录的类型,put, merge,delete等
示例
以实例来说明比较直观,还是上面介绍的那个表,插入一条记录,来看看记录的具体结构
INSERT INTO t1 (pk,a,b,c) VALUES (,,'bbbbbbbbbb','c');
查看主键index_id为260,二级索引index_id为261
select * from INFORMATION_SCHEMA.ROCKSDB_DDL where TABLE_NAME='t1';
TABLE_SCHEMA TABLE_NAME PARTITION_NAME INDEX_NAME COLUMN_FAMILY INDEX_NUMBER INDEX_TYPE KV_FORMAT_VERSION CF
test t1 NULL PRIMARY cf_1
test t1 NULL idx2 cf_2
主键记录
- key
- value
二级索引记录
- key
- value
这里包字段b的空格信息和collation转化映射关系。比较复杂,不详细展开,有兴趣的可以查看函数(rdb_init_collation_mapping)
myrocks记录格式分析的更多相关文章
- myrocks复制中断问题排查
背景 mysql可以支持多种不同的存储引擎,innodb由于其高效的读写性能,并且支持事务特性,使得它成为mysql存储引擎的代名词,使用非常广泛.随着SSD逐渐普及,硬件存储成本越来越高,面向写优化 ...
- Rocksdb引擎记录格式
Rocksdb是一个kv引擎,由facebook团队基于levelDB改进而来,Rocksdb采用LSM-tree存储数据,良好的读写特性以及压缩特性使得其非常受欢迎.此外,Rocksdb引擎作为插件 ...
- Hadoop学习笔记—20.网站日志分析项目案例(一)项目介绍
网站日志分析项目案例(一)项目介绍:当前页面 网站日志分析项目案例(二)数据清洗:http://www.cnblogs.com/edisonchou/p/4458219.html 网站日志分析项目案例 ...
- Hadoop学习笔记—20.网站日志分析项目案例(二)数据清洗
网站日志分析项目案例(一)项目介绍:http://www.cnblogs.com/edisonchou/p/4449082.html 网站日志分析项目案例(二)数据清洗:当前页面 网站日志分析项目案例 ...
- MyRocks简介
RocksDB是facebook基于LevelDB实现的,目前为facebook内部大量业务提供服务.经过facebook大量工作,将RocksDB为MySQL的一个存储引擎移植到MySQL,称之为M ...
- apache日志文件详解和实用分析命令
apache日志文件每条数据的请意义,以及一些实用日志分析命令. 一.日志分析 如果apache的安装时采用默认的配置,那么在/logs目录下就会生成两个文件,分别是access_log和error ...
- SQLite入门与分析(三)---内核概述(2)
写在前面:本节是前一节内容的后续部分,这两节都是从全局的角度SQLite内核各个模块的设计和功能.只有从全局上把握SQLite,才会更容易的理解SQLite的实现.SQLite采用了层次化,模块化的设 ...
- MyRocks DDL原理
最近一个日常实例在做DDL过程中,直接把数据库给干趴下了,问题还是比较严重的,于是赶紧排查问题,撸了下crash堆栈和alert日志,发现是在去除唯一约束的场景下,MyRocks存在一个严重的bug, ...
- APM和PIX飞控日志分析入门贴
我们在飞行中,经常会碰到各种各样的问题,经常有模友很纳闷,为什么我的飞机会这样那样的问题,为什么我的飞机会炸机,各种问题得不到答案是一件非常不爽的问题,在APM和PIX飞控中,都有记录我们整个飞行过程 ...
随机推荐
- js替换选中的文字
替换html中选中的文字 function replaceSelection() { if (window.getSelection) { var selecter = window.getSelec ...
- 选择流程—— switch if else结构
一.switch switch(表达式){ case 常量1: 语句; break; case 常量2: 语句; break; … default; 语句; } 例题:运用switch结构实现购物管理 ...
- 問題排查:类型“System.DateTime”的对象无法转换为类型“System.String”
最近在擴充資料對接工具的功能 經常會遇到這個狀況 當然還有其他同類提示,例如 int/decimal 無法轉 System.String 等等 無獨有偶 這些錯誤幾乎都是在 DataTable 轉換成 ...
- SQL存储过程删除数据库日志文件的方法
--日志文件收缩至多少M DECLARE @DBLogSise AS INT SET @DBLogSise=0 --查询出数据库对应的日志文件名称 DECLARE @strDBName AS NVAR ...
- CentOS下MySQL数据库安装
前辈们总是说,要边学边记录,要总结.所以,开始把每天学到的内容一点一点记录. 复杂的理论不懂,只会目前安装,安好后就开始玩咯! 1.在官网下载相应的rpm安装包 下载地址:http://dev.mys ...
- 云存储的那些事(2)——数据分布算法CRUSH
在分布式系统中,数据最终还是要存储到物理设备上的,ceph的底层设备抽象角色是OSD,那么数据是如何被决定放在哪块OSD上的,答案就是CRUSH算法. 关键字:CRUSH.一致性hash.ceph数据 ...
- Hibernate中的HQL查询与缓存机制
HQL:完全面向对象查询 SQL的执行顺序: 1.From 2.Where 过滤基础数据 where与having的区别:1.顺序不同 2.where过滤基础数据 3. 过滤聚合函数 3.Group ...
- IOS 支付、性能调试、IPv6兼容支持等
微信支付 支付宝支付 性能调试 IPv6兼容支持 APP引导页框架
- DDD领域驱动设计基本理论知识总结
领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...
- vue 2 滚动条加载更多数据实现
解析: 判断滚动条到底部,需要用到DOM的三个属性值,即scrollTop.clientHeight.scrollHeight. scrollTop为滚动条在Y轴上的滚动距离. clientHeigh ...