Skip to content

Commit 8c026d3

Browse files
authored
持久化功能 (#376)
### What problem were solved in this pull request? Issue Number: close #118 #279 Problem: 当前的WAL仅记录了事务的日志,没有记录内部对象,比如record manager、B+树等的日志,导致在异常重启时,可能正常无法恢复。 ### What is changed and how it works? 除了记录事务日志,还记录了Buffer pool、record manager、B+树等内部数据日志,可以保证内部对象变更后断电等异常,仍然可以通过日志来恢复数据。 另外,此PR也实现了事务的回滚日志。
1 parent be0dcfe commit 8c026d3

File tree

134 files changed

+11253
-3359
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+11253
-3359
lines changed

.github/workflows/build.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131

3232
- name: BuildDebug
3333
shell: bash
34-
run: bash build.sh debug -DENABLE_COVERAGE=ON --make -j4
34+
run: bash build.sh debug -DCONCURRENCY=ON -DENABLE_COVERAGE=ON --make -j4
3535

3636
- name: Test
3737
shell: bash
@@ -65,4 +65,7 @@ jobs:
6565

6666
- name: Build
6767
shell: bash
68-
run: sudo bash build.sh init && bash build.sh release --make -j4
68+
run: |
69+
export ASAN_OPTIONS=detect_container_overflow=0
70+
sudo bash build.sh init
71+
bash build.sh release --make -j4

.github/workflows/test.yml

+30-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
name: test
22

33
on:
4-
push:
5-
branches: [ "main" ]
64
pull_request:
75
branches: [ "main" ]
86

@@ -25,7 +23,6 @@ jobs:
2523
echo "begin test..."
2624
python3 test/case/miniob_test.py --test-cases=basic | tail -1 | grep "basic is success"
2725
28-
# sysbench cannot work property on this platform.
2926
# I found that sysbench would send more request before receiving last response
3027
sysbench-test:
3128
strategy:
@@ -45,22 +42,48 @@ jobs:
4542
sudo bash script.deb.sh
4643
sudo apt -y install sysbench mariadb-client
4744
48-
- name: start server
45+
- name: build miniob
4946
shell: bash
5047
run: |
5148
sudo bash build.sh init
5249
bash build.sh release -DCONCURRENCY=ON -DWITH_UNIT_TESTS=OFF
53-
nohup ./build_release/bin/observer -T ${{ matrix.thread_model }} -s /tmp/miniob.sock -f etc/observer.ini -P mysql -t mvcc &
50+
51+
- name: start server
52+
shell: bash
53+
run: |
54+
nohup ./build_release/bin/observer -T ${{ matrix.thread_model }} -s /tmp/miniob.sock -f etc/observer.ini -P mysql -t mvcc -d disk &
5455
sleep 10 && echo "wake up"
5556
mysql --version
5657
mysql -S /tmp/miniob.sock -e "show tables"
5758
59+
# error number 41 is LOCKED_CONCURRENCY_CONFLICT
60+
# we should change the error number if we update the code
5861
- name: sysbench test
5962
shell: bash
6063
run: |
6164
cd test/sysbench
62-
sysbench --mysql-socket=/tmp/miniob.sock --threads=10 ${{ matrix.test_case }} prepare
63-
sysbench --mysql-socket=/tmp/miniob.sock --threads=10 ${{ matrix.test_case }} run
65+
sysbench --mysql-socket=/tmp/miniob.sock --mysql-ignore-errors=41 --threads=10 ${{ matrix.test_case }} prepare
66+
sysbench --mysql-socket=/tmp/miniob.sock --mysql-ignore-errors=41 --threads=10 ${{ matrix.test_case }} run
67+
68+
- name: stop server
69+
shell: bash
70+
run: |
71+
mysql -S /tmp/miniob.sock -e "create table t(id int)"
72+
mysql -S /tmp/miniob.sock -e "show tables"
73+
killall observer
74+
75+
- name: restart server
76+
shell: bash
77+
run: |
78+
nohup ./build_release/bin/observer -T ${{ matrix.thread_model }} -s /tmp/miniob.sock -f etc/observer.ini -P mysql -t mvcc -d disk &
79+
sleep 10 && echo "wake up"
80+
mysql -S /tmp/miniob.sock -e "show tables"
81+
82+
- name: sysbench test again
83+
shell: bash
84+
run: |
85+
cd test/sysbench
86+
sysbench --mysql-socket=/tmp/miniob.sock --mysql-ignore-errors=41 --threads=10 ${{ matrix.test_case }} run
6487
6588
benchmark-test:
6689
runs-on: ubuntu-latest

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
.vscode
77
!.vscode/tasks.json
88
!.vscode/launch.json
9+
.VSCodeCounter/*
910
./docs/doxy/
1011
build/*
1112
build_*

.vscode/launch.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
"program": "${workspaceFolder}/${defaultBuildTask}/bin/observer",
1212
"args": ["-f", "${workspaceFolder}/etc/observer.ini", "-P", "cli"],
1313
"cwd": "${workspaceFolder}/${defaultBuildTask}/",
14-
"externalConsole":true,
1514
"internalConsoleOptions": "openOnSessionStart",
1615
"osx": {
17-
"MIMode": "lldb"
16+
"MIMode": "lldb",
17+
"externalConsole":true
1818
}
1919
},
2020
{

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ OPTION(ENABLE_UBSAN "Build with undefined behavior sanitizer" OFF)
1616
OPTION(WITH_UNIT_TESTS "Compile miniob with unit tests" ON)
1717
OPTION(WITH_BENCHMARK "Compile benchmark" OFF)
1818
OPTION(ENABLE_COVERAGE "Enable unittest coverage" OFF)
19+
OPTION(ENABLE_NOPIE "Enable no pie" OFF)
1920
OPTION(CONCURRENCY "Support concurrency operations" OFF)
2021
OPTION(STATIC_STDLIB "Link std library static or dynamic, such as libgcc, libstdc++, libasan" OFF)
2122

@@ -40,6 +41,11 @@ ENDIF(WIN32)
4041

4142
# This is for clangd plugin for vscode
4243
SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -Werror")
44+
IF (ENABLE_NOPIE)
45+
SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -no-pie")
46+
ADD_LINK_OPTIONS(-no-pie)
47+
ENDIF (ENABLE_NOPIE)
48+
4349
IF(DEBUG)
4450
MESSAGE(STATUS "DEBUG has been set as TRUE ${DEBUG}")
4551
SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O0 -g -DDEBUG ")

README.md

+25-28
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
<div align="center">
1+
# MiniOB 介绍
22

3+
<div align="left">
4+
5+
[![Chinese Doc](https://img.shields.io/badge/文档-简体中文-blue)](https://oceanbase.github.io/miniob/miniob-introduction.html)
6+
[![MiniOB stars](https://img.shields.io/badge/dynamic/json?color=blue&label=stars&query=stargazers_count&url=https%3A%2F%2Fapi.github.com%2Frepos%2Foceanbase%2Fminiob)](https://github.com/oceanbase/miniob)
37
[![Coverage Status](https://codecov.io/gh/oceanbase/miniob/branch/main/graph/badge.svg)](https://codecov.io/gh/oceanbase/miniob)
48

59
</div>
610

7-
# MiniOB 概述
8-
9-
MiniOB 是 [OceanBase](https://github.com/oceanbase/oceanbase) 团队基于华中科技大学数据库课程原型,联合多所高校重新开发的、专为零基础的同学设计的数据库入门学习项目。我们的目标是为在校学生、数据库从业者、爱好者或对基础技术感兴趣的人提供一个友好的数据库学习项目。
11+
MiniOB 是 [OceanBase](https://github.com/oceanbase/oceanbase) 团队基于华中科技大学数据库课程原型,联合多所高校重新开发的、专为零基础的同学设计的数据库入门学习项目。MiniOB 的目标是为在校学生、数据库从业者、爱好者或对基础技术感兴趣的人提供一个友好的数据库学习项目,更好地将理论、实践进行结合,提升同学们的工程实战能力。
1012

1113
MiniOB 整体代码简洁,容易上手,设计了一系列由浅入深的题目,帮助同学们从零基础入门,迅速了解数据库并深入学习数据库内核。MiniOB 简化了许多模块,例如不考虑并发操作、安全特性和复杂的事务管理等功能,以便更好地学习数据库实现原理。我们期望通过 MiniOB 的训练,同学们能够熟练掌握数据库内核模块的功能和协同关系,并具备一定的工程编码能力,例如内存管理、网络通信和磁盘 I/O 处理等, 这将有助于同学在未来的面试和工作中脱颖而出。
1214

1315
# [文档](https://oceanbase.github.io/miniob/)
14-
代码配套文档和相关代码注释已经生成文档,并通过 GitHub Pages 发布。您可以直接访问:[MiniOB GitHub Pages](https://oceanbase.github.io/miniob/).
16+
代码配套设计文档和相关代码注释已经生成文档,并通过 GitHub Pages 发布。您可以直接访问:[MiniOB GitHub Pages](https://oceanbase.github.io/miniob/).
1517

1618
## 快速上手
1719

@@ -40,16 +42,16 @@ MiniOB 整体架构如下图所示:
4042

4143
- SQL解析:将用户输入的SQL语句解析成语法树;
4244

43-
- 执行计划缓存:执行计划缓存模块会将该 SQL第一次生成的执行计划缓存在内存中,后续的执行可以反复执行这个计划,避免了重复查询优化的过程(未实现)。
44-
45-
- 语义解析模块:将生成的语法树,转换成数据库内部数据结构(部分实现);
46-
47-
- 查询缓存:将执行的查询结果缓存在内存中,下次查询时,可以直接返回(未实现);
45+
- 语义解析模块:将生成的语法树,转换成数据库内部数据结构;
4846

4947
- 查询优化:根据一定规则和统计数据,调整/重写语法树。(部分实现);
5048

5149
- 计划执行:根据语法树描述,执行并生成结果;
5250

51+
- 存储引擎:负责数据的存储和检索;
52+
53+
- 事务管理:管理事务的提交、回滚、隔离级别等;
54+
5355
- 会话管理:管理用户连接、调整某个连接的参数;
5456

5557
- 元数据管理:记录当前的数据库、表、字段和索引元数据信息;
@@ -59,43 +61,38 @@ MiniOB 整体架构如下图所示:
5961

6062
# [OceanBase 大赛](https://open.oceanbase.com/competition)
6163

62-
2022 OceanBase 数据库大赛是由中国计算机学会(CCF)数据库专业委员会指导,OceanBase 与蚂蚁技术研究院学术合作团队联合举办的数据库内核实战赛事。本次大赛主要面向全国爱好数据库的高校学生,以“竞技、交流、成长”为宗旨,搭建基于赛事的技术交流平台,促进高校创新人才培养机制,不仅帮助学生从0开始系统化学习数据库理论知识,提升学生数据库实践能力,更能帮助学生走向企业积累经验,促进国内数据库人才的发展,碰撞出创新的火花。
64+
全国大学生计算机系统能力大赛(以下简称“大赛”)是由系统能力培养研究专家组发起,全国高等学校计算机教育研究会、系统能力培养研究项目示范高校共同主办、OceanBase 承办,面向高校大学生的全国性数据库大赛。
65+
大赛面向全国爱好数据库的高校学生,以“竞技、交流、成长”为宗旨,搭建基于赛事的技术交流平台,促进高校创新人才培养机制,不仅帮助学生从0开始系统化学习 OceanBase 数据库理论知识,提升学生数据库实践能力,更能帮助学生走向企业积累经验,促进国内数据库人才的发展,碰撞出创新的火花。
6366

6467
OceanBase 初赛基于一套适合初学者实践的数据库实训平台 MiniOB,代码量少,易于上手学习,包含了数据库的各个关键模块,是一个系统性的数据库学习平台。基于该平台设置了一系列由浅入深的题目,以帮助同学们更好"零"基础入门。
6568

66-
2023 OceanBase 数据库大赛正在火热进行, 更多详情, 请参考 [OceanBase 大赛](https://open.oceanbase.com/competition/index)
67-
68-
### 1. 大赛手把手入门教程
69+
为了帮助大家能在大赛中取得好成绩,我们提供了一系列的教程和指导,帮助大家更好地学习数据库基础知识,更好地完成大赛题目
70+
欢迎大家查看[《从0到1数据库内核实战教程》 视频教程](https://open.oceanbase.com/activities/4921877?id=4921946),视频中包含了代码框架的介绍和一些入门题目的讲解。
71+
> 由于MiniOB是一个持续演进的产品,视频教程中有些内容会与最新代码有冲突,建议大家参考讲解中的思路。
6972
70-
[大赛入门教程](https://oceanbase.github.io/miniob/game/gitee-instructions.html)
71-
72-
### 2. 大赛赛题
73-
74-
[赛题介绍](https://oceanbase.github.io/miniob/game/miniob_topics.html)
75-
76-
### 3. 提交测试
77-
78-
题目完成并通过自测后,大家可以在 [MiniOB 训练营](https://open.oceanbase.com/train?questionId=500003) 上提交代码进行测试。
73+
大赛的初赛是在MiniOB上进行的,同学们可以在前几届的题目上进行提前训练,可以让自己比别人提前一步。大家在日常训练时可以在[MiniOB 训练营](https://open.oceanbase.com/train?questionId=500003) 上提交代码进行测试。
7974

8075
在提交前, 请参考并学习 [训练营使用说明](https://ask.oceanbase.com/t/topic/35600372)
8176

82-
### 4. 大赛FAQ
83-
84-
[大赛 FAQ ](https://ask.oceanbase.com/t/topic/35601465)
77+
如果大家在大赛中或使用训练营时遇到一些问题,请先查看[大赛 FAQ](https://ask.oceanbase.com/t/topic/35601465)
8578

8679
# 在线开发平台
8780

88-
本仓库基于 Gitpod 建立了快速在线开发平台。点击下面的按钮即可一键体验(建议使用 Chrome 浏览器)。
81+
搭建开发环境是一个比较耗时而且繁琐的事情,特别是对于初学者。为了让大家更快地上手 MiniOB,本仓库基于 Gitpod 建立了快速在线开发平台。点击下面的按钮即可一键体验(建议使用 Chrome 浏览器)。
8982

9083
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/oceanbase/miniob)
9184

85+
> 注意:这个链接打开的是MiniOB主仓库的开发环境,同学们需要通过gitpod进入自己的仓库开发环境。
86+
9287
首次进入 Gitpod 时需要安装一些依赖。安装完成后,终端界面会显示 "Dependency installed successfully"。运行 `bash build.sh --make -j4` 命令即可编译 MiniOB。
9388

9489
# Contributing
9590

96-
OceanBase 社区热情欢迎每一位对数据库技术热爱的开发者,期待与您携手开启思维碰撞之旅。无论是文档格式调整或文字修正、问题修复还是增加新功能,都是参与和贡献 OceanBase 社区的方式之一。现在就开始您的首次贡献吧!更多详情,请参考 [社区贡献](CONTRIBUTING.md).
91+
OceanBase 社区热情欢迎每一位对数据库技术热爱的开发者,期待与您携手开启思维碰撞之旅。无论是文档格式调整或文字修正、问题修复还是增加新功能,都是参与和贡献 OceanBase 社区的方式之一。MiniOB 现在开放了一些[新功能的开发](https://github.com/oceanbase/miniob/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22),欢迎有兴趣的同学一起共建,希望我们共同成长。如果你对MiniOB不熟悉也没关系,可以直接联系我们,我们将会有人指导上手。现在就开始您的首次贡献吧!更多详情,请参考 [社区贡献](CONTRIBUTING.md)
9792

9893
# Contributors
94+
感谢所有为 MiniOB 项目做出贡献的同学们!
95+
9996
<a href="https://github.com/oceanbase/miniob/graphs/contributors"><img src="https://contributors-img.web.app/image?repo=oceanbase/miniob&width=890" /></a>
10097

10198
# License

benchmark/bplus_tree_concurrency_test.cpp

+12-10
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@ See the Mulan PSL v2 for more details. */
1919
#include "common/math/integer_generator.h"
2020
#include "storage/buffer/disk_buffer_pool.h"
2121
#include "storage/index/bplus_tree.h"
22+
#include "storage/clog/vacuous_log_handler.h"
23+
#include "storage/buffer/double_write_buffer.h"
2224

2325
using namespace std;
2426
using namespace common;
2527
using namespace benchmark;
2628

27-
once_flag init_bpm_flag;
28-
BufferPoolManager bpm{512};
29-
3029
struct Stat
3130
{
3231
int64_t insert_success_count = 0;
@@ -48,7 +47,7 @@ class BenchmarkBase : public Fixture
4847
public:
4948
BenchmarkBase() {}
5049

51-
virtual ~BenchmarkBase() { BufferPoolManager::set_instance(nullptr); }
50+
virtual ~BenchmarkBase() {}
5251

5352
virtual string Name() const = 0;
5453

@@ -58,25 +57,26 @@ class BenchmarkBase : public Fixture
5857
return;
5958
}
6059

60+
bpm_.init(make_unique<VacuousDoubleWriteBuffer>());
61+
6162
string log_name = this->Name() + ".log";
6263
string btree_filename = this->Name() + ".btree";
6364
LoggerFactory::init_default(log_name.c_str(), LOG_LEVEL_TRACE);
6465

65-
std::call_once(init_bpm_flag, []() { BufferPoolManager::set_instance(&bpm); });
66-
6766
::remove(btree_filename.c_str());
6867

6968
const int internal_max_size = 200;
7069
const int leaf_max_size = 200;
7170

7271
const char *filename = btree_filename.c_str();
7372

74-
RC rc = handler_.create(filename, INTS, sizeof(int32_t) /*attr_len*/, internal_max_size, leaf_max_size);
73+
RC rc = handler_.create(
74+
log_handler_, bpm_, filename, INTS, sizeof(int32_t) /*attr_len*/, internal_max_size, leaf_max_size);
7575
if (rc != RC::SUCCESS) {
7676
throw runtime_error("failed to create btree handler");
7777
}
78-
LOG_INFO(
79-
"test %s setup done. threads=%d, thread index=%d", this->Name().c_str(), state.threads(), state.thread_index());
78+
LOG_INFO("test %s setup done. threads=%d, thread index=%d",
79+
this->Name().c_str(), state.threads(), state.thread_index());
8080
}
8181

8282
virtual void TearDown(const State &state)
@@ -181,7 +181,9 @@ class BenchmarkBase : public Fixture
181181
}
182182

183183
protected:
184-
BplusTreeHandler handler_;
184+
BufferPoolManager bpm_{512};
185+
BplusTreeHandler handler_;
186+
VacuousLogHandler log_handler_;
185187
};
186188

187189
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)