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