# RocksDB: 写入

__*MemTable*__
__*immutable MemTable*__
__*SST*__
__*RocksDB 写流程*__

![left](./student-guide/diagram/RocksDBWrite01_aa_001_20220511.png)
-------------------------------------------------------------
下面我们来看一下 RocksDB 的写操作是如何进行的,从而理解 TiDB 数据库通过 RocksDB 是如何持久化数据的,RocksDB 采用 LSM tree 的数据结构来存储 key value 数据,LSM treee 会将所有的数据插入、修改和删除等操作保存在内存之中,当此类操作达到一定的数据量后,再批量地写入到磁盘中。而在写入磁盘时,会和以前的数据做合并。在合并过程中,不会像 B+ 树一样,在原数据的位置上修改,而是直接插入新的数据,从而避免了随机写。

LSM tree 的结构是横跨内存和磁盘的,包含 MemTable、immutable MemTable、SSTable 等多个部分,我们以图中的一次写入操作来说明 LSM tree 和其相关组件的工作流程。

1. 先通过 WAL 的方式备份到磁盘中,以防数据因为内存掉电而丢失（预写式日志（Write-ahead logging,缩写 WAL 是关系数据库系统中用于提供原子性和持久性（ACID属性中的两个）的一系列技术 ）。在使用 WAL 的系统中,所有的修改在提交之前都要先写入日志 （ log ） 文件中）,sync-log = true 表示写入会调用 fsync,将 WAL 日志文件持久化道磁盘中,而不是操作系统缓存中。

2. WAL 完成后,就会写数据到 MemTable 中,MemTable 是一个内存数据结构,它保存了落盘前的数据。MemTable 可以使用跳跃表或者搜索树等数据结构来组织数据以保持数据的有序性。
MemTable 同时服务于读和写—新的写入总是将数据插入到 MemTable,读取操作在查询 SST 文件前总是要查询 MemTable,因为 MemTable 里面的数据总是最新的。

3. 当 MemTable 达到一定的数据量（write_buffer_size 大小）后,MemTable 会转化成为 immutable MemTable（immutable MemTable 在内存中是不可修改的数据结构,它是将 MemTable 转变为 SSTable 的一种中间状态。目的是为了在转存过程中不阻塞写操作。写操作可以由新的 MemTable 处理,而不会因为锁住 MemTable 而等待）,同时会创建一个新的 MemTable 来处理新的数据。一个后台线程会把这个 MemTable 的内容落盘到一个 SST 文件（SSTable ( Sorted String Table ) 即为有序键值对集合,是 LSM 树在磁盘中的数据的结构, MemTable 中的数据最终都会被转化为 SSTable 并保存在磁盘中）,然后这个 MemTable 就可以被销毁了,同时携带有跟这个 MemTable 相关数据的WAL 文件也可以被删除。默认 1 个 immutable MemTable 就会落盘,5 个会触发 write stall。