Put操作是在HRegion#doMiniBatchMutation方法中执行的。
private long doMiniBatchMutation(BatchOperationInProgress<?> batchOp) throws IOException
为什么方法名不叫doPut呢?从这个方法里的一段代码就可以看出,这个方法不仅是Put的执行方法,而且是Delete的执行方法,Put、Delete实质调用的是同一个方法。
if (isPutMutation) {
...
} else {
// 如果mutation不是Put,就强转成Delete
prepareDelete((Delete) mutation);
}
回到doMiniBatchMutation的内容,这个方法十分的长,近400行的代码,不过代码的注释清晰标明了每一段代码所执行的事情,咱们先从注释开始看,总共代码分9步。
- Try to acquire as many locks as we can, and ensure we acquire at least one.第1步,尽可能多的获得锁,至少保证获得一个。
- Update any LATEST_TIMESTAMP timestamps 第2步,更新时间戳,如果没设置,就更新成系统时间
- Build WAL edit 第3步,创建WAL edit
- Append the final edit to WAL. Do not sync wal. 第4步,提交edit到WAL,但是不同步,并且获取最新的MVCC number
- Write back to memstore. Write to memstore. It is ok to write to memstore first without syncing the WAL because we do not roll forward the memstore MVCC. The MVCC will be moved up when the complete operation is done. These changes are not yet visible to scanners till we update the MVCC. The MVCC is moved only when the sync is complete. 第5步,写回memstore。不同步WAL先写进memstore是OK的,因为我们不会向前滚动memstore的MVCC。完整操作完成的时候MVCC才会向前移动,这时候,改动才对scanner可见。重复一次,同步完成,MVCC才会向前移动。
- Release row locks, etc. 第6步,释放行锁
- Sync wal. 第7步,同步WAL
- Advance mvcc. This will make this put visible to scanners and getters. 第8步,更新MVCC,这会使这次put对scanner和getter可见
- Run coprocessor post hooks. This should be done after the wal is synced so that the coprocessor contract is adhered to.