MyRocks_zh_doc

MyRocks 行记录格式

由于RocksDB是一个键值存储,MySQL结构化信息必须以简单的键值形式进行编码。 单个实例中的所有数据都存储在平面键值空间中的一个RocksDB数据库中。 表可以在多个列族之间分配。每个表都包含一个主键,可能还有一组辅助索引(键)。 每个索引都有自己唯一的ID,我们来看一个示例表以及它如何存储在RocksDB中:

create table t1 (
  a varchar(50) primary key,
  b integer,
  c varchar(75),
  d varchar(100),
  key(c),
  unique(d),
  unique(c,d),
)

Primary key主键

key: index number, M(a)
value: NULL-bitmap, b, c, d

主键将所有数据存储在表中。较低级别 键/值的键由4字节索引号后跟主键的memcomparable格式(表示为'M()')组成。
memcomparable格式允许使用简单的memcmp "C"函数比较两个值。这比从密钥解析单个字段并进行特定类型的比较要高效得多。
为了支持memcomparable格式,MyRocks限制索引列上的排序规则---仅支持二进制,latin1_bin 和 utf8_bin排序规则。

主键的值存储其余非键列。在大多数情况下,我们不会将主键列存储在那里,因为我们已将它们存储为键的一部分。
但是,如果在转换为 memcomparable表单期间丢失了任何信息,我们会存储"还原"信息(足已从memcomparable值恢复原始值的信息)
或其中的原始列值。

Secondary index (c) 二级索引

key: index number, NULL-flag, M(c), M(a)
value: empty or restore data

对于非唯一索引,我们将辅助索引键列和主键列的memcomparable形式存储为键的一部分。与主键索引类似,密钥以4字节索引号开头,
后跟辅助和主键列的memcomparable形式。如果辅助索引列可以为空,则它由一个字节标志前置。
标志值为0表示该字段为NULL,在这种情况下,M(c)是空的。主键不能为NULL,因此没有标志。

如果需要,辅助索引的值为空或包含还原数据或原始键列值。

Multi column, secondary index (c,d) 多列,二级索引

key: index number, NULL-flag, M(c), NULL-flag, M(d), M(a)
value: empty or restore data

多列索引通过一个接一个地连接其成分的可比较表示来编码。所有可空列都以NULL字节开头。
多列主键还可以一个接一个地连接memcomparable表单。主键不需要NULL字节。

如果需要,该值为空或包含还原数据或原始键列值。

Memcomparable format 无与伦比的格式

重要的是能够在不反序列化和进行类型特定比较的情况下比较密钥,可以 以memocarable方式表示MySQL数据。
有许多细微的细节可以解决问题,包括多列键,不区分大小写的排序规则,甚至更复杂的排序规则,具有可变长度列的多列行等。

对于简单的固定宽度数据类型,我们使用MySQL提供的工具。有关详细信息,请参阅MySQL代码中Field_xxx::make_sort_key方法。

    * 对于整数类型,字节切换为big-endian高位优先顺序,负值使所有位都无效,而正值则高位打开。
    * 对于浮点类型,字节切换为big-endian高位优先顺序,负值使所有位都无效,而正值则高位打开,并且指数递增。
    * 对于可变大小数据类型,它取决于数据是否被视为二进制数据(varbinary或varchar with binary collat​​ion)。
      对于二进制数据,我们将8个字节组中的数据分解为一个额外的字节,该字节表示上一节中的有效字节数。额外字节的范围可以是1到9.
      值1到8表示许多字节是重要的,并且该组是最后一组 - 值9表示所有8个字节都很重要,并且有更多数据要来。
    * 对于非二进制数据的可变大小数据类型,我们需要支持空间填充。空间填充是某些排序规则类型的一个特征,表明数据应该按空格填充到其最大长度进行排序。
      目前,所有支持的排序规则(上面处理的二进制除外)都具有空间填充特性。空间填充的memcomparable格式是将数据分成块(块的大小取决于排序规则),
      使用空格字符填充最后一次检查以进行排序。每个块后跟一个标志字节,其中有三个值之一:1表示此块后面的数据排序小于空格,2表示这是最后一个块 - 概念上意味着此后的任何数据都是空格,3表示此块后面的数据排序大于空格。

要实现不同的编码,我们必须将字符创转换成某种基本格式。例如,对于latin拉丁语编码,我们所要做的就是将所有字符转换成大写。
这样memcmp将有效地忽略大小写。要恢复原始数据,我们所要做的就是存储一个位掩码,说明哪些字符被转换为大写。这是恢复数据。
对于更复杂的排序规则,事情更棘手。我们可能会选择仅使用原始字符串作为还原数据。
任何恢复数据都将存储在值中(1字节恢复标记+2字节恢复长度+恢复数据),还原标记为0x02。

我们在RocksDB存储引擎中有两种memcmp: 常规和反向。默认情况下,我们使用直接比较器,它实际上与memcmp格式相同。
但是,如果列族名称以"rev:"开头,我们将使用反向比较器(返回-memcmp(a,b);)。它使反向迭代范围更有效。 
RocksDB在SST文件块中使用前缀压缩。这有点减慢了反向迭代器。通过反转顺序,我们可以更快地进行反向迭代(例如,对于诸如select * from t1 desc limit 100之类的查询;)

Row checksums 行校验和

MyRocks具有可选地在值字段末尾存储校验和和功能。校验和每行总共有9个字节(1字节校验和和博鳌及+CRC32秘钥和CRC32值)。
它还可以配置要校验和的行的百分比。校验和标记为0x01