title: mysql · myrocks · myrocks記錄格式分析
rocksdb作為kv儲存引擎,那麼myrocks記錄最終會以kv的形式儲存在rocksdb中。mysql中的表一般由若干索引組成, 在innodb儲存引擎中,每個索引對應一顆b樹,而在rocksdb儲存引擎中,索引對應於rocksdb中一段連續範圍的資料。
具體來說,這個範圍是此索引id和id+1之間的所有資料。如果表的所有索引都在乙個column family, 那錶的這些索引資料在物理上基本是連續的。
可以參考之前文章中的圖示
myrocks以索引為單位,將表的所有索引分別儲存在rocksdb中。
根據索引的型別,myrocks記錄的格式有所不同。下面以下表不同索引型別來分別介紹
create table t1(a int,
b varchar(20),
c char(5),
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 (1,1,'bbbbbbbbbb','c');
key: index_id, m(pk)
value: unpack_info, null-bitmap,b,c,d
key由索引id和主鍵組成。 index_id是索引的唯一標識占用4個位元組,m(pk) 表示pk轉化後的資料,此轉化後的資料可以直接用於memcmp比較
rocksdb資料都是根據key排序的,為了便於比較,不同型別資料都會經過一些轉化,轉化後可以直接用於memcmp比較。unpace_info儲存將m(pk)逆轉化為pk的資訊,如果不需要額外轉換資訊則unpace_info為null,此例中pk為int型別,不需要額外資訊unpace_info為null關於memcmp轉化,下一節會詳細介紹
value儲存unpack_info和非主鍵外的其他字段資料, null-bitmap標識哪些欄位為空。
key: index_id,null-byte, m(b),m(pk)
value: unpack_info
key由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,來表示此欄位是否為空
rocksdb為了比較方便,將key欄位轉化為可以直接memcmp比較的形式。所以myrocks 一般建議使用sensitive collations (latin1_bin, utf8_bin, binary).
這樣可以避免轉化的開銷。
整形轉化比較簡單,但對於有符號型別需要特殊處理,如果直接儲存會導致比較是負數比正數大。
這裡對有符號型別處理的方式是將符號位反轉,這樣正數就比負數大了,
關鍵**段如下
field_long::make_sort_key:
if (!table->s->db_low_byte_first)
char型別直接補空格
varchar型別為了節省空間處理起來就複雜多了
以原始碼中的注釋為例
const int varchar_cmp_less_than_spaces = 1;
const int varchar_cmp_equal_to_spaces = 2;
const int varchar_cmp_greater_than_spaces = 3;
example: if fpi->m_segment_size=5, and the collation is latin1_bin:
'abcd\0' => [ 'abcd' ]['\0 ' ]
'abcd' => [ 'abcd' ]
'abcd ' => [ 'abcd' ]
'abcdzzzz' => [ 'abcd' ][ 'zzzz' ]
字串以m_segment_size分段儲存,每段前m_segment_size-1個字元是內容,最後乙個字元表示和空格比較,varchar_cmp_equal同時也表示字串結束
例子中m_segment_size為5,實際實現上值為9前面為我們看到的是進入rocksdb之前記錄的kv結構形式,實際上資料儲存到rocksdb後key還要進一步封裝
進入rocksdb之前的key稱為userkey, rocksdb內部稱為internalkey
internalkey=| user key (string) | sequence number (7 bytes) | value type (1 byte) |
其中sequence number 是記錄序列號,每個記錄sequence number根據是以記錄進入rocksdb先後順序遞增的。
sequence number是實現rocksdb事務處理的關鍵,這個下次討論。
value type是記錄的型別,put, merge,delete等
以例項來說明比較直觀,還是上面介紹的那個表,插入一條記錄,來看看記錄的具體結構
insert into t1 (pk,a,b,c) values (1,1,'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 2 260 1 11 cf_1
test t1 null idx2 3 261 2 11 cf_2
二級索引記錄
MyRocks寫入分析
title mysql myrocks myrocks寫入分析 myrocks的寫入流程可以簡單的分為以下幾步來完成 將解析後的記錄 ktypevalue ktypedeletion 寫入到writebatch中 將wal日誌寫入log檔案 將writebatch中的內容寫到memtable中,事務...
MyRocks事務鎖分析
myrocks中rocksdb作為基於快照的事務引擎,其在事務支援上有別於innodb,有其自身的特點。在早期的月報 myrocks之事務處理 中,我們對鎖的實現有過簡單的分析,本文會以一些例子來介紹myrocks是如果來加鎖解鎖的。myrocks早期只支援排他鎖,支援selec.in share ...
MySQL 特性分析 MyRocks簡介
rocksdb是facebook基於leveldb實現的,目前為facebook內部大量業務提供服務。經過facebook大量工作,將rocksdb作為mysql的乙個儲存引擎移植到mysql,稱之為myrocks。經過兩年的發展,myrocks已經比較成熟 rc階段 現已進入了facebook m...