H2 Database MVStore Commit 流程

作用

BackgroundWriterThread 按照固定频率,将内存里修改的尚未保存的 Page 信息持久化到存储。

流程

启动阶段创建后台线程

org.h2.mvstore.MVStore#setAutoCommitDelay
1.创建 BackgroundWriterThread 后台线程
2.创建序列化线程 serializationExecutor
3.创建持久化线程 bufferSaveExecutor
设置自动提交更改的最大延迟(单位毫秒)。
默认值为 1000,这意味着所有更改最多在一秒后提交。
要禁用自动提交,需要将值设置为 0。在这种情况下,仅在显式调用 commit 时才会提交更改。

BackgroundWriterThread 线程逻辑

定时任务周期性执行,比对内存里的 MVMap 版本号和上一次持久化的版本号是否有变更,有则收集变更的根节点,进行后续处理.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
org.h2.mvstore.FileStore.BackgroundWriterThread#run
org.h2.mvstore.FileStore#writeInBackground
org.h2.mvstore.FileStore#getTimeSinceCreation
获取 mvStore 自创建以来的时间
判断当前相对时间 > 上次提交相对时间 + 延迟时间
org.h2.mvstore.MVStore#tryCommit
提交修改
org.h2.mvstore.MVStore#store
org.h2.mvstore.MVStore#hasUnsavedChanges
判断 mvMap 有变更
获取最新一次持久化版本号
遍历所有 mvMap
和上次持久化的版本号比对, 判断当前 mvMap 是否有变更
org.h2.mvstore.MVStore#storeNow
如果有变更,持久化存储
org.h2.mvstore.MVStore#collectChangedMapRoots
1.收集自上次保存以来有更改的MVMap根页面
org.h2.mvstore.MVMap#hasChangesSince
判断有变更
  根节点添加到 变更列表
org.h2.mvstore.FileStore#storeIt
2.存储
org.h2.mvstore.FileStore#getTimeSinceCreation
更新 最新一次提交时间
org.h2.mvstore.FileStore#submitOrRun
将变更的 pages, 提交 序列化任务 到 serializationExecutor 线程执行

serializationExecutor 线程逻辑

遍历变更的 Pages,将其写出到 buffer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
org.h2.mvstore.FileStore#serializeAndStore 
序列化&存储
org.h2.mvstore.FileStore#createChunk
根据持久化版本号, 创建新的 chunk
org.h2.mvstore.FileStore#getWriteBuffer
org.h2.mvstore.FileStore#serializeToBuffer
序列化成 buffer
org.h2.mvstore.Chunk#estimateHeaderSize
预留头部长度,待会填充
org.h2.mvstore.Chunk#getHeaderBytes
获取 header 的字节表示
org.h2.mvstore.Page.Leaf#writeUnsavedRecursive
写出 pages
org.h2.mvstore.Page#write
org.h2.mvstore.type.BasicDataType#write
写出 keys
org.h2.mvstore.Page.Leaf#writeValues
写出 values
org.h2.mvstore.FileStore#submitOrRun
将 buffer 提交到 bufferSaveExecutor 线程执行, 将缓存刷出

bufferSaveExecutor 线程逻辑

将 buffer 写出到存储.

1
2
3
4
5
6
7
8
9
10
org.h2.mvstore.FileStore#storeBuffer 
存储 buffer
org.h2.mvstore.RandomAccessStore#allocateChunkSpace
分配 chunk 空间
org.h2.mvstore.Chunk#writeChunkHeader
写出 chunk header
org.h2.mvstore.RandomAccessStore#writeChunk
写出 chunk
org.h2.mvstore.FileStore#releaseWriteBuffer
释放 buffer