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飞控中,都有记录我们整个飞行过程 ...
随机推荐
- mysql学习(1)-linux操作系统源码包安装
背景: CentOS 6.4下通过yum安装的MySQL是5.1版的,比较老,所以就想通过源代码安装高版本的5.6.22. 正文: 一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server ...
- Loaders
Android3.0之后引入了加载器,支持轻松在Activity和Fragment中异步加载数据.加载器具有以下特点: 1.可用于任何Activity和Fragment 2.支持异步加载数据 3.监控 ...
- eclipse无法创建Server
报错:Cannot create a server using the selected type1.退出eclipse 2.到[工程目录下]/.metadata/.plugins/org.eclip ...
- java socket 网络编程常见异常
1.java.net.SocketTimeoutException 这个异常比较常见,socket超时.一般有2个地方会抛出这个,一个是connect的时候,这个超时参数由connect(Socket ...
- flask-admin章节一:使用chartkick画报表
一般中小型WEB整体来看逻辑比较简单些,一般都是基于数据库的增删改查.不过通过数据库查询到的记录直接展示给用户不是很直观,大家其实蛮期待有一个报表 直接展示他们期待的内容. 这块就涉及到数据的提取和展 ...
- SQL 列转行的实现
--列转行,逗号拼接指定列的值Oracle中写法:select wmsys.wm_concat(Field1) from TableASQL Server中写法:SELECT STUFF(( SELE ...
- js(ext)中,设置[!!异步!!]上传的简单进度条
代码在updateHmis的历史记录中,此处存档 handler : function() { //显示进度条 Ext.MessageBox.wait('数据上传中...','提示'); //上传数据 ...
- 解决Nginx不支持pathinfo的问题
server { listen 80; server_name www.zq27.cc zq27.cc; root /data/wwwroot/www.zq27.cc/; access_log off ...
- Linux 下curl模拟Http 的get or post请求
一.get请求 curl "http://www.baidu.com" 如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地 curl -i "http:// ...
- CSS布局技巧 -- 内凹圆角
圆角,相信每一个了解CSS属性的都知道,通过border-radius实现圆角(外凸圆角),但是如果需要实现内凹圆角怎么办呢?比如四角内凹的元素,比如如下所示这样的内凹圆角 对于这种问题,很多人的反应 ...