# RocksDB 写（B）

![center](./student-guide/diagram/03-RocksDB-Input-02-01.png)
-------------------------------------------------------------
下面，我们着重讨论下 RocksDB 的数据落盘后的文件组织方式。
磁盘上的文件被分成多层进行组织。我们叫它们为 Level-1，Level-2 ... 等等，或者简单的 L1 , L2 ... 等等。一个特殊的层，Level-0 ( L0 )，会包含刚从内存 MemTable 落盘的数据，到达 4 个会触发 compaction 向下一层，如果积压达到 20 个，会触发 write stall。每个层（除了 Level0 ）都是一个独立的排序结果。
在每一层（除了Level-0），数据被切分成多个SST文件。
每个 SST 文件中的 key 都是排好序的。如果需要定位一个 key ，我们先二分查找所有文件的起始和结束 key，定位哪个文件有这个 key ，然后二分查找具体的文件，来定位 key 的位置。总的来说，就是在该层的所有key里面进行二分查找。
所有非  0 层都有目标大小。压缩的目标是限制这些层的数据大小，大小目标通常是指数增加。
最后，关于 WAL 的日志，WAL 会把 MemTable 的操作序列化之后以日志文件形式存储在持久化介质中。发生崩溃的时候，WAL 日志（ log ）文件可以用于重新构建 MemTable，帮助数据库恢复数据库到一个一致的状态。当一个 MemTable 被安全地落盘到持久化介质之后，相关的 WAL 日志（ log ）会变成过期的，然后被归档。最终归档的日志会在一定时间后被从硬盘上删除。
到此为止，数据就被持久化写入了，我们可以看到，WAL 一开始就保证了写不丢失，接下来我们总结一下 RocksDB 的 CRUD 大致流程：
写入操作
写操作首先需要通过 WAL 将数据写入到磁盘日志（ Log ）中，防止数据丢失，然后数据会被写入到内存的 MemTable 中，这样一次写操作已经完成了，只需要 1 次磁盘 IO，再加 1 次内存操作。相较于 B+ 树的多次磁盘随机 IO，大大提高了效率。随后，这些在 MemTable 中的数据会被批量地合并到磁盘中的 SSTable 当中，将随机写变为了顺序写。
删除操作
当有删除操作时，并不需要像 B+ 树一样，在磁盘中找到相应的数据后再删除，只需要在 MemTable 中插入一条数据当作标志，如 delete key：1233 ，当读操作读到 MemTable 中的这个标志时，就会知道这个 key 已被删除。随后在日志合并中，这条被删除的数据会在合并的过程中一起被删除。
更新操作
更新操作和删除操作类似，都是只操作 MemTable，写入一个标志，随后真正的更新操作被延迟在合并时一并完成。

















