开发者社区> zysql> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

MyRocks写入分析

简介: --- title: MySQL · myrocks · myrocks写入分析 author: 张远 --- # 写入流程 myrocks的写入流程可以简单的分为以下几步来完成 1. 将解析后的记录(kTypeValue/kTypeDeletion)写入到WriteBatch中 2. 将WAL日志写入log文件 3. 将WriteBatch中的内容写到memtabl
+关注继续查看

title: MySQL · myrocks · myrocks写入分析

author: 张远

写入流程

myrocks的写入流程可以简单的分为以下几步来完成

  1. 将解析后的记录(kTypeValue/kTypeDeletion)写入到WriteBatch中
  2. 将WAL日志写入log文件
  3. 将WriteBatch中的内容写到memtable中,事务完成

其中第2,3步在提交时完成

WriteBatch与Myrocks事务处理密切相关,事务中的记录提交前都以字符串的形式存储在WriteBatch->rep_中,要么都提交,要么都回滚。 回滚的逻辑比较简单,只需要清理WriteBatch->rep_即可。详见TransactionImpl::Rollback

一个简单的insert 写入WriteBatch堆栈如下

#0  rocksdb::WriteBatchInternal::Put
#1  rocksdb::WriteBatch::Put
#2  myrocks::ha_rocksdb::update_pk
#3  myrocks::ha_rocksdb::update_indexes
#4  myrocks::ha_rocksdb::update_write_row
#5  myrocks::ha_rocksdb::write_row
#6  handler::ha_write_row
#7  write_record
#8  mysql_insert
#9  mysql_execute_command
#10 mysql_parse
#11 dispatch_command
#12 do_command
#13 do_handle_one_connection

一个简单的insert commit堆栈如下

#0  rocksdb::InlineSkipList<rocksdb::MemTableRep::KeyComparator const&>::Insert
#1  rocksdb::(anonymous namespace)::SkipListRep::Insert
#2  rocksdb::MemTable::Add
#3  rocksdb::MemTableInserter::PutCF
#4  rocksdb::WriteBatch::Iterate
#5  rocksdb::WriteBatch::Iterate
#6  rocksdb::WriteBatchInternal::InsertInto
#7  rocksdb::DBImpl::WriteImpl
#8  rocksdb::DBImpl::Write 
#9  rocksdb::TransactionImpl::Commit
#10 myrocks::Rdb_transaction_impl::commit_no_binlog
#11 myrocks::Rdb_transaction::commit
#12 myrocks::rocksdb_commit
#13 ha_commit_low
#14 TC_LOG_MMAP::commit 
#15 ha_commit_trans
#16 trans_commit_stmt
#17 mysql_execute_command
#18 mysql_parse
#19 dispatch_command
#20 do_command
#21 do_handle_one_connection

提交流程及优化

这里只分析rocksdb引擎的提交流程,实际MyRocks提交时还需先写binlog(binlog开启的情况).

rocksdb引擎提交时就完成两个事情

  1. 写WAL日志(WAL开启的情况下rocksdb_write_disable_wal=off)
  2. 将之前的WriteBatch写入到memtable中

然而,写WAL是一个串行操作。为了提高提交的效率, rocksdb引入了group commit机制。

待提交的事务都依次加入到提交的writer队列中,这个writer队列被划分为一个一个group. 每个group有一个leader, 其他为follower,leader负责批量写WAL。每个group由双向链表link_older, link_newer链接。如下图所示

屏幕快照 2017-07-11 下午7.46.22.png

每个writer可能的状态如下

  • Init: writer的初始状态
  • Header: writer被选为leader
  • Follower: writer被选为follower
  • LockedWating: writer在等待自己转变为指定的状态
  • Completed:writer操作完成

writer的状态变迁跟group是否并发写memtable有关
当开启并发写memtable(rocksdb_allow_concurrent_memtable_write=on)且group中的writer至少有两个时,group才会并发写。

group并发写时writer的状态变迁图如下:

屏幕快照 2017-07-14 下午1.25.27.png

group非并发写时writer的状态变迁图如下:

屏幕快照 2017-07-11 下午7.46.50.png

源码结构图如下(图片来自林青)
屏幕快照 2017-07-14 下午1.44.46.png

上面的图是在group内writer并发写memtable的情形。

非并发写memtable时,没有LaunchParallelFollowers/CompleteParallelWorker, Insertmemtable是由leader串行写入的。

这里group commit有以下要点

  1. 同一时刻只有一个leader, leader完成操作后,才设置下一个leader
  2. 需要等一个group都完成后,才会进行下一个group
  3. group中最后一个完成的writer负责完成提交和设置下一个leader
  4. Leader 负责批量写WAL
  5. 只有leader才会去调整双向链表link_older,link_newer.

注意这里2,3 应该可以优化改进为

  • 不需要等一个group完成再进行下一个group
  • 不同group的follower可以并发执行
  • 只有leader负责完成提交和设置下一个leader

写入控制

rocksdb在提交写入时,需考虑以下几种情况,详见PreprocessWrite

  • WAL日志满,WAL日志超过rocksdb_max_total_wal_size,会从所有的colomn family中找出含有最老日志(the earliest log containing a prepared section)的column family进行flush, 以释放WAL日志空间
  • Buffer满,全局的write buffer超过rocksdb_db_write_buffer_size时,会从所有的colomn family中找出最先创建的memtable进行切换,详见HandleWriteBufferFull
  • 某些条件会触发延迟写

    • max_write_buffer_number > 3且 未刷immutable memtable总数 >=max_write_buffer_number-1
    • 自动compact开启时,level0的文件总数 >= level0_slowdown_writes_trigger
  • 某些条件会触发停写

    • 未刷immutable memtable总数 >=max_write_buffer_number
    • 自动compact开启时,level0的文件总数 >= level0_stop_writes_trigger

具体可参考RecalculateWriteStallConditions

总结

rocksdb写入流程还有优化空间,Facebook也有相关的优化。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
MyRocks TTL特性介绍
# 概述 MyRocks TTL(Time To Live) 特性允许用户指定表数据的自动过期时间,表数据根据指定的时间在compact过程中进行清理。 MyRocks TTL 简单用法如下, 在comment中通过ttl_duration指定过期时间,ttl_col指定过期时间列 ``` CREATE TABLE t1 ( a bigint(20) NOT NUL
4307 0
MySQL · myrocks · 事务锁分析
概述 MyRocks中RocksDB作为基于快照的事务引擎,其在事务支持上有别于InnoDB,有其自身的特点。在早期的月报[myrocks之事务处理] 中,我们对锁的实现有过简单的分析,本文会以一些例子来介绍MyRocks是如果来加锁解锁的。
1748 0
MyRocks简介
--- title: MySQL · 特性分析 · MyRocks简介 author: 济天 --- RocksDB是facebook基于LevelDB实现的,目前为facebook内部大量业务提供服务。经过facebook大量工作,将RocksDB作为MySQL的一个存储引擎移植到MySQL,称之为MyRocks。 经过两年的发展,MyRocks已经比较成熟(RC阶段),现已进入了
2470 0
MyRocks之备份恢复
--- title: MySQL · myrocks · myrocks之备份恢复 author: 张远 --- myrocks支持逻辑备份和物理备份,逻辑备份仍然采用mysqldump,物理备份采用自己开发的myrocks_hotbackup工具,传统的物理备份工具Xtrabackup不支持rocksdb。
3466 0
【MySQL】MyRocks 漫谈
一 前言     最近一两年,数据库技术尤其是MySQL方面的发展可谓百花齐放,TokuDB,MyRocks ,MySQL 5.7 GA,MySQL 8.0 doc release 其软件也在开发当中,ALiSQL 开源。
2059 0
MyRocks简介
--- title: MySQL · 特性分析 · MyRocks简介 author: 济天 --- RocksDB是facebook基于LevelDB实现的,目前为facebook内部大量业务提供服务。经过facebook大量工作,将RocksDB作为MySQL的一个存储引擎移植到MySQL,称之为MyRocks。 经过两年的发展,MyRocks已经比较成熟(RC阶段),现已进入了
6560 0
/tmp/mysql.sock无故丢失的故障分析
环境:Oracle goldengate通过读取/tmp/mysql.sock来同步数据。 故障:mysql.sock经常无故丢失,查看日志、history找不到任何被删除的迹象。 问题分析与解决:Google了一下,发现是tmpwatch自动删除机制导致的。
1512 0
socks
http://sourceforge.net/projects/ssocks/ 3proxy ss5
661 0
+关注
zysql
张远 MySQL/MyRocks
34
文章
10
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载