Fast data load
Load data相比普通insert效率更高,Load data批量插入数据有效减少了解析SQL的开销。MyRocks 同其他MySQL 引擎一样也支持Load data语法,同时MyRocks对data load也做了特殊优化。RocksDB引擎有一个规律是,数据最终会存储在最底层SST文件中,MyRocks通过参数rocksdb_bulk_load控制是否直接将数据存储在最底层SST文件中,而不走普通的insert流程。
先来看下普通insert流程(图片来自yoshinorim)
优化后的bulk load流程(图片来自yoshinorim)
由于SST文件中的数据必须是有序的,所以 bulk load特性有一个限制是插入的数据必须是按主键有序的。
Insert和Load data都支持bulk load特性,Load data文件中的数据容易保证有序,但对于非自增insert来说,要保证有序插入比较困难,因此bulk load特性对普通insert意义不大。
rocksdb_bulk_load设为1后,开启bulk load特性。值得注意的是,在 bulk load特性下,会默认忽略唯一性检查,同时rocksdb_commit_in_the_middle自动开启。
Bulk load 源码实现
step 1 第一次插入时会新建SST临时文件, 参见myrocks::Rdb_sst_info::open_new_sst_file
文件形如:test.t1_PRIMARY_0_0.bulk_load.tmp
db.tablename_indexname_count1_count2_.bulk_load.tmp
其中count1每次都会原子自增,防止并发load时出现重名的情况。
其中count2表示当前是第几个SST临时文件step 2 随后插入都会直接插入到SST临时文件中,参见myrocks::Rdb_sst_info::put
step 3 SST临时文件写满或load结束,将SST临时文件copy或hard link为正式的SST文件,同时更新SST元数据信息,参考rocksdb::ExternalSstFileIngestionJob::Prepare/ExternalSstFileIngestionJob::Run
step 4 删除临时SST文件,参考ExternalSstFileIngestionJob::Cleanup
如果bulk load中途mysqld crash有可能残留SST临时文件,mysqld重启时会自动清理SST临时文件。参考Rdb_sst_info::init
Bulk load 相关测试
load data 测试
Bulk load下rocksdb load data比innodb快近3倍。
Bulk load下rocksdb load data比rocksdb 普通load data快近6倍。
perf top
可以看出bulk load模式下,插入流程要简洁很多。
rocksdb without bulk load
rocksdb with bulk load
insert 测试
由于SQL解析占比重较大,bulk load模式下的insert优势并不明细。
perf top
可以看出普通insert相比load data有更多的SQL解析操作(MySQLparse),同时非bulk load下的insert比bulk load下insert有更多的排序操作(KeyComparator)。
insert without bulk load
insert with bulk load