From 871c9b321844bc59d8494dab9feea68823454d9f Mon Sep 17 00:00:00 2001 From: wangyunlai Date: Tue, 9 May 2023 14:36:58 +0800 Subject: [PATCH] mvcc trx (#156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What problem were solved in this pull request? Issue Number: close #155 close #135 Problem: 实现了简单的事务处理。 当前支持并发事务数据. ### What is changed and how it works? - 支持两种事务模式:Vacuous和MVCC。 Vacuous 事务模式算是没有事务,它的事务接口什么都不做。 MVCC 是多版本并发控制(Multi-Version Concurrency Control),使用多个版本保留记录数据。启动miniob时增加运行时选项 -t mvcc可以选择mvcc。 - MVCC:简单模式的多版本并发控制。 当前miniob仅包含insert和delete操作,因此数据最多包含两个版本,并且不需要在record中保留版本链表信息; 不支持持久化; 没有做垃圾回收; 遗留一个BUG:在提交时没有保证提交的数据一次性对外可见; 使用简单的写写冲突策略:检测到要修改的数据当前有人在修改,就回退 - 编译MINIOB时使用 -DCONCURRENCY=ON 才会支持并发 支持各个模块并发处理,包括buffer pool、bplus、record manager。如果编译时没有使用CONCURRENCY选项,则保持原样,不支持并发,保持系统的简单性。 - 编译时增加 -DDEBUG=ON 还会增加并发调试日志与严格的运行时检测(ASSERT语句) - 当前版本代码中包含了bplus tree和record manager的并发测试,参考benchmark目录下的代码。 ### Other information --- .gitignore | 1 - .vscode/launch.json | 16 + .vscode/tasks.json | 32 + CMakeLists.txt | 1 - NOTICE | 18 +- benchmark/bplus_tree_concurrency_test.cpp | 23 +- benchmark/integer_generator.h | 31 + benchmark/record_manager_concurrency_test.cpp | 417 ++++++++++++ benchmark/server_concurrency_test.cpp | 204 ++++++ build.sh | 16 +- deps/3rd/libevent | 2 +- deps/common/conf/ini.cpp | 2 +- deps/common/conf/ini.h | 2 +- deps/common/defs.h | 6 +- deps/common/io/io.cpp | 2 +- deps/common/io/io.h | 14 +- deps/common/io/roll_select_dir.cpp | 2 +- deps/common/io/roll_select_dir.h | 2 +- deps/common/io/select_dir.h | 6 +- deps/common/lang/bitmap.cpp | 2 +- deps/common/lang/bitmap.h | 7 +- deps/common/lang/comparator.cpp | 4 +- deps/common/lang/comparator.h | 2 +- deps/common/lang/defer.h | 2 +- deps/common/lang/lower_bound.h | 2 +- deps/common/lang/lru_cache.h | 2 +- deps/common/lang/mutex.cpp | 85 ++- deps/common/lang/mutex.h | 40 +- deps/common/lang/serializable.h | 2 +- deps/common/lang/string.cpp | 2 +- deps/common/lang/string.h | 6 +- deps/common/log/log.cpp | 6 +- deps/common/log/log.h | 13 +- deps/common/math/md5.cpp | 2 +- deps/common/math/md5.h | 2 +- deps/common/math/random_generator.cpp | 2 +- deps/common/math/random_generator.h | 2 +- deps/common/math/regex.cpp | 2 +- deps/common/math/regex.h | 2 +- deps/common/metrics/console_reporter.cpp | 2 +- deps/common/metrics/console_reporter.h | 2 +- deps/common/metrics/histogram_snapshot.cpp | 2 +- deps/common/metrics/histogram_snapshot.h | 2 +- deps/common/metrics/log_reporter.cpp | 2 +- deps/common/metrics/log_reporter.h | 2 +- deps/common/metrics/metric.h | 2 +- deps/common/metrics/metrics.cpp | 2 +- deps/common/metrics/metrics.h | 2 +- deps/common/metrics/metrics_registry.cpp | 2 +- deps/common/metrics/metrics_registry.h | 2 +- deps/common/metrics/reporter.cpp | 2 +- deps/common/metrics/reporter.h | 2 +- deps/common/metrics/reservoir.cpp | 2 +- deps/common/metrics/reservoir.h | 2 +- deps/common/metrics/sampler.cpp | 2 +- deps/common/metrics/sampler.h | 2 +- deps/common/metrics/snapshot.h | 6 +- deps/common/metrics/timer_snapshot.cpp | 2 +- deps/common/metrics/timer_snapshot.h | 6 +- deps/common/metrics/uniform_reservoir.cpp | 2 +- deps/common/metrics/uniform_reservoir.h | 7 +- deps/common/mm/debug_new.h | 6 +- deps/common/mm/mem.h | 6 +- deps/common/mm/mem_pool.cpp | 2 +- deps/common/mm/mem_pool.h | 35 +- deps/common/os/os.cpp | 2 +- deps/common/os/os.h | 7 +- deps/common/os/path.cpp | 2 +- deps/common/os/path.h | 6 +- deps/common/os/pidfile.cpp | 2 +- deps/common/os/pidfile.h | 7 +- deps/common/os/process.cpp | 2 +- deps/common/os/process.h | 7 +- deps/common/os/process_param.cpp | 2 +- deps/common/os/process_param.h | 14 +- deps/common/os/signal.cpp | 2 +- deps/common/os/signal.h | 6 +- deps/common/seda/callback.cpp | 2 +- deps/common/seda/callback.h | 6 +- deps/common/seda/class_factory.h | 6 +- deps/common/seda/event_dispatcher.cpp | 2 +- deps/common/seda/event_dispatcher.h | 6 +- deps/common/seda/example_stage.cpp | 2 +- deps/common/seda/example_stage.h | 7 +- deps/common/seda/init.cpp | 2 +- deps/common/seda/init.h | 2 +- deps/common/seda/kill_thread.cpp | 2 +- deps/common/seda/kill_thread.h | 6 +- deps/common/seda/metrics_report_event.cpp | 2 +- deps/common/seda/metrics_report_event.h | 2 +- deps/common/seda/metrics_stage.cpp | 2 +- deps/common/seda/metrics_stage.h | 2 +- deps/common/seda/seda_config.cpp | 2 +- deps/common/seda/seda_config.h | 2 +- deps/common/seda/seda_defs.h | 7 +- deps/common/seda/stage.cpp | 2 +- deps/common/seda/stage.h | 2 +- deps/common/seda/stage_event.cpp | 2 +- deps/common/seda/stage_event.h | 6 +- deps/common/seda/stage_factory.h | 6 +- deps/common/seda/thread_pool.cpp | 2 +- deps/common/seda/thread_pool.h | 2 +- deps/common/seda/timer_stage.cpp | 2 +- deps/common/seda/timer_stage.h | 7 +- deps/common/time/datetime.cpp | 2 +- deps/common/time/datetime.h | 2 +- deps/common/time/timeout_info.cpp | 2 +- deps/common/time/timeout_info.h | 2 +- deps/common/version.h | 7 +- docs/miniob-transaction.md | 198 ++++++ etc/observer.ini | 2 +- src/obclient/client.cpp | 2 +- src/observer/defs.h | 2 +- src/observer/event/optimize_event.h | 2 +- src/observer/event/session_event.cpp | 40 +- src/observer/event/session_event.h | 27 +- src/observer/event/sql_event.cpp | 2 +- src/observer/event/sql_event.h | 2 +- src/observer/event/storage_event.h | 7 +- src/observer/ini_setting.h | 2 +- src/observer/init.cpp | 15 +- src/observer/init.h | 2 +- src/observer/main.cpp | 10 +- src/observer/net/communicator.cpp | 22 +- src/observer/net/communicator.h | 2 +- src/observer/net/mysql_communicator.cpp | 30 +- src/observer/net/mysql_communicator.h | 2 +- src/observer/net/server.cpp | 6 +- src/observer/net/server.h | 2 +- src/observer/net/server_param.h | 5 +- src/observer/rc.cpp | 4 +- src/observer/rc.h | 12 +- src/observer/session/session.cpp | 4 +- src/observer/session/session.h | 5 +- src/observer/session/session_stage.cpp | 9 +- src/observer/session/session_stage.h | 10 +- src/observer/session/thread_data.cpp | 2 +- src/observer/session/thread_data.h | 2 +- .../sql/executor/command_executor.cpp | 36 ++ src/observer/sql/executor/command_executor.h | 29 + .../sql/executor/create_index_executor.cpp | 31 + .../sql/executor/create_index_executor.h | 29 + src/observer/sql/executor/execute_stage.cpp | 481 +------------- src/observer/sql/executor/execute_stage.h | 7 +- src/observer/sql/executor/sql_result.cpp | 31 +- src/observer/sql/executor/sql_result.h | 10 +- src/observer/sql/expr/expression.cpp | 2 +- src/observer/sql/expr/expression.h | 23 +- src/observer/sql/expr/tuple.h | 20 +- src/observer/sql/expr/tuple_cell.cpp | 2 +- src/observer/sql/expr/tuple_cell.h | 7 +- .../sql/operator/delete_logical_operator.cpp | 2 +- .../sql/operator/delete_logical_operator.h | 5 +- .../sql/operator/delete_physical_operator.cpp | 10 +- .../sql/operator/delete_physical_operator.h | 9 +- .../sql/operator/explain_logical_operator.h | 2 +- .../operator/explain_physical_operator.cpp | 8 +- .../sql/operator/explain_physical_operator.h | 7 +- .../operator/index_scan_physical_operator.cpp | 33 +- .../operator/index_scan_physical_operator.h | 20 +- .../sql/operator/insert_logical_operator.cpp | 20 + .../sql/operator/insert_logical_operator.h | 40 ++ .../sql/operator/insert_physical_operator.cpp | 27 +- .../sql/operator/insert_physical_operator.h | 16 +- .../sql/operator/join_logical_operator.h | 2 +- .../sql/operator/join_physical_operator.cpp | 9 +- .../sql/operator/join_physical_operator.h | 9 +- .../sql/operator/logical_operator.cpp | 2 +- src/observer/sql/operator/logical_operator.h | 9 +- .../sql/operator/physical_operator.cpp | 6 +- src/observer/sql/operator/physical_operator.h | 14 +- .../operator/predicate_logical_operator.cpp | 2 +- .../sql/operator/predicate_logical_operator.h | 5 +- .../operator/predicate_physical_operator.cpp | 6 +- .../operator/predicate_physical_operator.h | 7 +- .../sql/operator/project_logical_operator.cpp | 2 +- .../sql/operator/project_logical_operator.h | 5 +- .../operator/project_physical_operator.cpp | 6 +- .../sql/operator/project_physical_operator.h | 7 +- .../operator/string_list_physical_operator.h | 7 +- .../operator/table_get_logical_operator.cpp | 6 +- .../sql/operator/table_get_logical_operator.h | 14 +- .../operator/table_scan_physical_operator.cpp | 17 +- .../operator/table_scan_physical_operator.h | 22 +- .../comparison_simplification_rule.cpp | 2 +- .../comparison_simplification_rule.h | 5 +- .../conjunction_simplification_rule.cpp | 2 +- .../conjunction_simplification_rule.h | 5 +- .../sql/optimizer/expression_rewriter.cpp | 2 +- .../sql/optimizer/expression_rewriter.h | 5 +- src/observer/sql/optimizer/optimize_stage.cpp | 77 ++- src/observer/sql/optimizer/optimize_stage.h | 7 +- .../sql/optimizer/physical_plan_generator.cpp | 102 +-- .../sql/optimizer/physical_plan_generator.h | 16 +- .../optimizer/predicate_pushdown_rewriter.cpp | 2 +- .../optimizer/predicate_pushdown_rewriter.h | 5 +- .../sql/optimizer/predicate_rewrite.cpp | 2 +- .../sql/optimizer/predicate_rewrite.h | 5 +- src/observer/sql/optimizer/rewrite_rule.h | 2 +- src/observer/sql/optimizer/rewriter.cpp | 2 +- src/observer/sql/optimizer/rewriter.h | 5 +- src/observer/sql/parser/parse.cpp | 2 +- src/observer/sql/parser/parse.h | 2 +- src/observer/sql/parser/parse_defs.h | 65 +- src/observer/sql/parser/parse_stage.cpp | 7 +- src/observer/sql/parser/parse_stage.h | 2 +- src/observer/sql/parser/resolve_stage.cpp | 5 +- src/observer/sql/parser/resolve_stage.h | 7 +- .../sql/plan_cache/plan_cache_stage.cpp | 2 +- .../sql/plan_cache/plan_cache_stage.h | 7 +- .../sql/query_cache/query_cache_stage.cpp | 2 +- .../sql/query_cache/query_cache_stage.h | 7 +- src/observer/sql/stmt/create_index_stmt.cpp | 57 ++ src/observer/sql/stmt/create_index_stmt.h | 49 ++ src/observer/sql/stmt/delete_stmt.cpp | 2 +- src/observer/sql/stmt/delete_stmt.h | 2 +- src/observer/sql/stmt/explain_stmt.cpp | 2 +- src/observer/sql/stmt/explain_stmt.h | 5 +- src/observer/sql/stmt/filter_stmt.cpp | 2 +- src/observer/sql/stmt/filter_stmt.h | 2 +- src/observer/sql/stmt/insert_stmt.cpp | 11 +- src/observer/sql/stmt/insert_stmt.h | 5 +- src/observer/sql/stmt/select_stmt.cpp | 2 +- src/observer/sql/stmt/select_stmt.h | 5 +- src/observer/sql/stmt/stmt.cpp | 7 +- src/observer/sql/stmt/stmt.h | 12 +- src/observer/sql/stmt/update_stmt.cpp | 2 +- src/observer/sql/stmt/update_stmt.h | 5 +- src/observer/storage/buffer/frame.cpp | 86 ++- src/observer/storage/buffer/frame.h | 24 +- src/observer/storage/buffer/page.h | 2 +- src/observer/storage/clog/clog.cpp | 4 +- src/observer/storage/clog/clog.h | 4 +- .../storage/common/condition_filter.cpp | 4 +- .../storage/common/condition_filter.h | 21 +- src/observer/storage/common/db.cpp | 6 +- src/observer/storage/common/db.h | 7 +- src/observer/storage/common/field.cpp | 33 + src/observer/storage/common/field.h | 8 +- src/observer/storage/common/field_meta.cpp | 8 +- src/observer/storage/common/field_meta.h | 6 +- src/observer/storage/common/index_meta.cpp | 4 +- src/observer/storage/common/index_meta.h | 11 +- src/observer/storage/common/meta_util.cpp | 4 +- src/observer/storage/common/meta_util.h | 9 +- src/observer/storage/common/table.cpp | 609 +++--------------- src/observer/storage/common/table.h | 56 +- src/observer/storage/common/table_meta.cpp | 68 +- src/observer/storage/common/table_meta.h | 15 +- .../storage/default/default_handler.cpp | 56 -- .../storage/default/default_handler.h | 56 +- .../storage/default/default_storage_stage.cpp | 46 +- .../storage/default/default_storage_stage.h | 8 +- .../storage/default/disk_buffer_pool.cpp | 34 +- .../storage/default/disk_buffer_pool.h | 2 + src/observer/storage/index/bplus_tree.h | 2 + .../storage/index/bplus_tree_index.cpp | 4 +- src/observer/storage/index/bplus_tree_index.h | 9 +- src/observer/storage/index/index.cpp | 4 +- src/observer/storage/index/index.h | 7 +- .../storage/mem/mem_storage_stage.cpp | 2 +- src/observer/storage/mem/mem_storage_stage.h | 7 +- src/observer/storage/persist/persist.cpp | 2 +- src/observer/storage/persist/persist.h | 10 +- src/observer/storage/record/record.h | 62 +- .../storage/record/record_manager.cpp | 116 +++- src/observer/storage/record/record_manager.h | 46 +- src/observer/storage/trx/latch_memo.cpp | 2 +- src/observer/storage/trx/latch_memo.h | 6 +- src/observer/storage/trx/mvcc_trx.cpp | 271 ++++++++ src/observer/storage/trx/mvcc_trx.h | 81 +++ src/observer/storage/trx/trx.cpp | 272 +------- src/observer/storage/trx/trx.h | 112 ++-- src/observer/storage/trx/vacuous_trx.cpp | 64 ++ src/observer/storage/trx/vacuous_trx.h | 45 ++ test/perf/client_performance_test.cpp | 2 +- unittest/bitmap_test.cpp | 2 +- unittest/bp_manager_test.cpp | 2 +- unittest/bplus_tree_test.cpp | 2 +- unittest/clog_test.cpp | 4 +- unittest/log_test.cpp | 2 +- unittest/log_test.h | 2 +- unittest/lower_bound_test.cpp | 2 +- unittest/md5_test.cpp | 2 +- unittest/md5_test.h | 2 +- unittest/mem_pool_test.cpp | 2 +- unittest/path_test.cpp | 2 +- unittest/persist_test.cpp | 2 +- unittest/pidfile_test.cpp | 2 +- unittest/rc_test.cpp | 3 +- unittest/record_manager_test.cpp | 10 +- unittest/thread_test.h | 5 +- 292 files changed, 3235 insertions(+), 2403 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 benchmark/integer_generator.h create mode 100644 benchmark/record_manager_concurrency_test.cpp create mode 100644 benchmark/server_concurrency_test.cpp create mode 100644 docs/miniob-transaction.md create mode 100644 src/observer/sql/executor/command_executor.cpp create mode 100644 src/observer/sql/executor/command_executor.h create mode 100644 src/observer/sql/executor/create_index_executor.cpp create mode 100644 src/observer/sql/executor/create_index_executor.h create mode 100644 src/observer/sql/operator/insert_logical_operator.cpp create mode 100644 src/observer/sql/operator/insert_logical_operator.h create mode 100644 src/observer/sql/stmt/create_index_stmt.cpp create mode 100644 src/observer/sql/stmt/create_index_stmt.h create mode 100644 src/observer/storage/common/field.cpp create mode 100644 src/observer/storage/trx/mvcc_trx.cpp create mode 100644 src/observer/storage/trx/mvcc_trx.h create mode 100644 src/observer/storage/trx/vacuous_trx.cpp create mode 100644 src/observer/storage/trx/vacuous_trx.h diff --git a/.gitignore b/.gitignore index 2e52092..005c0c1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ build/* build_* cmake-build-*/* -.vscode/* .DS_Store .idea .ccls-cache diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..eadaf1d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug", + "program": "${workspaceFolder}/${defaultBuildTask}/bin/observer", + "args": ["-f", "${workspaceFolder}/etc/observer.ini", "-s", "miniob.sock"], + "cwd": "${workspaceFolder}/${defaultBuildTask}/" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..29d97a2 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,32 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "init", + "type": "shell", + "command": "sudo -E env PATH=$PATH bash ${workspaceFolder}/build.sh init" + }, + { + "label": "build_debug", + "type": "shell", + "command": "bash build.sh debug", + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "build_release", + "type": "shell", + "command": "bash build.sh release" + }, + { + "label": "build_release_asan", + "type": "shell", + "command": "bash build.sh release_asan" + } + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 03de195..64131dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,6 @@ ELSE() ENDIF(WIN32) # This is for clangd plugin for vscode -#SET(CMAKE_COMMON_FLAGS ${CMAKE_COMMON_FLAGS} " -Wstring-plus-int -Wsizeof-array-argument -Wunused-variable -Wmissing-braces") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -DCMAKE_EXPORT_COMPILE_COMMANDS=1") IF(DEBUG) MESSAGE("DEBUG has been set as TRUE ${DEBUG}") diff --git a/NOTICE b/NOTICE index 3fb18a5..f278328 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,6 @@ OceanBase miniob -Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under [Mulan PSL v2.](http://license.coscl.org.cn/MulanPSL2) @@ -114,3 +114,19 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================== googl benchmark =========================== + +Copyright 2015 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/benchmark/bplus_tree_concurrency_test.cpp b/benchmark/bplus_tree_concurrency_test.cpp index a5637bd..cc92352 100644 --- a/benchmark/bplus_tree_concurrency_test.cpp +++ b/benchmark/bplus_tree_concurrency_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,7 +12,6 @@ See the Mulan PSL v2 for more details. */ // Created by Wangyunlai on 2023/03/14 // #include -#include #include #include @@ -20,28 +19,12 @@ See the Mulan PSL v2 for more details. */ #include "storage/default/disk_buffer_pool.h" #include "rc.h" #include "common/log/log.h" +#include "integer_generator.h" using namespace std; using namespace common; using namespace benchmark; -class IntegerGenerator -{ -public: - IntegerGenerator(int min, int max) - : distrib_(min, max) - {} - - int next() - { - return distrib_(rd_); - } - -private: - random_device rd_; - uniform_int_distribution<> distrib_; -}; - once_flag init_bpm_flag; BufferPoolManager bpm{512}; @@ -116,7 +99,7 @@ public: for (uint32_t value = min; value < max; ++value) { const char *key = reinterpret_cast(&value); RID rid(value, value); - RC rc = handler_.insert_entry(key, &rid); + [[maybe_unused]] RC rc = handler_.insert_entry(key, &rid); ASSERT(rc == RC::SUCCESS, "failed to insert entry into btree. key=%" PRIu32, value); } } diff --git a/benchmark/integer_generator.h b/benchmark/integer_generator.h new file mode 100644 index 0000000..1747e08 --- /dev/null +++ b/benchmark/integer_generator.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/05/04 +// +#include + +class IntegerGenerator +{ +public: + IntegerGenerator(int min, int max) + : distrib_(min, max) + {} + + int next() + { + return distrib_(rd_); + } + +private: + std::random_device rd_; + std::uniform_int_distribution<> distrib_; +}; \ No newline at end of file diff --git a/benchmark/record_manager_concurrency_test.cpp b/benchmark/record_manager_concurrency_test.cpp new file mode 100644 index 0000000..b14cae5 --- /dev/null +++ b/benchmark/record_manager_concurrency_test.cpp @@ -0,0 +1,417 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/05/04 +// + +#include +#include +#include +#include + +#include "storage/record/record_manager.h" +#include "storage/default/disk_buffer_pool.h" +#include "storage/common/condition_filter.h" +#include "storage/trx/vacuous_trx.h" +#include "rc.h" +#include "common/log/log.h" +#include "integer_generator.h" + +using namespace std; +using namespace common; +using namespace benchmark; + +once_flag init_bpm_flag; +BufferPoolManager bpm{512}; + +struct Stat +{ + int64_t insert_success_count = 0; + int64_t insert_other_count = 0; + + int64_t delete_success_count = 0; + int64_t not_exist_count = 0; + int64_t delete_other_count = 0; + + int64_t scan_success_count = 0; + int64_t scan_open_failed_count = 0; + int64_t mismatch_count = 0; + int64_t scan_other_count = 0; +}; + +struct TestRecord +{ + int32_t int_fields[15]; +}; + +class TestConditionFilter : public ConditionFilter +{ +public: + TestConditionFilter(int32_t begin, int32_t end) + : begin_(begin), end_(end) + {} + + bool filter(const Record &rec) const override + { + const char *data = rec.data(); + int32_t value = *(int32_t *)data; + return value >= begin_ && value <= end_; + } + +private: + int32_t begin_; + int32_t end_; +}; + +class BenchmarkBase : public Fixture +{ +public: + BenchmarkBase() + { + } + + virtual ~BenchmarkBase() + { + BufferPoolManager::set_instance(nullptr); + } + + virtual string Name() const = 0; + + string record_filename() const { return this->Name() + ".record"; } + + virtual void SetUp(const State &state) + { + if (0 != state.thread_index()) { + return; + } + + string log_name = this->Name() + ".log"; + string record_filename = this->record_filename(); + LoggerFactory::init_default(log_name.c_str(), LOG_LEVEL_TRACE); + + std::call_once(init_bpm_flag, []() { BufferPoolManager::set_instance(&bpm); }); + + ::remove(record_filename.c_str()); + + RC rc = bpm.create_file(record_filename.c_str()); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to create record buffer pool file. filename=%s, rc=%s", + record_filename.c_str(), strrc(rc)); + throw runtime_error("failed to create record buffer pool file."); + } + + rc = bpm.open_file(record_filename.c_str(), buffer_pool_); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to open record file. filename=%s, rc=%s", + record_filename.c_str(), strrc(rc)); + throw runtime_error("failed to open record file"); + } + + rc = handler_.init(buffer_pool_); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to init record file handler. rc=%s", strrc(rc)); + throw runtime_error("failed to init record file handler"); + } + LOG_INFO("test %s setup done. threads=%d, thread index=%d", + this->Name().c_str(), state.threads(), state.thread_index()); + } + + virtual void TearDown(const State &state) + { + if (0 != state.thread_index()) { + return; + } + + handler_.close(); + bpm.close_file(this->record_filename().c_str()); + buffer_pool_ = nullptr; + LOG_INFO("test %s teardown done. threads=%d, thread index=%d", + this->Name().c_str(), state.threads(), state.thread_index()); + } + + void FillUp(int32_t min, int32_t max, vector &rids) + { + rids.reserve(max - min); + RID rid; + TestRecord record; + vector record_values; + record_values.reserve(max - min); + for (int32_t value = min; value < max; ++value) { + record_values.push_back(value); + } + + random_device rd; + mt19937 random_generator(rd()); + shuffle(record_values.begin(), record_values.end(), random_generator); + + for (int32_t record_value : record_values) { + record.int_fields[0] = record_value; + [[maybe_unused]] RC rc = handler_.insert_record(reinterpret_cast(&record), sizeof(record), &rid); + ASSERT(rc == RC::SUCCESS, "failed to insert record into record file. record value=%" PRIu32, record_value); + rids.push_back(rid); + } + + LOG_INFO("fill up done. min=%" PRIu32 ", max=%" PRIu32 ", distance=%" PRIu32, min, max, (max-min)); + } + + uint32_t GetRangeMax(const State &state) const + { + uint32_t max = static_cast(state.range(0) * 3); + if (max <= 0) { + max = (1 << 31); + } + return max; + } + + void Insert(int32_t value, Stat &stat, RID &rid) + { + TestRecord record; + record.int_fields[0] = value; + RC rc = handler_.insert_record(reinterpret_cast(&record), sizeof(record), &rid); + switch (rc) { + case RC::SUCCESS: { + stat.insert_success_count++; + } break; + default: { + stat.insert_other_count++; + } break; + } + } + + void Delete(const RID &rid, Stat &stat) + { + RC rc = handler_.delete_record(&rid); + switch (rc) { + case RC::SUCCESS: { + stat.delete_success_count++; + } break; + case RC::RECORD_RECORD_NOT_EXIST: { + stat.not_exist_count++; + } break; + default: { + stat.delete_other_count++; + } break; + } + } + + void Scan(int32_t begin, int32_t end, Stat &stat) + { + TestConditionFilter condition_filter(begin, end); + RecordFileScanner scanner; + VacuousTrx trx; + RC rc = scanner.open_scan(nullptr/*table*/, *buffer_pool_, &trx, true/*readonly*/, &condition_filter); + if (rc != RC::SUCCESS) { + stat.scan_open_failed_count++; + } else { + Record record; + int32_t count = 0; + while (scanner.has_next()) { + rc = scanner.next(record); + ASSERT(rc == RC::SUCCESS, "failed to get record, rc=%s", strrc(rc)); + count++; + } + + if (rc != RC::SUCCESS) { + stat.scan_other_count++; + } else if (count != (end - begin + 1)) { + stat.mismatch_count++; + } else { + stat.scan_success_count++; + } + + scanner.close_scan(); + } + } + +protected: + DiskBufferPool * buffer_pool_ = nullptr; + RecordFileHandler handler_; +}; + +//////////////////////////////////////////////////////////////////////////////// + +struct InsertionBenchmark : public BenchmarkBase +{ + string Name() const override { return "insertion"; } +}; + +BENCHMARK_DEFINE_F(InsertionBenchmark, Insertion) (State &state) +{ + IntegerGenerator generator(1, 1 << 31); + Stat stat; + + RID rid; + for (auto _ : state) { + Insert(generator.next(), stat, rid); + } + + state.counters["success"] = Counter(stat.insert_success_count, Counter::kIsRate); + state.counters["other"] = Counter(stat.insert_other_count, Counter::kIsRate); +} + +BENCHMARK_REGISTER_F(InsertionBenchmark, Insertion)->Threads(10); + +//////////////////////////////////////////////////////////////////////////////// + +class DeletionBenchmark : public BenchmarkBase +{ +public: + + string Name() const override { return "deletion"; } + + void SetUp(const State &state) override + { + if (0 != state.thread_index()) { + return; + } + + BenchmarkBase::SetUp(state); + + uint32_t max = GetRangeMax(state); + ASSERT(max > 0, "invalid argument count. %ld", state.range(0)); + FillUp(0, max, rids_); + } + +protected: + vector rids_; +}; + +BENCHMARK_DEFINE_F(DeletionBenchmark, Deletion) (State &state) +{ + IntegerGenerator generator(0, static_cast(rids_.size())); + Stat stat; + + for (auto _ : state) { + int32_t value = generator.next(); + RID rid = rids_[value]; + Delete(rid, stat); + } + + state.counters["success"] = Counter(stat.delete_success_count, Counter::kIsRate); + state.counters["not_exist"] = Counter(stat.not_exist_count, Counter::kIsRate); + state.counters["other"] = Counter(stat.delete_other_count, Counter::kIsRate); +} + +BENCHMARK_REGISTER_F(DeletionBenchmark, Deletion)->Threads(10)->Arg(4* 10000); + +//////////////////////////////////////////////////////////////////////////////// + +class ScanBenchmark : public BenchmarkBase +{ +public: + + string Name() const override { return "scan"; } + + void SetUp(const State &state) override + { + if (0 != state.thread_index()) { + return; + } + + BenchmarkBase::SetUp(state); + + int32_t max = state.range(0) * 3; + ASSERT(max > 0, "invalid argument count. %ld", state.range(0)); + vector rids; + FillUp(0, max, rids); + } +}; + +BENCHMARK_DEFINE_F(ScanBenchmark, Scan) (State &state) +{ + int max_range_size = 100; + uint32_t max = GetRangeMax(state); + IntegerGenerator begin_generator(1, max - max_range_size); + IntegerGenerator range_generator(1, max_range_size); + Stat stat; + + for (auto _ : state) { + int32_t begin = begin_generator.next(); + int32_t end = begin + range_generator.next(); + Scan(begin, end, stat); + } + + state.counters["success"] = Counter(stat.scan_success_count, Counter::kIsRate); + state.counters["open_failed_count"] = Counter(stat.scan_open_failed_count, Counter::kIsRate); + state.counters["mismatch_number_count"] = Counter(stat.mismatch_count, Counter::kIsRate); + state.counters["other"] = Counter(stat.scan_other_count, Counter::kIsRate); +} + +BENCHMARK_REGISTER_F(ScanBenchmark, Scan)->Threads(10)->Arg(4 * 10000); + +//////////////////////////////////////////////////////////////////////////////// + +struct MixtureBenchmark : public BenchmarkBase +{ + string Name() const override { return "mixture"; } +}; + +BENCHMARK_DEFINE_F(MixtureBenchmark, Mixture) (State &state) +{ + pair data_range{0, GetRangeMax(state)}; + pair scan_range{1, 100}; + + IntegerGenerator data_generator(data_range.first, data_range.second); + IntegerGenerator scan_range_generator(scan_range.first, scan_range.second); + IntegerGenerator operation_generator(0, 2); + + Stat stat; + + vector rids; + for (auto _ : state) { + int operation_type = operation_generator.next(); + switch (operation_type) { + case 0: { // insert + int32_t value = data_generator.next(); + RID rid; + Insert(value, stat, rid); + if (rids.size() < 1000000) { + rids.push_back(rid); + } + } break; + case 1: { // delete + int32_t index = data_generator.next(); + if (!rids.empty()) { + index %= rids.size(); + RID rid = rids[index]; + rids.erase(rids.begin() + index); + Delete(rid, stat); + } + } break; + case 2: { // scan + int32_t begin = data_generator.next(); + int32_t end = begin + scan_range_generator.next(); + Scan(begin, end, stat); + } break; + default: { + ASSERT(false, "should not happen. operation=%ld", operation_type); + } + } + } + + state.counters.insert({ + {"insert_success", Counter(stat.insert_success_count, Counter::kIsRate)}, + {"insert_other", Counter(stat.insert_other_count, Counter::kIsRate)}, + {"delete_success", Counter(stat.delete_success_count, Counter::kIsRate)}, + {"delete_other", Counter(stat.delete_other_count, Counter::kIsRate)}, + {"delete_not_exist", Counter(stat.not_exist_count, Counter::kIsRate)}, + {"scan_success", Counter(stat.scan_success_count, Counter::kIsRate)}, + {"scan_other", Counter(stat.scan_other_count, Counter::kIsRate)}, + {"scan_mismatch", Counter(stat.mismatch_count, Counter::kIsRate)}, + {"scan_open_failed", Counter(stat.scan_open_failed_count, Counter::kIsRate)} + }); +} + +BENCHMARK_REGISTER_F(MixtureBenchmark, Mixture)->Threads(10)->Arg(4 * 10000); + +//////////////////////////////////////////////////////////////////////////////// + +BENCHMARK_MAIN(); diff --git a/benchmark/server_concurrency_test.cpp b/benchmark/server_concurrency_test.cpp new file mode 100644 index 0000000..439c9f5 --- /dev/null +++ b/benchmark/server_concurrency_test.cpp @@ -0,0 +1,204 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/04/28 +// + +#if 0 +#include +#include +#include +#include + +#include +#include +#include + +#include "rc.h" +#include "common/log/log.h" + +using namespace std; +using namespace common; +using namespace benchmark; + +class Client +{ +public: + Client() = default; + virtual ~Client(); + + RC init(string host, int port); + RC init(string unix_socket); + + RC close(); + + RC send_sql(const char *sql); + RC receive_result(ostream &result_stream); + RC execute(const char *sql, ostream &result_stream); + +private: + string server_addr_; + int socket_ = -1; +}; + +class BenchmarkBase : public Fixture +{ +public: + BenchmarkBase() + {} + + virtual ~BenchmarkBase() + {} + + string Name() const override = 0; + void SetUp(const State &state) override + { + + } + + void TearDown(const State &state) override + { + + } +}; + +Client::~Client() +{ + this->close(); +} + +RC Client::init(string host, int port) +{ + struct hostent *host; + struct sockaddr_in serv_addr; + + if ((host = gethostbyname(host.c_str())) == NULL) { + LOG_WARN("failed to gethostbyname. rc=%s", strerror(errno)); + return RC::IOERR; + } + + int sockfd = -1; + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + LOG_WARN("failed to create socket. rc=%s", strerror(errno)); + return RC::IOERROR; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons((uint16_t)port); + serv_addr.sin_addr = *((struct in_addr *)host->h_addr); + + if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) { + LOG_WARN("failed to connect to server. rc=%s", strerror(errno)); + return RC::IOERROR; + } + + socket_ = sockfd; + server_addr_ = string("tcp://") + host + string(":") + to_string(port); + LOG_INFO("connect to server sucess"); + return RC::SUCCESS; +} + +RC Client::init(string unix_socket) +{ + int socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (socket_fd < 0) { + LOG_WARN("failed to create socket. rc=%s", strerror(errno)); + return RC::IOERROR; + } + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, unix_socket.c_str()); + + int ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)); + if (ret == -1) { + LOG_WARN("failed to connect to server. rc=%s", strerror(errno)); + return RC::IOERROR; + } + + socket_ = socket_fd; + server_addr_ = string("unix://") + unix_socket; + LOG_INFO("connect to unix socket success"); + return RC::SUCCESS; +} + +RC Client::close() +{ + if (socket_ >= 0) { + LOG_INFO("close connection. server addr: %s", server_addr_.c_str()); + ::close(socket_); + socket_ = -1; + } + return RC::SUCESS; +} + +RC Client::send_sql(const char *sql) +{ + int ret = writen(socket_, sql, strlen(sql) + 1); + if (ret != 0) { + LOG_WARN("failed to send sql to server. server=%s, rc=%s", server_addr_.c_str(), strerror(ret)); + return RC::IOERROR; + } + return RC::SUCCESS; +} + +RC Client::receive_result(ostream &result_stream) +{ + char tmp_buf[256]; + + // 持续接收消息,直到遇到'\0'。将'\0'遇到的后续数据直接丢弃没有处理,因为目前仅支持一收一发的模式 + int read_len = 0; + while (true) { + read_len = ::read(socket_, tmp_buf, sizeof(tmp_buf)); + if (read_len < 0) { + if (errno == EAGAIN) { + continue; + } + break; + } + if (read_len == 0) { + break; + } + + result_stream.write(tmp_buf, read_len); + + bool msg_end = false; + for (int i = 0; i < read_len; i++) { + if (tmp_buf[i] == 0) { + msg_end = true; + break; + } + } + + if (msg_end) { + break; + } + } +} + +RC Client::execute(const char *sql, ostream &result_stream) +{ + RC rc = this->send_sql(sql); + if (rc != RC::SUCCESS) { + return rc; + } + + return receive_result(result_stream); +} + +#endif + +int main(void) +{ + return 0; +} \ No newline at end of file diff --git a/build.sh b/build.sh index 76c140d..4aba907 100755 --- a/build.sh +++ b/build.sh @@ -1,6 +1,8 @@ #!/bin/bash -TOPDIR=`readlink -f \`dirname $0\`` +# readlink -f cannot work on mac +TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + BUILD_SH=$TOPDIR/build.sh CMAKE_COMMAND="cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1" @@ -17,7 +19,7 @@ function usage { echo "Usage:" echo "./build.sh -h" - echo "./build.sh init" + echo "./build.sh init # install dependence" echo "./build.sh clean" echo "./build.sh [BuildType] [--make [MakeOptions]]" echo "" @@ -75,7 +77,7 @@ function do_init # build libevent cd ${TOPDIR}/deps/3rd/libevent && \ git checkout release-2.1.12-stable && \ - mkdir build && \ + mkdir -p build && \ cd build && \ cmake .. -DEVENT__DISABLE_OPENSSL=ON && \ make -j4 && \ @@ -83,7 +85,7 @@ function do_init # build googletest cd ${TOPDIR}/deps/3rd/googletest && \ - mkdir build && \ + mkdir -p build && \ cd build && \ cmake .. && \ make -j4 && \ @@ -91,7 +93,7 @@ function do_init # build google benchmark cd ${TOPDIR}/deps/3rd/benchmark && \ - mkdir build && \ + mkdir -p build && \ cd build && \ cmake .. -DBENCHMARK_ENABLE_TESTING=OFF -DBENCHMARK_INSTALL_DOCS=OFF -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_USE_BUNDLED_GTEST=OFF -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF && \ make -j4 && \ @@ -99,7 +101,7 @@ function do_init # build jsoncpp cd ${TOPDIR}/deps/3rd/jsoncpp && \ - mkdir build && \ + mkdir -p build && \ cd build && \ cmake -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF .. && \ make && \ @@ -119,7 +121,7 @@ function do_build TYPE=$1; shift prepare_build_dir $TYPE || return echo "${CMAKE_COMMAND} ${TOPDIR} $@" - ${CMAKE_COMMAND} ${TOPDIR} $@ + ${CMAKE_COMMAND} -S ${TOPDIR} $@ } function do_clean diff --git a/deps/3rd/libevent b/deps/3rd/libevent index 6e1826d..5df3037 160000 --- a/deps/3rd/libevent +++ b/deps/3rd/libevent @@ -1 +1 @@ -Subproject commit 6e1826dd7730330536e1838824bddd0d4d8adb0d +Subproject commit 5df3037d10556bfcb675bc73e516978b75fc7bc7 diff --git a/deps/common/conf/ini.cpp b/deps/common/conf/ini.cpp index 8964908..3e8d84e 100644 --- a/deps/common/conf/ini.cpp +++ b/deps/common/conf/ini.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/conf/ini.h b/deps/common/conf/ini.h index 225a686..384e3c3 100644 --- a/deps/common/conf/ini.h +++ b/deps/common/conf/ini.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/defs.h b/deps/common/defs.h index 1c8be6a..087395a 100644 --- a/deps/common/defs.h +++ b/deps/common/defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_DEFS_H__ -#define __COMMON_DEFS_H__ +#pragma once #include #include @@ -85,4 +84,3 @@ typedef long long s64_t; #define EPSILON (1E-6) } // namespace common -#endif //__COMMON_DEFS_H__ diff --git a/deps/common/io/io.cpp b/deps/common/io/io.cpp index 6cfb113..916671d 100644 --- a/deps/common/io/io.cpp +++ b/deps/common/io/io.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/io/io.h b/deps/common/io/io.h index 390551c..28af6ce 100644 --- a/deps/common/io/io.h +++ b/deps/common/io/io.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_IO_IO_H__ -#define __COMMON_IO_IO_H__ +#pragma once #include #include @@ -58,8 +57,15 @@ int touch(const std::string &fileName); */ int getFileSize(const char *filePath, u64_t &fileLen); +/** + * @brief 一次性写入所有指定数据 + * + * @param fd 写入的描述符 + * @param buf 写入的数据 + * @param size 写入多少数据 + * @return int 0 表示成功,否则返回errno + */ int writen(int fd, const void *buf, int size); int readn(int fd, void *buf, int size); } // namespace common -#endif /* __COMMON_IO_IO_H__ */ diff --git a/deps/common/io/roll_select_dir.cpp b/deps/common/io/roll_select_dir.cpp index 0390c5c..7b33fef 100644 --- a/deps/common/io/roll_select_dir.cpp +++ b/deps/common/io/roll_select_dir.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/io/roll_select_dir.h b/deps/common/io/roll_select_dir.h index 127bd90..bac1bca 100644 --- a/deps/common/io/roll_select_dir.h +++ b/deps/common/io/roll_select_dir.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/io/select_dir.h b/deps/common/io/select_dir.h index db6f659..d544d10 100644 --- a/deps/common/io/select_dir.h +++ b/deps/common/io/select_dir.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_IO_SELECT_DIR_H__ -#define __COMMON_IO_SELECT_DIR_H__ +#pragma once #include namespace common { @@ -28,4 +27,3 @@ public: }; } // namespace common -#endif /* __COMMON_IO_SELECT_DIR_H__ */ diff --git a/deps/common/lang/bitmap.cpp b/deps/common/lang/bitmap.cpp index 57dbbe7..b3f493c 100644 --- a/deps/common/lang/bitmap.cpp +++ b/deps/common/lang/bitmap.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/bitmap.h b/deps/common/lang/bitmap.h index 6c05be9..012302d 100644 --- a/deps/common/lang/bitmap.h +++ b/deps/common/lang/bitmap.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by wangyunlai on 2021/5/7. // -#ifndef __COMMON_LANG_BITMAP_H__ -#define __COMMON_LANG_BITMAP_H__ +#pragma once namespace common { @@ -39,5 +38,3 @@ private: }; } // namespace common - -#endif // __COMMON_LANG_BITMAP_H__ diff --git a/deps/common/lang/comparator.cpp b/deps/common/lang/comparator.cpp index b23d575..8ebd04c 100644 --- a/deps/common/lang/comparator.cpp +++ b/deps/common/lang/comparator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -60,4 +60,4 @@ int compare_string(void *arg1, int arg1_max_length, void *arg2, int arg2_max_len return 0; } -} \ No newline at end of file +} // namespace common diff --git a/deps/common/lang/comparator.h b/deps/common/lang/comparator.h index 35e0cc9..0371165 100644 --- a/deps/common/lang/comparator.h +++ b/deps/common/lang/comparator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/defer.h b/deps/common/lang/defer.h index 6290cbd..d103dfc 100644 --- a/deps/common/lang/defer.h +++ b/deps/common/lang/defer.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/lower_bound.h b/deps/common/lang/lower_bound.h index 5ebbe68..8eb6324 100644 --- a/deps/common/lang/lower_bound.h +++ b/deps/common/lang/lower_bound.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/lru_cache.h b/deps/common/lang/lru_cache.h index f3b06a9..b5c28c0 100644 --- a/deps/common/lang/lru_cache.h +++ b/deps/common/lang/lru_cache.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/mutex.cpp b/deps/common/lang/mutex.cpp index 7a5dd4d..a632d30 100644 --- a/deps/common/lang/mutex.cpp +++ b/deps/common/lang/mutex.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -347,4 +347,85 @@ void SharedMutex::unlock_shared() #endif // CONCURRENCY end -} // namespace common \ No newline at end of file +//////////////////////////////////////////////////////////////////////////////// +#ifndef CONCURRENCY +void RecursiveSharedMutex::lock_shared() +{} + +bool RecursiveSharedMutex::try_lock_shared() +{ + return true; +} + +void RecursiveSharedMutex::unlock_shared() +{} + +void RecursiveSharedMutex::lock() +{} + +void RecursiveSharedMutex::unlock() +{} + +#else // ifdef CONCURRENCY + +void RecursiveSharedMutex::lock_shared() +{ + unique_lock lock(mutex_); + while (exclusive_lock_count_ > 0) { + shared_lock_cv_.wait(lock); + } + shared_lock_count_++; +} + +bool RecursiveSharedMutex::try_lock_shared() +{ + unique_lock lock(mutex_); + if (exclusive_lock_count_ == 0) { + shared_lock_count_++; + return true; + } + return false; +} + +void RecursiveSharedMutex::unlock_shared() +{ + unique_lock lock(mutex_); + shared_lock_count_--; + if (shared_lock_count_ == 0) { + exclusive_lock_cv_.notify_one(); + } +} + +void RecursiveSharedMutex::lock() +{ + unique_lock lock(mutex_); + while (shared_lock_count_ > 0 || exclusive_lock_count_ > 0) { + if (recursive_owner_ == this_thread::get_id()) { + recursive_count_++; + return; + } + exclusive_lock_cv_.wait(lock); + } + recursive_owner_ = this_thread::get_id(); + recursive_count_ = 1; + exclusive_lock_count_++; +} + +void RecursiveSharedMutex::unlock() +{ + unique_lock lock(mutex_); + if (recursive_owner_ == this_thread::get_id() && recursive_count_ > 1) { + recursive_count_--; + } else { + recursive_owner_ = thread::id(); + recursive_count_ = 0; + exclusive_lock_count_--; + if (exclusive_lock_count_ == 0) { + shared_lock_cv_.notify_all(); + exclusive_lock_cv_.notify_one(); + } + } +} +#endif // CONCURRENCY + +} // namespace common diff --git a/deps/common/lang/mutex.h b/deps/common/lang/mutex.h index 0635e2d..78bf81c 100644 --- a/deps/common/lang/mutex.h +++ b/deps/common/lang/mutex.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -18,15 +18,18 @@ See the Mulan PSL v2 for more details. */ #include #include #include +#include #include -#include #include #include #include #include +#include #include "common/log/log.h" +using namespace std; + namespace common { #define MUTEX_LOG LOG_DEBUG @@ -290,4 +293,35 @@ private: #endif }; -} // namespace common \ No newline at end of file +/** + * 支持写锁递归加锁的读写锁 + * 读锁本身就可以递归加锁。但是某个线程加了读锁后,也不能再加写锁。 + * 但是一个线程可以加多次写锁 + * 与其它类型的锁一样,在CONCURRENCY编译模式下才会真正的生效 + */ +class RecursiveSharedMutex +{ + public: + RecursiveSharedMutex() = default; + ~RecursiveSharedMutex() = default; + + void lock_shared(); + bool try_lock_shared(); + void unlock_shared(); + + void lock(); + void unlock(); + +private: +#ifdef CONCURRENCY + std::mutex mutex_; + std::condition_variable shared_lock_cv_; + std::condition_variable exclusive_lock_cv_; + int shared_lock_count_ = 0; + int exclusive_lock_count_ = 0; + std::thread::id recursive_owner_; + int recursive_count_ = 0; // 表示当前线程加写锁加了多少次 +#endif // CONCURRENCY +}; + +} // namespace common diff --git a/deps/common/lang/serializable.h b/deps/common/lang/serializable.h index a1333fa..feba9fd 100644 --- a/deps/common/lang/serializable.h +++ b/deps/common/lang/serializable.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/string.cpp b/deps/common/lang/string.cpp index ae0e38d..8e0d53f 100644 --- a/deps/common/lang/string.cpp +++ b/deps/common/lang/string.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/lang/string.h b/deps/common/lang/string.h index bbf8235..d19295a 100644 --- a/deps/common/lang/string.h +++ b/deps/common/lang/string.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_LANG_STRING_H__ -#define __COMMON_LANG_STRING_H__ +#pragma once // Basic includes #include @@ -173,4 +172,3 @@ std::string get_type_name(const T &val) } } // namespace common -#endif // __COMMON_LANG_STRING_H__ diff --git a/deps/common/log/log.cpp b/deps/common/log/log.cpp index 703e973..2d27343 100644 --- a/deps/common/log/log.cpp +++ b/deps/common/log/log.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -29,7 +29,7 @@ Log::Log(const std::string &log_file_name, const LOG_LEVEL log_level, const LOG_ { prefix_map_[LOG_LEVEL_PANIC] = "PANIC:"; prefix_map_[LOG_LEVEL_ERR] = "ERROR:"; - prefix_map_[LOG_LEVEL_WARN] = "WARNNING:"; + prefix_map_[LOG_LEVEL_WARN] = "WARN:"; prefix_map_[LOG_LEVEL_INFO] = "INFO:"; prefix_map_[LOG_LEVEL_DEBUG] = "DEBUG:"; prefix_map_[LOG_LEVEL_TRACE] = "TRACE:"; @@ -365,4 +365,4 @@ const char *lbt() return backtrace_buffer; } -} // namespace common \ No newline at end of file +} // namespace common diff --git a/deps/common/log/log.h b/deps/common/log/log.h index 8f9327e..35c56e7 100644 --- a/deps/common/log/log.h +++ b/deps/common/log/log.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -294,15 +294,18 @@ int Log::out(const LOG_LEVEL console_level, const LOG_LEVEL log_level, T &msg) #define ASSERT(expression, description, ...) \ do { \ if (!(expression)) { \ - if (common::g_log) { \ - LOG_PANIC(description, ##__VA_ARGS__); \ - } \ + LOG_PANIC(description, ##__VA_ARGS__); \ assert(expression); \ } \ } while (0) #else // DEBUG -#define ASSERT(expression, description, ...) +#define ASSERT(expression, description, ...) \ + do { \ + if (!(expression)) { \ + LOG_ERROR(description, ##__VA_ARGS__); \ + } \ + } while (0) #endif // DEBUG #endif // ASSERT diff --git a/deps/common/math/md5.cpp b/deps/common/math/md5.cpp index 5777bd3..b241eb4 100644 --- a/deps/common/math/md5.cpp +++ b/deps/common/math/md5.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/math/md5.h b/deps/common/math/md5.h index 2c2f0bc..8cf37aa 100644 --- a/deps/common/math/md5.h +++ b/deps/common/math/md5.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/math/random_generator.cpp b/deps/common/math/random_generator.cpp index b8f2432..78f2fec 100644 --- a/deps/common/math/random_generator.cpp +++ b/deps/common/math/random_generator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/math/random_generator.h b/deps/common/math/random_generator.h index 43b26cd..8e44a9a 100644 --- a/deps/common/math/random_generator.h +++ b/deps/common/math/random_generator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/math/regex.cpp b/deps/common/math/regex.cpp index 590add9..df12f7d 100644 --- a/deps/common/math/regex.cpp +++ b/deps/common/math/regex.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/math/regex.h b/deps/common/math/regex.h index 08b8e4f..e1ec139 100644 --- a/deps/common/math/regex.h +++ b/deps/common/math/regex.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/console_reporter.cpp b/deps/common/metrics/console_reporter.cpp index 36ab11e..e8abd08 100644 --- a/deps/common/metrics/console_reporter.cpp +++ b/deps/common/metrics/console_reporter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/console_reporter.h b/deps/common/metrics/console_reporter.h index 9d0af23..eb1d5bd 100644 --- a/deps/common/metrics/console_reporter.h +++ b/deps/common/metrics/console_reporter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/histogram_snapshot.cpp b/deps/common/metrics/histogram_snapshot.cpp index 48ad01d..9845495 100644 --- a/deps/common/metrics/histogram_snapshot.cpp +++ b/deps/common/metrics/histogram_snapshot.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/histogram_snapshot.h b/deps/common/metrics/histogram_snapshot.h index df6a63b..747d28a 100644 --- a/deps/common/metrics/histogram_snapshot.h +++ b/deps/common/metrics/histogram_snapshot.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/log_reporter.cpp b/deps/common/metrics/log_reporter.cpp index 8873a04..8bc6fe9 100644 --- a/deps/common/metrics/log_reporter.cpp +++ b/deps/common/metrics/log_reporter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/log_reporter.h b/deps/common/metrics/log_reporter.h index 99f9357..f5cd750 100644 --- a/deps/common/metrics/log_reporter.h +++ b/deps/common/metrics/log_reporter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/metric.h b/deps/common/metrics/metric.h index e5ab5d7..b9507f0 100644 --- a/deps/common/metrics/metric.h +++ b/deps/common/metrics/metric.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/metrics.cpp b/deps/common/metrics/metrics.cpp index e97f035..7dc7dac 100644 --- a/deps/common/metrics/metrics.cpp +++ b/deps/common/metrics/metrics.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/metrics.h b/deps/common/metrics/metrics.h index 98c2195..fa340bc 100644 --- a/deps/common/metrics/metrics.h +++ b/deps/common/metrics/metrics.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/metrics_registry.cpp b/deps/common/metrics/metrics_registry.cpp index e2a6cf6..94bc41d 100644 --- a/deps/common/metrics/metrics_registry.cpp +++ b/deps/common/metrics/metrics_registry.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/metrics_registry.h b/deps/common/metrics/metrics_registry.h index f4ba40b..45b15c5 100644 --- a/deps/common/metrics/metrics_registry.h +++ b/deps/common/metrics/metrics_registry.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/reporter.cpp b/deps/common/metrics/reporter.cpp index b470e15..e020fcf 100644 --- a/deps/common/metrics/reporter.cpp +++ b/deps/common/metrics/reporter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/reporter.h b/deps/common/metrics/reporter.h index b5c957c..4153258 100644 --- a/deps/common/metrics/reporter.h +++ b/deps/common/metrics/reporter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/reservoir.cpp b/deps/common/metrics/reservoir.cpp index be4b546..3624f08 100644 --- a/deps/common/metrics/reservoir.cpp +++ b/deps/common/metrics/reservoir.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/reservoir.h b/deps/common/metrics/reservoir.h index 6102a60..3341c38 100644 --- a/deps/common/metrics/reservoir.h +++ b/deps/common/metrics/reservoir.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/sampler.cpp b/deps/common/metrics/sampler.cpp index a7efe24..f8a59e7 100644 --- a/deps/common/metrics/sampler.cpp +++ b/deps/common/metrics/sampler.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/sampler.h b/deps/common/metrics/sampler.h index 06c7047..5fb3dde 100644 --- a/deps/common/metrics/sampler.h +++ b/deps/common/metrics/sampler.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/snapshot.h b/deps/common/metrics/snapshot.h index 44664c8..07864be 100644 --- a/deps/common/metrics/snapshot.h +++ b/deps/common/metrics/snapshot.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/20. // -#ifndef __COMMON_METRICS_SNAPSHOT_H__ -#define __COMMON_METRICS_SNAPSHOT_H__ +#pragma once #include #include "common/lang/string.h" @@ -80,4 +79,3 @@ private: double tps = 1.0; }; } // namespace common -#endif //__COMMON_METRICS_SNAPSHOT_H__ diff --git a/deps/common/metrics/timer_snapshot.cpp b/deps/common/metrics/timer_snapshot.cpp index cb9baf7..1b10b36 100644 --- a/deps/common/metrics/timer_snapshot.cpp +++ b/deps/common/metrics/timer_snapshot.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/timer_snapshot.h b/deps/common/metrics/timer_snapshot.h index fe074e3..01d6688 100644 --- a/deps/common/metrics/timer_snapshot.h +++ b/deps/common/metrics/timer_snapshot.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/20. // -#ifndef __COMMON_METRICS_TIMER_SNAPSHOT_H__ -#define __COMMON_METRICS_TIMER_SNAPSHOT_H__ +#pragma once #include "common/metrics/histogram_snapshot.h" @@ -32,4 +31,3 @@ protected: double tps = 1.0; }; } // namespace common -#endif //__COMMON_METRICS_TIMER_SNAPSHOT_H__ diff --git a/deps/common/metrics/uniform_reservoir.cpp b/deps/common/metrics/uniform_reservoir.cpp index c2c05e9..926d3d3 100644 --- a/deps/common/metrics/uniform_reservoir.cpp +++ b/deps/common/metrics/uniform_reservoir.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/metrics/uniform_reservoir.h b/deps/common/metrics/uniform_reservoir.h index 1e30679..924da90 100644 --- a/deps/common/metrics/uniform_reservoir.h +++ b/deps/common/metrics/uniform_reservoir.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -11,8 +11,7 @@ See the Mulan PSL v2 for more details. */ // // Created by Longda on 2021/4/20. // -#ifndef __COMMON_METRICS_UNIFORM_RESERVOIR_H_ -#define __COMMON_METRICS_UNIFORM_RESERVOIR_H_ +#pragma once #include @@ -57,5 +56,3 @@ protected: }; } // namespace common - -#endif /* __COMMON_METRICS_UNIFORM_RESERVOIR_H_ */ diff --git a/deps/common/mm/debug_new.h b/deps/common/mm/debug_new.h index 761f152..364f628 100644 --- a/deps/common/mm/debug_new.h +++ b/deps/common/mm/debug_new.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_MM_DEBUG_NEW_H__ -#define __COMMON_MM_DEBUG_NEW_H__ +#pragma once #include #include @@ -48,4 +47,3 @@ extern bool new_verbose_flag; // default to false: no verbose information extern bool new_autocheck_flag; // default to true: call check_leaks() on exit } // namespace common -#endif // __COMMON_MM_DEBUG_NEW_H__ diff --git a/deps/common/mm/mem.h b/deps/common/mm/mem.h index 7d00198..3617873 100644 --- a/deps/common/mm/mem.h +++ b/deps/common/mm/mem.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_MM_MEM_H__ -#define __COMMON_MM_MEM_H__ +#pragma once #include #include @@ -132,4 +131,3 @@ static void operator delete[](void *pointer); #endif /* MEM_DEBUG */ } // namespace common -#endif /* __COMMON_MM_MEM_H__ */ diff --git a/deps/common/mm/mem_pool.cpp b/deps/common/mm/mem_pool.cpp index cccdede..c5f6256 100644 --- a/deps/common/mm/mem_pool.cpp +++ b/deps/common/mm/mem_pool.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/mm/mem_pool.h b/deps/common/mm/mem_pool.h index 9ec41f7..2b6b3ad 100644 --- a/deps/common/mm/mem_pool.h +++ b/deps/common/mm/mem_pool.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -34,7 +34,8 @@ namespace common { typedef bool (*match)(void *item, void *input_arg); template -class MemPool { +class MemPool +{ public: MemPool(const char *tag) : name(tag) { @@ -110,10 +111,13 @@ protected: }; /** - * MemoryPoolSimple is a simple Memory Pool manager, + * MemoryPoolSimple is a simple Memory Pool manager + * The objects is constructed when creating the pool and destructed when the pool is cleanup. + * `alloc` calls T's `reinit` routine and `free` calls T's `reset` */ template -class MemPoolSimple : public MemPool { +class MemPoolSimple : public MemPool +{ public: MemPoolSimple(const char *tag) : MemPool(tag) {} @@ -189,9 +193,7 @@ int MemPoolSimple::init(bool dynamic, int pool_num, int item_num_per_pool) if (pool_num <= 0 || item_num_per_pool <= 0) { LOG_ERROR("Invalid arguments, pool_num:%d, item_num_per_pool:%d, this->name:%s.", - pool_num, - item_num_per_pool, - this->name.c_str()); + pool_num, item_num_per_pool, this->name.c_str()); return -1; } @@ -207,9 +209,7 @@ int MemPoolSimple::init(bool dynamic, int pool_num, int item_num_per_pool) this->dynamic = dynamic; LOG_INFO("Extend one pool, this->size:%d, item_num_per_pool:%d, this->name:%s.", - this->size, - item_num_per_pool, - this->name.c_str()); + this->size, item_num_per_pool, this->name.c_str()); return 0; } @@ -250,9 +250,7 @@ int MemPoolSimple::extend() if (pool == nullptr) { MUTEX_UNLOCK(&this->mutex); LOG_ERROR("Failed to extend memory pool, this->size:%d, item_num_per_pool:%d, this->name:%s.", - this->size, - item_num_per_pool, - this->name.c_str()); + this->size, item_num_per_pool, this->name.c_str()); return -1; } @@ -264,9 +262,7 @@ int MemPoolSimple::extend() MUTEX_UNLOCK(&this->mutex); LOG_INFO("Extend one pool, this->size:%d, item_num_per_pool:%d, this->name:%s.", - this->size, - item_num_per_pool, - this->name.c_str()); + this->size, item_num_per_pool, this->name.c_str()); return 0; } @@ -291,14 +287,14 @@ T *MemPoolSimple::alloc() used.insert(buffer); MUTEX_UNLOCK(&this->mutex); - new (buffer) T(); + buffer->reinit(); return buffer; } template void MemPoolSimple::free(T *buf) { - buf->~T(); + buf->reset(); MUTEX_LOCK(&this->mutex); @@ -330,7 +326,8 @@ std::string MemPoolSimple::to_string() return ss.str(); } -class MemPoolItem { +class MemPoolItem +{ public: using unique_ptr = std::unique_ptr>; diff --git a/deps/common/os/os.cpp b/deps/common/os/os.cpp index 102fb1d..f17ef49 100644 --- a/deps/common/os/os.cpp +++ b/deps/common/os/os.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/os/os.h b/deps/common/os/os.h index 0840d1e..33c653a 100644 --- a/deps/common/os/os.h +++ b/deps/common/os/os.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,8 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_OS_OS_H__ -#define __COMMON_OS_OS_H__ +#pragma once + namespace common { u32_t getCpuNum(); @@ -21,4 +21,3 @@ u32_t getCpuNum(); void print_stacktrace(); } // namespace common -#endif /* __COMMON_OS_OS_H__ */ diff --git a/deps/common/os/path.cpp b/deps/common/os/path.cpp index 95bd7c1..6735165 100644 --- a/deps/common/os/path.cpp +++ b/deps/common/os/path.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/os/path.h b/deps/common/os/path.h index 6b3d668..09a638b 100644 --- a/deps/common/os/path.h +++ b/deps/common/os/path.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/3/27. // -#ifndef __COMMON_OS_PATH_H__ -#define __COMMON_OS_PATH_H__ +#pragma once #include namespace common { @@ -68,4 +67,3 @@ bool check_directory(std::string &path); int list_file(const char *path, const char *filter_pattern, std::vector &files); // io/io.h::getFileList } // namespace common -#endif //__COMMON_OS_PATH_H__ diff --git a/deps/common/os/pidfile.cpp b/deps/common/os/pidfile.cpp index 313b0e6..7cbe0a4 100644 --- a/deps/common/os/pidfile.cpp +++ b/deps/common/os/pidfile.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/os/pidfile.h b/deps/common/os/pidfile.h index 629ee28..bc3cbe5 100644 --- a/deps/common/os/pidfile.h +++ b/deps/common/os/pidfile.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,8 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_OS_PIDFILE_H__ -#define __COMMON_OS_PIDFILE_H__ +#pragma once + namespace common { //! Generates a PID file for the current component @@ -37,4 +37,3 @@ void removePidFile(void); std::string &getPidPath(); } // namespace common -#endif // __COMMON_OS_PIDFILE_H__ diff --git a/deps/common/os/process.cpp b/deps/common/os/process.cpp index 3db298a..24d77ac 100644 --- a/deps/common/os/process.cpp +++ b/deps/common/os/process.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/os/process.h b/deps/common/os/process.h index 15db7ea..e992182 100644 --- a/deps/common/os/process.h +++ b/deps/common/os/process.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,8 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_OS_PROCESS_H__ -#define __COMMON_OS_PROCESS_H__ +#pragma once + namespace common { //! Get process Name @@ -43,4 +43,3 @@ int daemonize_service(const char *std_out_file, const char *std_err_file); void sys_log_redirect(const char *std_out_file, const char *std_err_file); } // namespace common -#endif //__COMMON_OS_PROCESS_H__ diff --git a/deps/common/os/process_param.cpp b/deps/common/os/process_param.cpp index a3606c5..e70d287 100644 --- a/deps/common/os/process_param.cpp +++ b/deps/common/os/process_param.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/os/process_param.h b/deps/common/os/process_param.h index 228916d..c5303cd 100644 --- a/deps/common/os/process_param.h +++ b/deps/common/os/process_param.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -120,6 +120,17 @@ public: return protocol_; } + void set_trx_kit_name(const char *kit_name) + { + if (kit_name) { + trx_kit_name_ = kit_name; + } + } + const std::string &trx_kit_name() const + { + return trx_kit_name_; + } + private: std::string std_out_; // The output file std::string std_err_; // The err output file @@ -130,6 +141,7 @@ private: int server_port_ = -1; // server port(if valid, will overwrite the port in the config file) std::string unix_socket_path_; std::string protocol_; + std::string trx_kit_name_; }; ProcessParam *&the_process_param(); diff --git a/deps/common/os/signal.cpp b/deps/common/os/signal.cpp index a4b2c67..f8c8d54 100644 --- a/deps/common/os/signal.cpp +++ b/deps/common/os/signal.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/os/signal.h b/deps/common/os/signal.h index 70801f1..1346d24 100644 --- a/deps/common/os/signal.h +++ b/deps/common/os/signal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_OS_SIGNAL_H__ -#define __COMMON_OS_SIGNAL_H__ +#pragma once #include @@ -42,4 +41,3 @@ void setSignalHandler(sighandler_t func); void setSignalHandler(int sig, sighandler_t func); } // namespace common -#endif /* __COMMON_OS_SIGNAL_H__ */ diff --git a/deps/common/seda/callback.cpp b/deps/common/seda/callback.cpp index afee205..c2637b7 100644 --- a/deps/common/seda/callback.cpp +++ b/deps/common/seda/callback.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/callback.h b/deps/common/seda/callback.h index 0f6372b..6117d1c 100644 --- a/deps/common/seda/callback.h +++ b/deps/common/seda/callback.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_CALLBACK_H__ -#define __COMMON_SEDA_CALLBACK_H__ +#pragma once // Include Files #include "common/defs.h" @@ -122,4 +121,3 @@ private: }; } // namespace common -#endif // __COMMON_SEDA_CALLBACK_H__ diff --git a/deps/common/seda/class_factory.h b/deps/common/seda/class_factory.h index 8b55824..53e93b1 100644 --- a/deps/common/seda/class_factory.h +++ b/deps/common/seda/class_factory.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_CLASS_FACTORY_H__ -#define __COMMON_SEDA_CLASS_FACTORY_H__ +#pragma once #include @@ -139,4 +138,3 @@ T *ClassFactory::make_instance(const std::string &tag) } } // namespace common -#endif // __COMMON_SEDA_CLASS_FACTORY_H__ diff --git a/deps/common/seda/event_dispatcher.cpp b/deps/common/seda/event_dispatcher.cpp index 59d6dc4..1cc6196 100644 --- a/deps/common/seda/event_dispatcher.cpp +++ b/deps/common/seda/event_dispatcher.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/event_dispatcher.h b/deps/common/seda/event_dispatcher.h index 5f93ae5..dab59ab 100644 --- a/deps/common/seda/event_dispatcher.h +++ b/deps/common/seda/event_dispatcher.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_EVENT_DISPATCHER_H__ -#define __COMMON_SEDA_EVENT_DISPATCHER_H__ +#pragma once // Include Files #include @@ -156,4 +155,3 @@ public: }; } // namespace common -#endif // __COMMON_SEDA_EVENT_DISPATCHER_H__ diff --git a/deps/common/seda/example_stage.cpp b/deps/common/seda/example_stage.cpp index bf84110..683aefe 100644 --- a/deps/common/seda/example_stage.cpp +++ b/deps/common/seda/example_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/example_stage.h b/deps/common/seda/example_stage.h index 41a7f5d..ce06948 100644 --- a/deps/common/seda/example_stage.h +++ b/deps/common/seda/example_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/13. // -#ifndef __COMMON_SEDA_EXAMPLE_STAGE_H__ -#define __COMMON_SEDA_EXAMPLE_STAGE_H__ +#pragma once #include "common/seda/stage.h" @@ -35,4 +34,4 @@ protected: void callback_event(StageEvent *event, CallbackContext *context); }; } // namespace common -#endif //__COMMON_SEDA_EXAMPLE_STAGE_H__ + diff --git a/deps/common/seda/init.cpp b/deps/common/seda/init.cpp index 8eb1d93..ac6bfe4 100644 --- a/deps/common/seda/init.cpp +++ b/deps/common/seda/init.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/init.h b/deps/common/seda/init.h index 640c04c..f66cb52 100644 --- a/deps/common/seda/init.h +++ b/deps/common/seda/init.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/kill_thread.cpp b/deps/common/seda/kill_thread.cpp index 0e63ebb..3d56a3f 100644 --- a/deps/common/seda/kill_thread.cpp +++ b/deps/common/seda/kill_thread.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/kill_thread.h b/deps/common/seda/kill_thread.h index 5bda3c0..6fe0b2a 100644 --- a/deps/common/seda/kill_thread.h +++ b/deps/common/seda/kill_thread.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_KILL_THREAD_H__ -#define __COMMON_SEDA_KILL_THREAD_H__ +#pragma once #include @@ -99,4 +98,3 @@ protected: }; } // namespace common -#endif // __COMMON_SEDA_KILL_THREAD_H__ diff --git a/deps/common/seda/metrics_report_event.cpp b/deps/common/seda/metrics_report_event.cpp index c199121..45f3a11 100644 --- a/deps/common/seda/metrics_report_event.cpp +++ b/deps/common/seda/metrics_report_event.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/metrics_report_event.h b/deps/common/seda/metrics_report_event.h index d2fecb0..f3991c6 100644 --- a/deps/common/seda/metrics_report_event.h +++ b/deps/common/seda/metrics_report_event.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/metrics_stage.cpp b/deps/common/seda/metrics_stage.cpp index bc3ec6c..6d9d9f1 100644 --- a/deps/common/seda/metrics_stage.cpp +++ b/deps/common/seda/metrics_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/metrics_stage.h b/deps/common/seda/metrics_stage.h index 601cbe9..b556ec6 100644 --- a/deps/common/seda/metrics_stage.h +++ b/deps/common/seda/metrics_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/seda_config.cpp b/deps/common/seda/seda_config.cpp index 540d3bc..4dbffd3 100644 --- a/deps/common/seda/seda_config.cpp +++ b/deps/common/seda/seda_config.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/seda_config.h b/deps/common/seda/seda_config.h index 1d26091..ed019a8 100644 --- a/deps/common/seda/seda_config.h +++ b/deps/common/seda/seda_config.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/seda_defs.h b/deps/common/seda/seda_defs.h index 045bff9..1e1c9ac 100644 --- a/deps/common/seda/seda_defs.h +++ b/deps/common/seda/seda_defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/21. // -#ifndef __COMMON_SEDA_SEDA_DEFS_H__ -#define __COMMON_SEDA_SEDA_DEFS_H__ +#pragma once #define SEDA_BASE_NAME "SEDA_BASE" #define THREAD_POOLS_NAME "ThreadPools" @@ -29,5 +28,3 @@ See the Mulan PSL v2 for more details. */ #define NEXT_STAGES "NextStages" #define DEFAULT_THREAD_POOL "DefaultThreads" #define METRCS_REPORT_INTERVAL "MetricsReportInterval" - -#endif //__COMMON_SEDA_SEDA_DEFS_H__ diff --git a/deps/common/seda/stage.cpp b/deps/common/seda/stage.cpp index 5ee48ef..8820188 100644 --- a/deps/common/seda/stage.cpp +++ b/deps/common/seda/stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/stage.h b/deps/common/seda/stage.h index af478f0..77f9b09 100644 --- a/deps/common/seda/stage.h +++ b/deps/common/seda/stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/stage_event.cpp b/deps/common/seda/stage_event.cpp index 1a92f8f..15929df 100644 --- a/deps/common/seda/stage_event.cpp +++ b/deps/common/seda/stage_event.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/stage_event.h b/deps/common/seda/stage_event.h index 16c152d..ffb86de 100644 --- a/deps/common/seda/stage_event.h +++ b/deps/common/seda/stage_event.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -11,8 +11,7 @@ See the Mulan PSL v2 for more details. */ // // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_STAGE_EVENT_H__ -#define __COMMON_SEDA_STAGE_EVENT_H__ +#pragma once // Include Files #include @@ -177,4 +176,3 @@ bool &get_event_history_flag(); u32_t &get_max_event_hops(); } // namespace common -#endif // __COMMON_SEDA_STAGE_EVENT_H__ diff --git a/deps/common/seda/stage_factory.h b/deps/common/seda/stage_factory.h index 6ca5a57..4d95e9b 100644 --- a/deps/common/seda/stage_factory.h +++ b/deps/common/seda/stage_factory.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_STAGE_FACTORY_H__ -#define __COMMON_SEDA_STAGE_FACTORY_H__ +#pragma once #include "common/seda/class_factory.h" #include "common/seda/stage.h" @@ -24,4 +23,3 @@ class Stage; typedef ClassFactory StageFactory; } // namespace common -#endif // __COMMON_SEDA_STAGE_FACTORY_H__ diff --git a/deps/common/seda/thread_pool.cpp b/deps/common/seda/thread_pool.cpp index 5dec02b..eddca27 100644 --- a/deps/common/seda/thread_pool.cpp +++ b/deps/common/seda/thread_pool.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/thread_pool.h b/deps/common/seda/thread_pool.h index c1be810..acbb1a3 100644 --- a/deps/common/seda/thread_pool.h +++ b/deps/common/seda/thread_pool.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/timer_stage.cpp b/deps/common/seda/timer_stage.cpp index f854f68..c4f69f3 100644 --- a/deps/common/seda/timer_stage.cpp +++ b/deps/common/seda/timer_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/seda/timer_stage.h b/deps/common/seda/timer_stage.h index 11d5c31..e769aa9 100644 --- a/deps/common/seda/timer_stage.h +++ b/deps/common/seda/timer_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_SEDA_TIMER_STAGE_H__ -#define __COMMON_SEDA_TIMER_STAGE_H__ +#pragma once #include #include @@ -321,4 +320,4 @@ private: }; } // namespace common -#endif // __COMMON_SEDA_TIMER_STAGE_H__ + diff --git a/deps/common/time/datetime.cpp b/deps/common/time/datetime.cpp index 69eef2b..c24515a 100644 --- a/deps/common/time/datetime.cpp +++ b/deps/common/time/datetime.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/time/datetime.h b/deps/common/time/datetime.h index a49391f..c04ef64 100644 --- a/deps/common/time/datetime.h +++ b/deps/common/time/datetime.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/time/timeout_info.cpp b/deps/common/time/timeout_info.cpp index 8568433..b38fe2d 100644 --- a/deps/common/time/timeout_info.cpp +++ b/deps/common/time/timeout_info.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/time/timeout_info.h b/deps/common/time/timeout_info.h index 9e6fd57..5fa1461 100644 --- a/deps/common/time/timeout_info.h +++ b/deps/common/time/timeout_info.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/deps/common/version.h b/deps/common/version.h index 73e3e5f..0c64228 100644 --- a/deps/common/version.h +++ b/deps/common/version.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,8 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2010 // -#ifndef __COMMON_VERSION_H__ -#define __COMMON_VERSION_H__ +#pragma once + namespace common { #ifndef MAIJOR_VER @@ -39,4 +39,3 @@ namespace common { #define VERSION_NUM (MAIJOR_VER << 24 | MINOR_VER << 16 | PATCH_VER << 8 | OTHER_VER) } // namespace common -#endif //__COMMON_VERSION_H__ diff --git a/docs/miniob-transaction.md b/docs/miniob-transaction.md new file mode 100644 index 0000000..10f70c6 --- /dev/null +++ b/docs/miniob-transaction.md @@ -0,0 +1,198 @@ +本篇文档介绍 MiniOB 中的事务模块是如何工作的。 + +# 背景 +事务是数据库中非常基础的一个模块,也是非常核心的功能。事务有一些基本的概念,叫做ACID,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。如果你对事务的基本概念不太清楚,建议先学习了解事务的基本概念,比如学习[事务处理](lectures/lecture-6.md)章节,或者在网上搜索更多资料。 + +# MiniOB 中的事务 +## 实现简介 +MiniOB 作为一个帮助学习数据库的代码,为了使其学习起来更简单,实现了两种类型的事务。一个叫做Vacuous,另一个叫做MVCC,可以在启动observer时,选择特定的事务模块。 + +**Vacuous(真空)** + +顾名思义,这个事务模块,将不会做任何事务相关的处理,这保留了原始的简单性,有利于学习其它模块时,简化调试。 + +**MVCC** + +多版本并发控制,是一种常见的事务实现。著名的MySQL数据库也支持MVCC,[OceanBase](https://github.com/oceanbase/oceanbase)也实现了此机制。 + +简单来说,MVCC 会在修改数据——MiniOB当前支持插入和删除——时,不会直接在现有的数据上修改,而是创建一个新的行记录,将旧数据复制出来,在新数据上做修改。并将新旧数据使用链表的方式串联起来。每个数据都会有自己的版本号(或者称为时间戳),而版本号通常使用单调递增的数字表示,每个事务根据自己的版本号与数据的版本号,来判断当前能够访问哪个版本的数据。由此可见,MVCC 一个优点就是可以提高只读事务的并发度,它不与其它的写事务产生冲突,因为它访问旧版本的数据就可以了。 + +> NOTE: 不同的数据库,会有不同的实现方式。对MVCC感兴趣的同学,可以阅读一些相关的论文。 + +## 如何运行与测试 +当前MiniOB支持两种类型的事务模型,并且默认情况下是Vacuous,即不开启事务特性。 + +**测试MVCC** + +编译时增加选项 `-DCONCURRENCY=ON`: +```bash +cmake -DCONCURRENCY=ON .. +``` +然后在build目录执行 make。编译完成后启动 observer 服务端进程。 + +可以在启动observer时,增加 `-t mvcc` 选项来开启MVCC,假设当前目录是build(或build_debug之类): + +```bash +./bin/observer -f ../etc/observer.ini -s miniob.sock -t mvcc +``` + +>-f 是配置文件,-s 指使用unix socket,-t 指定使用的事务模型 + +启动observer后,可以使用obclient连接observer: + +```bash +./bin/obclient -s miniob.sock +``` + +可以开启多个客户端。在命令行界面执行 `begin` 可以开启事务,执行 `commit` 提交事务,`rollback` 回滚事务。 + +## 更多的实现原理 + +事务代码位于 `src/observer/storage/trx` 目录下,代码很少。 + +### 事务模型选择 +trx.h 文件中有一个抽象类 `TrxKit`,它可以根据运行时参数传入的名字来创建对应的 `VacuousTrxKit` 和 `MvccTrxKit`。这两个类可以创建相应的事务对象,并且按照需要,初始化行数据中事务需要的额外表字段。当前 Vacuous 什么字段都不需要,而MVCC会额外使用一些表字段。 + +### 事务接口 +不同的事务模型,使用了一些统一的接口,这些接口定义在 `Trx` 中。 + +**事务本身相关的操作** + +- start_if_need。开启一个事务。在SQL请求处理过程中,通常需要开启一个事务; +- commit。提交一个事务; +- rollback。回滚一个事务。 + +**行数据相关的操作** + +- insert_record。插入一行数据。事务可能需要对记录做一些修改,然后调用table的插入记录接口。提交之前插入的记录通常对其它事务不可见; +- delete_record。删除一行数据。与插入记录类似,也会对记录做一些修改,对MVCC来说,并不是真正的将其删除,而是让他对其它事务不可见(提交后); +- visit_record。访问一行数据。当遍历记录,访问某条数据时,需要由事务来判断一下,这条数据是否对当前事务可见,或者事务有访问冲突。 + +### MVCC 相关实现 +**版本号与可见性** + +与常见的MVCC实现方案相似,这里也使用单调递增的数字来作为版本号。并且在表上增加两个额外的字段来表示这条记录有效的版本范围。两个版本字段是`begin_xid`和`end_xid`。每个事务在开始时,就会生成一个自己的版本号,当访问某条记录时,判断自己的版本号是否在该条记录的版本号的范围内,如果在,就是可见的,否则就不可见。 + +> 有些文章或者某些数据库实现中,使用"时间戳"来表示版本号。如果可以保证时间戳也是单调递增的,那这个时间戳确实更好可以作为版本号,并且在分布式系统中,比单纯的单调递增数字更好用。 + +**记录版本号与事务版本号** + +行数据上的版本号,是事务设置的,这个版本号也是事务的版本号。一个写事务,通常会有两个版本号,在启动时,会生成一个版本号,用来在运行时做数据的可见性判断。在提交时,会再生成一个版本号,这个版本号是最终设置在记录上的。 + +```cpp +trx start: + trx_id = next_id() + read record: is_visible(trx_id, record_begin_xid, record_end_xid) + +trx commit: + commit_id = next_id() + foreach updated record: update record begin/end xid with commit_id +``` + +>Q:为什么一定要在提交时生成一个新的版本号?只用该事务之前的版本号不行吗?会有什么问题? + +**版本号与插入删除** + +新插入的记录,在提交后,它的版本号是 `begin_xid` = 事务提交版本号,`end_xid` = 无穷大。表示此数据从当前事务开始生效,对此后所有的新事务都可见。 +而删除相反,`begin_xid` 保持不变,而 `end_xid` 变成了当前事务提交的版本号。表示这条数据对当前事务之后的新事务,就不可见了。 +记录还有一个中间状态,就是事务刚插入或者删除,但是还没有提交时,这里的修改对其它事务应该都是不可见的。比如新插入一条数据,只有当前事务可见,而新删除的数据,只有当前事务不可见。需要使用一种特殊的方法来标记,当然也是在版本号上做动作。对插入的数据,`begin_xid` 改为 (-当前事务版本号)(负数),删除记录将`end_xid`改为 (-当前事务版本号)。在做可见性判断时,对负版本号做特殊处理即可。 + +假设某个事务运行时trx id是 Ta,提交时是 Tc + +| operation | trx state | begin xid | end xid | +| --------- | --------- | --------- | ------- | +| inserted | committed | Tc | +∞ | +| deleted | committed | some trx_id | Tc | +| insert | uncommit | -Ta | +∞ | +| delete | uncommit | some trx_id | -Ta | + +**并发冲突处理** + +MVCC很好的处理了只读事务与写事务的并发,只读事务可以在其它事务修改了某个记录后,访问它的旧版本。但是写事务与写事务之间,依然是有冲突的。这里解决的方法简单粗暴,就是当一个写事务想要修改某个记录时,如果看到有另一个事务也在修改,就直接回滚。如何判断其它事务在修改?判断`begin_xid`或`end_xid`是否为负数就可以。 + +**隔离级别** + +我们通常在聊事务隔离级别时,都会说脏读(Read Uncommitted)、读提交(Read Committed)、可重复读(Repeatable Read)和可串行化(Serializable),说这些时也通常都会提到大名鼎鼎的MySQL。但实际上隔离级别不止是这4种。 +不过这里也没有对隔离级别做特殊的处理,让它顺其自然。 + +>Q: 通过上面的描述,你知道这里的MVCC是什么隔离级别吗? + + +## 遗留问题和扩展 +当前的MVCC是一个简化版本,还有一些功能没有实现,并且还有一些已知BUG。同时还可以扩展更多的事务模型。 + +- 事务提交时,对外原子可见 + + 当前事务在提交时,会逐个修改之前修改过的行数据,调整版本号。这造成的问题是,在某个时刻,有些行数据的版本号已经修改了,有些还没有。那可能会存在一个事务,能够看到已经修改完成版本号的行,但是看不到未修改的行。 + 比如事务A,插入了3条数据,在提交的时候,逐个修改版本号,某个情况下可能会存在下面的场景(假设A的事务ID是90,commit id是100): + + | record | begin xid | end xid | data | + | ------ | --------- | ------- | ---- | + | R1 | 100 | +∞ | ... | + | R2 | 100 | +∞ | ... | + | R3 | -90 | +∞ | ... | + + 此时有一个新的事务,假设事务号是 110,那么它可以看到记录R1和R2,但是看不到R3,因为R3从记录状态来看,还没有提交。 + +- 垃圾回收 + + 随着数据库进程的运行,不断有事务更新数据,不断产生新版本的数据,会占用越来越多的资源。此时需要一种机制,来回收对任何事务都不再可见的数据,这称为垃圾回收。垃圾回收也是一个很有趣的话题,实现方式有很多种。最常见的是,开启一个或多个后台线程,定期的扫描所有的行数据,检查它们的版本。如果某个数据对当前所有活跃事务都不可见,那就认为此条数据是垃圾,可以回收掉。当然,这种回收方法最简单,也是最低效的,同学们如何优化或者实现新的回收方法。 + +- 多版本存储 + + 当前miniob仅实现了插入和删除,并不支持更新操作。而插入和删除最多会存在两个版本的数据,从实现上来看,最多需要一条数据就可以。这大大简化了MVCC的实现。但是也因此没有涉及到MVCC非常核心的多版本数据存储问题。如何合理的存储多个版本的数据,对数据库的性能影响也是巨大的。比如多个版本数据串联时,使用从新到旧,还是从旧到新。两种方式都有合理性,适用于不同的场景。另外还有,多版本的数据存储在哪里?内存还是磁盘,是与原有的数据放在同一个存储空间,还是规划单独的空间,各有什么优缺点,都适用于什么场景。还有,更新数据时,复制整行数据,还是仅记录更新的字段。各有什么优缺点,各适用于什么场景。 + +- 持久化事务 + + 持久性是事务的基本要素之一,是指事务修改后的数据,在数据库重启或者出现异常时,能够从磁盘中将数据恢复出来。除了将修改的数据直接写入到磁盘,还有一个常用的技术手段是WAL,比如Redo日志和Undo日志。那么什么情况下使用Redo,什么时候使用Undo,以及如果只使用Redo或者只使用Undo会有什么问题。另外还有如何存储这些日志,B+树的持久化怎么处理等。有兴趣的同学可以再了解一下 `Steal/No-Steal` 和 `Force/No-Force` 的概念。 + +- MVCC的并发控制 + + 如前文描述,这里的写事务并发冲突处理过于简单粗暴,以至于可以避免的冲突却没有避免。 + +- 基于锁的并发控制 + + MVCC的并发控制通常认为是乐观事务,就是我们认为此系统中事务之间大部分情况下不会存在冲突。但是在OLTP系统中,访问冲突可能是非常频繁发生的,这时候使用悲观事务,效率会更高一点。常见的悲观事务实现方法就是基于锁来实现。假设使用记录锁(行锁)来实现并发,在读数据时加读锁,写时加写锁,也可以实现多种级别的隔离机制。另外,还可以将使用基于锁的机制与MVCC结合起来,实现更好的并发控制。 + + 顺便提一下一个常见的问题,就是在使用行锁时,如何与页面锁(latch)协调? + 大家都知道,latch 都是短锁,在latch保护范围内,都不应该出现长期等待的事情。另外,latch没有死锁检测,不处理锁冲突。而行锁是一种长锁,需要做锁冲突处理,可能需要等待。那在拿着某个latch时,需要等待行锁时,如何处理? + + > 这是很多做了CMU 15445课程的同学没有考虑的问题,15445 课程中将 `Lock Manager` 模块单独拎出来让同学们做练习。但是当行锁与latch同时工作时,它的复杂度将提升好几个量级。 + + +# 进一步学习 + +事务是非常复杂非常有趣的,相关的话题也已经有非常多的研究。如果对事务感兴趣,可以在了解数据库整体实现基础之上,深入研究事务的实现原理。 +这里推荐一些介绍数据库入门的书籍: +- 《数据库系统概念》该书是数据库领域的经典教材之一,涵盖了数据库基本概念、关系型数据库设计、事务处理、并发控制等方面的内容,也可以着重阅读事务相关的内容 +- 《数据库系统实现》:该书是一本数据库系统实现方面的教材,讲解了数据库系统的核心组成部分,包括事务处理、索引、查询优化等方面的内容,对事务处理机制进行了较为细致的讲解 +- 《MySQL技术内幕:InnoDB存储引擎》:该书是一本MySQL数据库方面的重要教材,对InnoDB存储引擎的事务处理机制进行了详细的阐述,包括事务的隔离级别、MVCC实现、锁机制等方面。 + +想直接上手看工业届的事务实现原理,欢迎阅读: +- [分布式事务并发控制的思考与实现](https://open.oceanbase.com/blog/1100128) +- [OceanBase事务引擎的技术创新](https://open.oceanbase.com/blog/1100194) +- [深入浅出事务的本质,附OceanBase事务解析14问!](https://open.oceanbase.com/blog/1100248) + +内功深厚想要直接阅读源码:[OceanBase 事务源码](https://github.com/oceanbase/oceanbase/tree/master/src/storage/tx) + +还有一些著名开放课程,理论结合实践,比如 +- [CMU 15445](https://15445.courses.cs.cmu.edu/spring2023/)。理论结合实践,不仅有课程讲解,还有实验项目,对理解数据库实现原理帮助非常大 +- [CMU 15721](https://15721.courses.cs.cmu.edu/spring2023/)。卡内基梅陇大学的数据库进阶课程 + +如果上面的还感觉太浅,可以持续找一些事务的论文研读: + +- [A Critique of ANSI SQL Isolation Levels](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-95-51.pdf) 该论文针对ANSI SQL标准中隔离级别的定义进行了深入的分析,提出了一些改进的建议。天天看到RC/RR名词的,可以看看这篇论文,了解更详细一点。 + +- [ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging](https://github.com/tpn/pdfs/blob/master/ARIES%20-%20A%20Transaction%20Recovery%20Method%20Supporting%20Fine-Granularity%20Locking%20and%20Partial%20Rollbacks%20Using%20Write-Ahead%20Logging%20(1992).pdf) 该论文提出了ARIES算法,这是一种基于日志记录的恢复算法,支持细粒度锁和部分回滚,可以在数据库崩溃时恢复事务。如果想要对steal/no-force的概念有比较详细的了解,可以直接阅读该论文相关部分。 + +- [Granularity of Locks and Degrees of Consistency in a Shared Data Base](https://web.stanford.edu/class/cs245/readings/granularity-of-locks.pdf) 这也是一个又老又香的论文,提出了基于锁的并发控制。 + +- [Aether: A Scalable Approach to Logging](http://www.pandis.net/resources/vldb10aether.pdf) 介绍可扩展日志系统的。 + +- [An Empirical Evaluation of InMemory Multi-Version Concurrency Control](https://www.vldb.org/pvldb/vol10/p781-Wu.pdf) 介绍MVCC可扩展性的。通过这篇论文可以对MVCC有非常清晰的认识。 + +- [Scalable Garbage Collection for In-Memory MVCC Systems](http://www.vldb.org/pvldb/vol13/p128-bottcher.pdf) 这里对各种垃圾回收算法做了说明,并且有些创新算法。 + +大家看了这些论文会发现,都是一些陈年老论文。数据库领域发展这么多年了,技术依然不过时。 + +如果这些还不够,可以问问ChatGPT还有啥资料。如果觉得单机上的玩腻了,可以再看看分布式事务,总之希望你能玩得愉快。 diff --git a/etc/observer.ini b/etc/observer.ini index f7fb6d3..770cb51 100644 --- a/etc/observer.ini +++ b/etc/observer.ini @@ -12,7 +12,7 @@ LOG_FILE_NAME = observer.log # LOG_LEVEL_TRACE = 5, # LOG_LEVEL_LAST # output log level, default is LOG_LEVEL_INFO -LOG_FILE_LEVEL=3 +LOG_FILE_LEVEL=5 LOG_CONSOLE_LEVEL=1 # the module's log will output whatever level used. #DefaultLogModules="server.cpp,client.cpp" diff --git a/src/obclient/client.cpp b/src/obclient/client.cpp index 991026f..1eade65 100644 --- a/src/obclient/client.cpp +++ b/src/obclient/client.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/defs.h b/src/observer/defs.h index 22ada5a..2ea62fa 100644 --- a/src/observer/defs.h +++ b/src/observer/defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/event/optimize_event.h b/src/observer/event/optimize_event.h index e2bdff5..21cafda 100644 --- a/src/observer/event/optimize_event.h +++ b/src/observer/event/optimize_event.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/event/session_event.cpp b/src/observer/event/session_event.cpp index 361bcaa..a503f12 100644 --- a/src/observer/event/session_event.cpp +++ b/src/observer/event/session_event.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -15,15 +15,13 @@ See the Mulan PSL v2 for more details. */ #include "session_event.h" #include "net/communicator.h" -SessionEvent::SessionEvent(Communicator *comm) : communicator_(comm) +SessionEvent::SessionEvent(Communicator *comm) + : communicator_(comm), + sql_result_(communicator_->session()) {} SessionEvent::~SessionEvent() { - if (sql_result_) { - delete sql_result_; - sql_result_ = nullptr; - } } Communicator *SessionEvent::get_communicator() const @@ -35,33 +33,3 @@ Session *SessionEvent::session() const { return communicator_->session(); } - -const char *SessionEvent::get_response() const -{ - return response_.c_str(); -} - -void SessionEvent::set_response(const char *response) -{ - set_response(response, strlen(response)); -} - -void SessionEvent::set_response(const char *response, int len) -{ - response_.assign(response, len); -} - -void SessionEvent::set_response(std::string &&response) -{ - response_ = std::move(response); -} - -int SessionEvent::get_response_len() const -{ - return response_.size(); -} - -const char *SessionEvent::get_request_buf() -{ - return query_.c_str(); -} diff --git a/src/observer/event/session_event.h b/src/observer/event/session_event.h index 52810ec..088bb0b 100644 --- a/src/observer/event/session_event.h +++ b/src/observer/event/session_event.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -22,9 +22,9 @@ See the Mulan PSL v2 for more details. */ class Session; class Communicator; -class SqlResult; -class SessionEvent : public common::StageEvent { +class SessionEvent : public common::StageEvent +{ public: SessionEvent(Communicator *client); virtual ~SessionEvent(); @@ -36,30 +36,19 @@ public: { query_ = query; } - void set_sql_result(SqlResult *result) - { - sql_result_ = result; - } + const std::string &query() const { return query_; } - SqlResult *sql_result() const + SqlResult *sql_result() { - return sql_result_; + return &sql_result_; } - const char *get_response() const; - void set_response(const char *response); - void set_response(const char *response, int len); - void set_response(std::string &&response); - int get_response_len() const; - const char *get_request_buf(); // TODO remove me - private: Communicator *communicator_ = nullptr; - SqlResult *sql_result_ = nullptr; + SqlResult sql_result_; - std::string query_; - std::string response_; + std::string query_; }; diff --git a/src/observer/event/sql_event.cpp b/src/observer/event/sql_event.cpp index 6f301a6..63a23e4 100644 --- a/src/observer/event/sql_event.cpp +++ b/src/observer/event/sql_event.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/event/sql_event.h b/src/observer/event/sql_event.h index b5875a3..988ae1f 100644 --- a/src/observer/event/sql_event.h +++ b/src/observer/event/sql_event.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/event/storage_event.h b/src/observer/event/storage_event.h index a4aacf5..274439e 100644 --- a/src/observer/event/storage_event.h +++ b/src/observer/event/storage_event.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/14. // -#ifndef __OBSERVER_SQL_EVENT_STORAGEEVENT_H__ -#define __OBSERVER_SQL_EVENT_STORAGEEVENT_H__ +#pragma once #include "common/seda/stage_event.h" @@ -34,5 +33,3 @@ public: private: SQLStageEvent *sql_event_; }; - -#endif //__OBSERVER_SQL_EVENT_STORAGEEVENT_H__ diff --git a/src/observer/ini_setting.h b/src/observer/ini_setting.h index ebbfe8d..ea3d126 100644 --- a/src/observer/ini_setting.h +++ b/src/observer/ini_setting.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/init.cpp b/src/observer/init.cpp index 23e5b08..5aab672 100644 --- a/src/observer/init.cpp +++ b/src/observer/init.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -38,6 +38,7 @@ See the Mulan PSL v2 for more details. */ #include "storage/mem/mem_storage_stage.h" #include "storage/default/disk_buffer_pool.h" #include "storage/default/default_handler.h" +#include "storage/trx/trx.h" using namespace common; @@ -158,7 +159,7 @@ int prepare_init_seda() return 0; } -int init_global_objects() +int init_global_objects(ProcessParam *process_param) { BufferPoolManager *bpm = new BufferPoolManager(); BufferPoolManager::set_instance(bpm); @@ -166,7 +167,13 @@ int init_global_objects() DefaultHandler *handler = new DefaultHandler(); DefaultHandler::set_default(handler); - return 0; + int ret = 0; + RC rc = TrxKit::init_global(process_param->trx_kit_name().c_str()); + if (rc != RC::SUCCESS) { + LOG_ERROR("failed to init trx kit. rc=%s", strrc(rc)); + ret = -1; + } + return ret; } int uninit_global_objects() @@ -229,7 +236,7 @@ int init(ProcessParam *process_param) get_properties()->to_string(conf_data); LOG_INFO("Output configuration \n%s", conf_data.c_str()); - rc = init_global_objects(); + rc = init_global_objects(process_param); if (rc != 0) { LOG_ERROR("failed to init global objects"); return rc; diff --git a/src/observer/init.h b/src/observer/init.h index 553f8c5..8451864 100644 --- a/src/observer/init.h +++ b/src/observer/init.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/main.cpp b/src/observer/main.cpp index 2453907..851f4ab 100644 --- a/src/observer/main.cpp +++ b/src/observer/main.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -38,7 +38,8 @@ void usage() std::cout << "-p: server port. if not specified, the item in the config file will be used" << std::endl; std::cout << "-f: path of config file." << std::endl; std::cout << "-s: use unix socket and the argument is socket address" << std::endl; - std::cout << "-P: protocol. {plain, mysql}. plain is default." << std::endl; + std::cout << "-P: protocol. {plain(default), mysql}." << std::endl; + std::cout << "-t: transaction model. {vacuous(default), mvcc}." << std::endl; exit(0); } @@ -53,7 +54,7 @@ void parse_parameter(int argc, char **argv) // Process args int opt; extern char *optarg; - while ((opt = getopt(argc, argv, "dp:P:s:f:o:e:h")) > 0) { + while ((opt = getopt(argc, argv, "dp:P:s:t:f:o:e:h")) > 0) { switch (opt) { case 's': process_param->set_unix_socket_path(optarg); @@ -76,6 +77,9 @@ void parse_parameter(int argc, char **argv) case 'd': process_param->set_demon(true); break; + case 't': + process_param->set_trx_kit_name(optarg); + break; case 'h': default: usage(); diff --git a/src/observer/net/communicator.cpp b/src/observer/net/communicator.cpp index d836f6d..bc9c260 100644 --- a/src/observer/net/communicator.cpp +++ b/src/observer/net/communicator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -140,8 +140,8 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) SqlResult *sql_result = event->sql_result(); if (nullptr == sql_result) { - const char *response = event->get_response(); - int len = event->get_response_len(); + const char *response = "Unexpected error: no result"; + int len = strlen(response); int ret = common::writen(fd_, response, len); if (ret < 0) { @@ -189,6 +189,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) int ret = common::writen(fd_, alias, len); if (ret != 0) { LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + sql_result->close(); return RC::IOERR; } } @@ -199,6 +200,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) int ret = common::writen(fd_, &newline, 1); if (ret != 0) { LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + sql_result->close(); return RC::IOERR; } } @@ -215,6 +217,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) int ret = common::writen(fd_, delim, strlen(delim)); if (ret != 0) { LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + sql_result->close(); return RC::IOERR; } } @@ -222,6 +225,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) TupleCell cell; rc = tuple->cell_at(i, cell); if (rc != RC::SUCCESS) { + sql_result->close(); return rc; } @@ -231,6 +235,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) int ret = common::writen(fd_, cell_str.data(), cell_str.size()); if (ret != RC::SUCCESS) { LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + sql_result->close(); return RC::IOERR; } } @@ -239,6 +244,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) int ret = common::writen(fd_, &newline, 1); if (ret != 0) { LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + sql_result->close(); return RC::IOERR; } } @@ -251,6 +257,10 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) // 除了select之外,其它的消息通常不会通过operator来返回结果,表头和行数据都是空的 // 这里针对这种情况做特殊处理,当表头和行数据都是空的时候,就返回处理的结果 // 可能是insert/delete等操作,不直接返回给客户端数据,这里把处理结果返回给客户端 + RC rc_close = sql_result->close(); + if (rc == RC::SUCCESS) { + rc = rc_close; + } sql_result->set_return_code(rc); return write_state(event, need_disconnect); } else { @@ -258,11 +268,17 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) int ret = common::writen(fd_, &message_terminate, sizeof(message_terminate)); if (ret < 0) { LOG_ERROR("Failed to send data back to client. ret=%d, error=%s", ret, strerror(errno)); + sql_result->close(); return RC::IOERR; } need_disconnect = false; } + + RC rc_close = sql_result->close(); + if (rc == RC::SUCCESS) { + rc = rc_close; + } return rc; } diff --git a/src/observer/net/communicator.h b/src/observer/net/communicator.h index 3954b15..5511de5 100644 --- a/src/observer/net/communicator.h +++ b/src/observer/net/communicator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/net/mysql_communicator.cpp b/src/observer/net/mysql_communicator.cpp index a5402a5..6dcd362 100644 --- a/src/observer/net/mysql_communicator.cpp +++ b/src/observer/net/mysql_communicator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -409,13 +409,12 @@ RC decode_query_packet(std::vector &net_packet, QueryPacket &query_packet) return RC::SUCCESS; } -RC create_version_comment_sql_result(SqlResult *&sql_result) +RC create_version_comment_sql_result(SqlResult *sql_result) { TupleSchema tuple_schema; TupleCellSpec cell_spec("", "", "@@version_comment"); tuple_schema.append_cell(cell_spec); - sql_result = new SqlResult; sql_result->set_return_code(RC::SUCCESS); sql_result->set_tuple_schema(tuple_schema); @@ -449,15 +448,13 @@ RC MysqlCommunicator::init(int fd, Session *session, const std::string &addr) RC MysqlCommunicator::handle_version_comment(bool &need_disconnect) { - SqlResult *sql_result = nullptr; - RC rc = create_version_comment_sql_result(sql_result); + SessionEvent session_event(this); + RC rc = create_version_comment_sql_result(session_event.sql_result()); if (rc != RC::SUCCESS) { LOG_WARN("failed to handle version comment. rc=%s", strrc(rc)); return rc; } - SessionEvent session_event(this); - session_event.set_sql_result(sql_result); rc = write_result(&session_event, need_disconnect); return rc; } @@ -469,9 +466,7 @@ RC MysqlCommunicator::read_event(SessionEvent *&event) int ret = common::readn(fd_, &packet_header, sizeof(packet_header)); if (ret != 0) { LOG_WARN("failed to read packet header. length=%d, addr=%s. error=%s", - sizeof(packet_header), - addr_.c_str(), - strerror(errno)); + sizeof(packet_header), addr_.c_str(), strerror(errno)); return RC::IOERR; } @@ -481,10 +476,8 @@ RC MysqlCommunicator::read_event(SessionEvent *&event) std::vector buf(packet_header.payload_length); ret = common::readn(fd_, buf.data(), packet_header.payload_length); if (ret != 0) { - LOG_WARN("failed to read packet payload. length=%d, addr=%s, error=%s", - packet_header.payload_length, - addr_.c_str(), - strerror(errno)); + LOG_WARN("failed to read packet payload. length=%d, addr=%s, error=%s", + packet_header.payload_length, addr_.c_str(), strerror(errno)); return RC::IOERR; } @@ -583,9 +576,9 @@ RC MysqlCommunicator::write_result(SessionEvent *event, bool &need_disconnect) need_disconnect = true; SqlResult *sql_result = event->sql_result(); if (nullptr == sql_result) { - const char *response = event->get_response(); - int len = event->get_response_len(); + const char *response = "Unexpected error: no result"; + const int len = strlen(response); OkPacket ok_packet; // TODO if error occurs, we should send an error packet to client ok_packet.info.assign(response, len); rc = send_packet(ok_packet); @@ -617,6 +610,7 @@ RC MysqlCommunicator::write_result(SessionEvent *event, bool &need_disconnect) // send metadata : Column Definition rc = send_column_definition(sql_result, need_disconnect); if (rc != RC::SUCCESS) { + sql_result->close(); return rc; } } @@ -624,6 +618,10 @@ RC MysqlCommunicator::write_result(SessionEvent *event, bool &need_disconnect) rc = send_result_rows(sql_result, cell_num == 0, need_disconnect); } + RC close_rc = sql_result->close(); + if (rc == RC::SUCCESS) { + rc = close_rc; + } return rc; } diff --git a/src/observer/net/mysql_communicator.h b/src/observer/net/mysql_communicator.h index a450d98..59d0c47 100644 --- a/src/observer/net/mysql_communicator.h +++ b/src/observer/net/mysql_communicator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/net/server.cpp b/src/observer/net/server.cpp index c697fa1..0fe3474 100644 --- a/src/observer/net/server.cpp +++ b/src/observer/net/server.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -257,7 +257,7 @@ int Server::start_tcp_server() sa.sin_port = htons(server_param_.port); sa.sin_addr.s_addr = htonl(server_param_.listen_addr); - ret = bind(server_socket_, (struct sockaddr *)&sa, sizeof(sa)); + ret = ::bind(server_socket_, (struct sockaddr *)&sa, sizeof(sa)); if (ret < 0) { LOG_ERROR("bind(): can not bind server socket, %s", strerror(errno)); ::close(server_socket_); @@ -315,7 +315,7 @@ int Server::start_unix_socket_server() sockaddr.sun_family = PF_UNIX; snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s", server_param_.unix_socket_path.c_str()); - ret = bind(server_socket_, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + ret = ::bind(server_socket_, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); if (ret < 0) { LOG_ERROR("bind(): can not bind server socket(path=%s), %s", sockaddr.sun_path, strerror(errno)); ::close(server_socket_); diff --git a/src/observer/net/server.h b/src/observer/net/server.h index 01d87f7..e4f3f69 100644 --- a/src/observer/net/server.h +++ b/src/observer/net/server.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/net/server_param.h b/src/observer/net/server_param.h index 90db4ec..28331df 100644 --- a/src/observer/net/server_param.h +++ b/src/observer/net/server_param.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,8 @@ See the Mulan PSL v2 for more details. */ #include #include "net/communicator.h" -class ServerParam { +class ServerParam +{ public: ServerParam(); diff --git a/src/observer/rc.cpp b/src/observer/rc.cpp index a5b9899..e2c4715 100644 --- a/src/observer/rc.cpp +++ b/src/observer/rc.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -84,6 +84,7 @@ const char *strrc(RC rc) RC_CASE_STRING(RECORD_SCANOPENNED); RC_CASE_STRING(RECORD_EOF); RC_CASE_STRING(RECORD_RECORD_NOT_EXIST); + RC_CASE_STRING(RECORD_INVISIBLE); RC_CASE_STRING(SCHEMA_DB_EXIST); RC_CASE_STRING(SCHEMA_DB_NOT_EXIST); @@ -138,6 +139,7 @@ const char *strrc(RC rc) RC_CASE_STRING(LOCKED_VIRT); RC_CASE_STRING(LOCKED_NEED_WAIT); RC_CASE_STRING(LOCKED_RESOURCE_DELETED); + RC_CASE_STRING(LOCKED_CONCURRENCY_CONFLICT); RC_CASE_STRING(BUSY_RECOVERY); RC_CASE_STRING(BUSY_SNAPSHOT); diff --git a/src/observer/rc.h b/src/observer/rc.h index 69019da..629aefd 100644 --- a/src/observer/rc.h +++ b/src/observer/rc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,10 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/5/2. // -#ifndef __OBSERVER_RC_H__ -#define __OBSERVER_RC_H__ - -#define rc2SimpleStr(rc) #rc +#pragma once enum RCBufferPool { BP_EXIST = 1, @@ -48,6 +45,7 @@ enum RCRecord { RD_SCANOPENNED, RD_EOF, RD_NOT_EXIST, + RD_INVISIBLE, }; enum RCSchema { @@ -110,6 +108,7 @@ enum RCLock { LVIRT, NEED_WAIT, RESOURCE_DELETED, + CONCURRENCY_CONFLICT, }; enum RCBusy { @@ -255,6 +254,7 @@ enum RC { RECORD_SCANOPENNED = (RECORD | (RCRecord::RD_SCANOPENNED << 8)), RECORD_EOF = (RECORD | (RCRecord::RD_EOF << 8)), RECORD_RECORD_NOT_EXIST = (RECORD | (RCRecord::RD_NOT_EXIST << 8)), + RECORD_INVISIBLE = (RECORD | (RCRecord::RD_INVISIBLE << 8)), /* schema part */ SCHEMA_DB_EXIST = (SCHEMA | (RCSchema::DB_EXIST << 8)), @@ -312,6 +312,7 @@ enum RC { LOCKED_VIRT = (LOCKED | (RCLock::LVIRT << 8)), LOCKED_NEED_WAIT = (LOCKED | (RCLock::NEED_WAIT << 8)), LOCKED_RESOURCE_DELETED = (LOCKED | (RCLock::RESOURCE_DELETED << 8)), + LOCKED_CONCURRENCY_CONFLICT = (LOCKED | (RCLock::CONCURRENCY_CONFLICT << 8)), /* busy part */ BUSY_RECOVERY = (BUSY | (RCBusy::BRECOVERY << 8)), @@ -383,4 +384,3 @@ enum RC { extern const char *strrc(RC rc); -#endif //__OBSERVER_RC_H__ diff --git a/src/observer/session/session.cpp b/src/observer/session/session.cpp index 4a91482..20e97df 100644 --- a/src/observer/session/session.cpp +++ b/src/observer/session/session.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -71,7 +71,7 @@ bool Session::is_trx_multi_operation_mode() const Trx *Session::current_trx() { if (trx_ == nullptr) { - trx_ = new Trx; + trx_ = TrxKit::instance()->create_trx(); } return trx_; } diff --git a/src/observer/session/session.h b/src/observer/session/session.h index c3b7e68..a3ae660 100644 --- a/src/observer/session/session.h +++ b/src/observer/session/session.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,7 +19,8 @@ See the Mulan PSL v2 for more details. */ class Trx; class Db; -class Session { +class Session +{ public: // static Session ¤t(); static Session &default_session(); diff --git a/src/observer/session/session_stage.cpp b/src/observer/session/session_stage.cpp index 66be387..4b96c01 100644 --- a/src/observer/session/session_stage.cpp +++ b/src/observer/session/session_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -140,13 +140,8 @@ void SessionStage::handle_request(StageEvent *event) } TimerStat sql_stat(*sql_metric_); - if (nullptr == sev->get_request_buf()) { - LOG_ERROR("Invalid request buffer."); - sev->done_immediate(); - return; - } - std::string sql = sev->get_request_buf(); + std::string sql = sev->query(); if (common::is_blank(sql.c_str())) { sev->done_immediate(); return; diff --git a/src/observer/session/session_stage.h b/src/observer/session/session_stage.h index 3310af2..6f94a83 100644 --- a/src/observer/session/session_stage.h +++ b/src/observer/session/session_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/13. // -#ifndef __OBSERVER_SESSION_SESSIONSTAGE_H__ -#define __OBSERVER_SESSION_SESSIONSTAGE_H__ +#pragma once #include "common/seda/stage.h" #include "common/metrics/metrics.h" @@ -25,7 +24,8 @@ See the Mulan PSL v2 for more details. */ * 每个stage使用handleEvent函数处理任务,并且使用StageEvent::pushCallback注册回调函数。 * 这时当调用StageEvent::done(Immediate)时,就会调用该事件注册的回调函数。 */ -class SessionStage : public common::Stage { +class SessionStage : public common::Stage +{ public: ~SessionStage(); static Stage *make_stage(const std::string &tag); @@ -50,5 +50,3 @@ private: common::SimpleTimer *sql_metric_ = nullptr; static const std::string SQL_METRIC_TAG; }; - -#endif //__OBSERVER_SESSION_SESSIONSTAGE_H__ diff --git a/src/observer/session/thread_data.cpp b/src/observer/session/thread_data.cpp index 94b2cc9..c152316 100644 --- a/src/observer/session/thread_data.cpp +++ b/src/observer/session/thread_data.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/session/thread_data.h b/src/observer/session/thread_data.h index 4368db3..e98d554 100644 --- a/src/observer/session/thread_data.h +++ b/src/observer/session/thread_data.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/executor/command_executor.cpp b/src/observer/sql/executor/command_executor.cpp new file mode 100644 index 0000000..846da03 --- /dev/null +++ b/src/observer/sql/executor/command_executor.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/25. +// + +#include "sql/executor/command_executor.h" +#include "session/session.h" +#include "sql/stmt/stmt.h" +#include "sql/executor/create_index_executor.h" +#include "common/log/log.h" + +RC CommandExecutor::execute(Session *session, Stmt *stmt) +{ + switch (stmt->type()) { + case StmtType::CREATE_INDEX: { + CreateIndexExecutor executor; + return executor.execute(session, stmt); + } break; + + default: { + LOG_ERROR("unknown command: %d", static_cast(stmt->type())); + return RC::UNIMPLENMENT; + } + } + + return RC::INTERNAL; +} \ No newline at end of file diff --git a/src/observer/sql/executor/command_executor.h b/src/observer/sql/executor/command_executor.h new file mode 100644 index 0000000..4ea7932 --- /dev/null +++ b/src/observer/sql/executor/command_executor.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/25. +// + +#pragma once + +#include "rc.h" + +class Session; +class Stmt; + +class CommandExecutor +{ +public: + CommandExecutor() = default; + virtual ~CommandExecutor() = default; + + RC execute(Session *session, Stmt *stmt); +}; diff --git a/src/observer/sql/executor/create_index_executor.cpp b/src/observer/sql/executor/create_index_executor.cpp new file mode 100644 index 0000000..98c066e --- /dev/null +++ b/src/observer/sql/executor/create_index_executor.cpp @@ -0,0 +1,31 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/25. +// + +#include "sql/executor/create_index_executor.h" +#include "sql/stmt/create_index_stmt.h" +#include "session/session.h" +#include "common/log/log.h" +#include "storage/common/table.h" + +RC CreateIndexExecutor::execute(Session *session, Stmt *stmt) +{ + ASSERT(stmt->type() == StmtType::CREATE_INDEX, + "create index executor can not run this command: %d", static_cast(stmt->type())); + + CreateIndexStmt *create_index_stmt = static_cast(stmt); + + Trx *trx = session->current_trx(); + Table *table = create_index_stmt->table(); + return table->create_index(trx, create_index_stmt->field_meta(), create_index_stmt->index_name().c_str()); +} \ No newline at end of file diff --git a/src/observer/sql/executor/create_index_executor.h b/src/observer/sql/executor/create_index_executor.h new file mode 100644 index 0000000..8684ed4 --- /dev/null +++ b/src/observer/sql/executor/create_index_executor.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/25. +// + +#pragma once + +#include "rc.h" + +class Session; +class Stmt; + +class CreateIndexExecutor +{ +public: + CreateIndexExecutor() = default; + virtual ~CreateIndexExecutor() = default; + + RC execute(Session *session, Stmt *stmt); +}; \ No newline at end of file diff --git a/src/observer/sql/executor/execute_stage.cpp b/src/observer/sql/executor/execute_stage.cpp index ad8417d..e096015 100644 --- a/src/observer/sql/executor/execute_stage.cpp +++ b/src/observer/sql/executor/execute_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,11 +9,12 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Longda on 2021/4/13. +// Created by Longda on 2021/4/13. // #include #include +#include #include "execute_stage.h" @@ -45,8 +46,9 @@ See the Mulan PSL v2 for more details. */ #include "storage/default/default_handler.h" #include "storage/common/condition_filter.h" #include "storage/trx/trx.h" -#include "storage/clog/clog.h" +#include "sql/executor/command_executor.h" +using namespace std; using namespace common; //! Constructor @@ -127,8 +129,9 @@ void ExecuteStage::callback_event(StageEvent *event, CallbackContext *context) RC ExecuteStage::handle_request(common::StageEvent *event) { SQLStageEvent *sql_event = static_cast(event); + SqlResult *sql_result = sql_event->session_event()->sql_result(); - const std::unique_ptr &physical_operator = sql_event->physical_operator(); + const unique_ptr &physical_operator = sql_event->physical_operator(); if (physical_operator != nullptr) { return handle_request_with_physical_operator(sql_event); } @@ -139,21 +142,22 @@ RC ExecuteStage::handle_request(common::StageEvent *event) Command *sql = sql_event->command().get(); Stmt *stmt = sql_event->stmt(); if (stmt != nullptr) { + CommandExecutor command_executor; + RC rc = RC::UNIMPLENMENT; switch (stmt->type()) { - case StmtType::INSERT: { - do_insert(sql_event); - } break; case StmtType::UPDATE: { // do_update((UpdateStmt *)stmt, session_event); } break; - case StmtType::DELETE: { - do_delete(sql_event); + case StmtType::CREATE_INDEX: { + rc = command_executor.execute(session, stmt); } break; default: { LOG_WARN("should not happen. please implement this type:%d", stmt->type()); } break; } + session_event->sql_result()->set_return_code(rc); } else { + // TODO create command to execute these sql switch (sql->flag) { case SCF_HELP: { do_help(sql_event); @@ -161,9 +165,7 @@ RC ExecuteStage::handle_request(common::StageEvent *event) case SCF_CREATE_TABLE: { do_create_table(sql_event); } break; - case SCF_CREATE_INDEX: { - do_create_index(sql_event); - } break; + case SCF_SHOW_TABLES: { do_show_tables(sql_event); } break; @@ -176,59 +178,31 @@ RC ExecuteStage::handle_request(common::StageEvent *event) case SCF_LOAD_DATA: { default_storage_stage_->handle_event(event); } break; - case SCF_SYNC: { - /* - RC rc = DefaultHandler::get_default().sync(); - session_event->set_response(strrc(rc)); - */ - } break; case SCF_BEGIN: { do_begin(sql_event); - /* - session_event->set_response("SUCCESS\n"); - */ } break; case SCF_COMMIT: { do_commit(sql_event); - /* - Trx *trx = session->current_trx(); - RC rc = trx->commit(); - session->set_trx_multi_operation_mode(false); - session_event->set_response(strrc(rc)); - */ } break; - case SCF_CLOG_SYNC: { - do_clog_sync(sql_event); - } + case SCF_ROLLBACK: { Trx *trx = session_event->session()->current_trx(); - RC rc = trx->rollback(); - session->set_trx_multi_operation_mode(false); - SqlResult *sql_result = new SqlResult; sql_result->set_return_code(rc); - - session_event->set_sql_result(sql_result); } break; + case SCF_EXIT: { // do nothing - SqlResult *sql_result = new SqlResult; sql_result->set_return_code(RC::SUCCESS); - - session_event->set_sql_result(sql_result); } break; - default: { + default: { LOG_ERROR("Unsupported command=%d\n", sql->flag); - SqlResult *sql_result = new SqlResult; - sql_result->set_return_code(RC::UNIMPLENMENT); sql_result->set_state_string("Unsupported command"); - - session_event->set_sql_result(sql_result); } } } @@ -242,7 +216,7 @@ RC ExecuteStage::handle_request_with_physical_operator(SQLStageEvent *sql_event) Stmt *stmt = sql_event->stmt(); ASSERT(stmt != nullptr, "SQL Statement shouldn't be empty!"); - std::unique_ptr &physical_operator = sql_event->physical_operator(); + unique_ptr &physical_operator = sql_event->physical_operator(); ASSERT(physical_operator != nullptr, "physical operator should not be null"); TupleSchema schema; @@ -268,11 +242,9 @@ RC ExecuteStage::handle_request_with_physical_operator(SQLStageEvent *sql_event) } break; } - SqlResult *sql_result = new SqlResult; + SqlResult *sql_result = sql_event->session_event()->sql_result(); sql_result->set_tuple_schema(schema); sql_result->set_operator(std::move(physical_operator)); - - sql_event->session_event()->set_sql_result(sql_result); return rc; } @@ -287,231 +259,8 @@ void end_trx_if_need(Session *session, Trx *trx, bool all_right) } } -void tuple_to_string(std::ostream &os, const Tuple &tuple) -{ - RC rc = RC::SUCCESS; - bool first_field = true; - - TupleCell cell; - for (int i = 0; i < tuple.cell_num(); i++) { - rc = tuple.cell_at(i, cell); - if (rc != RC::SUCCESS) { - LOG_WARN("failed to fetch field of cell. index=%d, rc=%s", i, strrc(rc)); - break; - } - - if (!first_field) { - os << " | "; - } else { - first_field = false; - } - cell.to_string(os); - } -} - -#if 0 -IndexScanOperator *try_to_create_index_scan_operator(FilterStmt *filter_stmt) -{ - const std::vector &filter_units = filter_stmt->filter_units(); - if (filter_units.empty() ) { - return nullptr; - } - - // 在所有过滤条件中,找到字段与值做比较的条件,然后判断字段是否可以使用索引 - // 如果是多列索引,这里的处理需要更复杂。 - // 这里的查找规则是比较简单的,就是尽量找到使用相等比较的索引 - // 如果没有就找范围比较的,但是直接排除不等比较的索引查询. (你知道为什么?) - const FilterUnit *better_filter = nullptr; - for (const FilterUnit * filter_unit : filter_units) { - if (filter_unit->comp() == NOT_EQUAL) { - continue; - } - - Expression *left = filter_unit->left(); - Expression *right = filter_unit->right(); - if (left->type() == ExprType::FIELD && right->type() == ExprType::VALUE) { - } else if (left->type() == ExprType::VALUE && right->type() == ExprType::FIELD) { - std::swap(left, right); - } else { - continue; - } - - FieldExpr &left_field_expr = *(FieldExpr *)left; - const Field &field = left_field_expr.field(); - const Table *table = field.table(); - Index *index = table->find_index_by_field(field.field_name()); - if (index != nullptr) { - if (better_filter == nullptr) { - better_filter = filter_unit; - } else if (filter_unit->comp() == EQUAL_TO) { - better_filter = filter_unit; - break; - } - } - } - - if (better_filter == nullptr) { - return nullptr; - } - - Expression *left = better_filter->left(); - Expression *right = better_filter->right(); - CompOp comp = better_filter->comp(); - if (left->type() == ExprType::VALUE && right->type() == ExprType::FIELD) { - std::swap(left, right); - switch (comp) { - case EQUAL_TO: { comp = EQUAL_TO; } break; - case LESS_EQUAL: { comp = GREAT_THAN; } break; - case NOT_EQUAL: { comp = NOT_EQUAL; } break; - case LESS_THAN: { comp = GREAT_EQUAL; } break; - case GREAT_EQUAL: { comp = LESS_THAN; } break; - case GREAT_THAN: { comp = LESS_EQUAL; } break; - default: { - LOG_WARN("should not happen"); - } - } - } - - FieldExpr &left_field_expr = *(FieldExpr *)left; - const Field &field = left_field_expr.field(); - const Table *table = field.table(); - Index *index = table->find_index_by_field(field.field_name()); - assert(index != nullptr); - - ValueExpr &right_value_expr = *(ValueExpr *)right; - TupleCell value; - right_value_expr.get_tuple_cell(value); - - const TupleCell *left_cell = nullptr; - const TupleCell *right_cell = nullptr; - bool left_inclusive = false; - bool right_inclusive = false; - - switch (comp) { - case EQUAL_TO: { - left_cell = &value; - right_cell = &value; - left_inclusive = true; - right_inclusive = true; - } break; - - case LESS_EQUAL: { - left_cell = nullptr; - left_inclusive = false; - right_cell = &value; - right_inclusive = true; - } break; - - case LESS_THAN: { - left_cell = nullptr; - left_inclusive = false; - right_cell = &value; - right_inclusive = false; - } break; - - case GREAT_EQUAL: { - left_cell = &value; - left_inclusive = true; - right_cell = nullptr; - right_inclusive = false; - } break; - - case GREAT_THAN: { - left_cell = &value; - left_inclusive = false; - right_cell = nullptr; - right_inclusive = false; - } break; - - default: { - LOG_WARN("should not happen. comp=%d", comp); - } break; - } - - IndexScanOperator *oper = new IndexScanOperator(table, index, - left_cell, left_inclusive, right_cell, right_inclusive); - - LOG_INFO("use index for scan: %s in table %s", index->index_meta().name(), table->name()); - return oper; -} - -#endif - -RC ExecuteStage::do_select(SQLStageEvent *sql_event) -{ -#if 0 - RC rc = RC::SUCCESS; - - SessionEvent *session_event = sql_event->session_event(); - - SelectStmt *select_stmt = (SelectStmt *)(sql_event->stmt()); - if (select_stmt->tables().size() != 1) { - LOG_WARN("select more than 1 tables is not supported"); - rc = RC::UNIMPLENMENT; - return rc; - } - - Operator *scan_oper = nullptr; // try_to_create_index_scan_operator(select_stmt->filter_stmt()); - if (nullptr == scan_oper) { - scan_oper = new TableScanOperator(select_stmt->tables()[0]); - } - - PredicateOperator *pred_oper = new PredicateOperator(select_stmt->filter_stmt()); - pred_oper->add_child(scan_oper); - - ProjectOperator *project_oper = new ProjectOperator; - project_oper->add_child(pred_oper); - - TupleSchema schema; - for (const Field &field : select_stmt->query_fields()) { - project_oper->add_projection(field.table(), field.meta()); - schema.append_cell(field.field_name()); - } - - SqlResult *sql_result = new SqlResult; - sql_result->set_tuple_schema(schema); - sql_result->set_operator(project_oper); - - /* - rc = project_oper.open(); - if (rc != RC::SUCCESS) { - LOG_WARN("failed to open operator"); - return rc; - } - - std::stringstream ss; - print_tuple_header(ss, project_oper); - while ((rc = project_oper.next()) == RC::SUCCESS) { - // get current record - // write to response - Tuple * tuple = project_oper.current_tuple(); - if (nullptr == tuple) { - rc = RC::INTERNAL; - LOG_WARN("failed to get current record. rc=%s", strrc(rc)); - break; - } - - tuple_to_string(ss, *tuple); - ss << std::endl; - } - - if (rc != RC::RECORD_EOF) { - LOG_WARN("something wrong while iterate operator. rc=%s", strrc(rc)); - project_oper.close(); - } else { - rc = project_oper.close(); - } - session_event->set_response(ss.str()); - */ - session_event->set_sql_result(sql_result); -#endif - return RC::SUCCESS; -} - RC ExecuteStage::do_help(SQLStageEvent *sql_event) { - SessionEvent *session_event = sql_event->session_event(); - const char *strings[] = {"show tables;", "desc `table name`;", "create table `table name` (`column name` `column type`, ...);", @@ -526,15 +275,14 @@ RC ExecuteStage::do_help(SQLStageEvent *sql_event) oper->append(strings[i]); } - SqlResult *sql_result = new SqlResult; + SqlResult *sql_result = sql_event->session_event()->sql_result(); TupleSchema schema; schema.append_cell("Commands"); sql_result->set_tuple_schema(schema); - sql_result->set_operator(std::unique_ptr(oper)); + sql_result->set_operator(unique_ptr(oper)); - session_event->set_sql_result(sql_result); return RC::SUCCESS; } @@ -548,38 +296,15 @@ RC ExecuteStage::do_create_table(SQLStageEvent *sql_event) RC rc = db->create_table(create_table.relation_name.c_str(), attribute_count, create_table.attr_infos.data()); - SqlResult *sql_result = new SqlResult; - sql_result->set_return_code(rc); - - sql_event->session_event()->set_sql_result(sql_result); - return rc; -} -RC ExecuteStage::do_create_index(SQLStageEvent *sql_event) -{ - SqlResult *sql_result = new SqlResult; - SessionEvent *session_event = sql_event->session_event(); - session_event->set_sql_result(sql_result); - - Db *db = session_event->session()->get_current_db(); - - const CreateIndex &create_index = sql_event->command()->create_index; - Table *table = db->find_table(create_index.relation_name.c_str()); - if (nullptr == table) { - sql_result->set_return_code(RC::SCHEMA_TABLE_NOT_EXIST); - return RC::SCHEMA_TABLE_NOT_EXIST; - } - - RC rc = table->create_index(nullptr, create_index.index_name.c_str(), create_index.attribute_name.c_str()); - + SqlResult *sql_result = session_event->sql_result(); sql_result->set_return_code(rc); return rc; } RC ExecuteStage::do_show_tables(SQLStageEvent *sql_event) { - SqlResult *sql_result = new SqlResult; + SqlResult *sql_result = sql_event->session_event()->sql_result(); SessionEvent *session_event = sql_event->session_event(); - session_event->set_sql_result(sql_result); Db *db = session_event->session()->get_current_db(); @@ -601,8 +326,7 @@ RC ExecuteStage::do_show_tables(SQLStageEvent *sql_event) RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event) { - SqlResult *sql_result = new SqlResult; - sql_event->session_event()->set_sql_result(sql_result); + SqlResult *sql_result = sql_event->session_event()->sql_result(); Command *cmd = sql_event->command().get(); const char *table_name = cmd->desc_table.relation_name.c_str(); @@ -626,7 +350,7 @@ RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event) oper->append({field_meta->name(), attr_type_to_string(field_meta->type()), std::to_string(field_meta->len())}); } - sql_result->set_operator(std::unique_ptr(oper)); + sql_result->set_operator(unique_ptr(oper)); } else { sql_result->set_return_code(RC::SCHEMA_TABLE_NOT_EXIST); @@ -635,134 +359,17 @@ RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event) return RC::SUCCESS; } -RC ExecuteStage::do_insert(SQLStageEvent *sql_event) -{ - SessionEvent *session_event = sql_event->session_event(); - SqlResult *sql_result = new SqlResult; - session_event->set_sql_result(sql_result); - - Session *session = session_event->session(); - Db *db = session->get_current_db(); - - Trx *trx = session->current_trx(); - CLogManager *clog_manager = db->get_clog_manager(); - - Stmt *stmt = sql_event->stmt(); - if (stmt == nullptr) { - LOG_WARN("cannot find statement"); - return RC::GENERIC_ERROR; - } - - InsertStmt *insert_stmt = (InsertStmt *)stmt; - Table *table = insert_stmt->table(); - - RC rc = table->insert_record(trx, insert_stmt->value_amount(), insert_stmt->values()); - if (rc == RC::SUCCESS) { - if (!session->is_trx_multi_operation_mode()) { - - CLogRecord *clog_record = nullptr; - rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record); - if (rc != RC::SUCCESS || clog_record == nullptr) { - if (rc == RC::SUCCESS) { - rc = RC::INTERNAL; - } - sql_result->set_return_code(rc); - return rc; - } - - rc = clog_manager->clog_append_record(clog_record); - if (rc != RC::SUCCESS) { - sql_result->set_return_code(rc); - return rc; - } - - trx->next_current_id(); - sql_result->set_return_code(RC::SUCCESS); - } else { - sql_result->set_return_code(RC::SUCCESS); - } - } else { - sql_result->set_return_code(rc); - } - return rc; -} - -RC ExecuteStage::do_delete(SQLStageEvent *sql_event) -{ -#if 0 - SessionEvent *session_event = sql_event->session_event(); - Session *session = session_event->session(); - - Db *db = session->get_current_db(); - Trx *trx = session->current_trx(); - CLogManager *clog_manager = db->get_clog_manager(); - - Stmt *stmt = sql_event->stmt(); - if (stmt == nullptr) { - LOG_WARN("cannot find statement"); - return RC::GENERIC_ERROR; - } - - DeleteStmt *delete_stmt = (DeleteStmt *)stmt; - - TableScanOperator scan_oper(delete_stmt->table()); - PredicateOperator pred_oper(delete_stmt->filter_stmt()); - pred_oper.add_child(&scan_oper); - - DeleteOperator delete_oper(delete_stmt, trx); - delete_oper.add_child(&pred_oper); - - RC rc = delete_oper.open(); - if (rc != RC::SUCCESS) { - session_event->set_response("FAILURE\n"); - } else { - - session_event->set_response("SUCCESS\n"); - if (!session->is_trx_multi_operation_mode()) { - - CLogRecord *clog_record = nullptr; - rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record); - if (rc != RC::SUCCESS || clog_record == nullptr) { - session_event->set_response("FAILURE\n"); - return rc; - } - - rc = clog_manager->clog_append_record(clog_record); - if (rc != RC::SUCCESS) { - session_event->set_response("FAILURE\n"); - return rc; - } - - trx->next_current_id(); - session_event->set_response("SUCCESS\n"); - } - } - return rc; -#endif - return RC::SUCCESS; -} - RC ExecuteStage::do_begin(SQLStageEvent *sql_event) { SessionEvent *session_event = sql_event->session_event(); - SqlResult *sql_result = new SqlResult; - session_event->set_sql_result(sql_result); + SqlResult *sql_result = session_event->sql_result(); Session *session = session_event->session(); - Db *db = session->get_current_db(); Trx *trx = session->current_trx(); - CLogManager *clog_manager = db->get_clog_manager(); session->set_trx_multi_operation_mode(true); - CLogRecord *clog_record = nullptr; - RC rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_BEGIN, trx->get_current_id(), clog_record); - if (rc != RC::SUCCESS || clog_record == nullptr) { - sql_result->set_return_code(rc); - return rc; - } - - rc = clog_manager->clog_append_record(clog_record); + RC rc = trx->start_if_need(); sql_result->set_return_code(rc); return rc; @@ -770,45 +377,15 @@ RC ExecuteStage::do_begin(SQLStageEvent *sql_event) RC ExecuteStage::do_commit(SQLStageEvent *sql_event) { - SessionEvent *session_event = sql_event->session_event(); - SqlResult *sql_result = new SqlResult; - session_event->set_sql_result(sql_result); + SqlResult *sql_result = session_event->sql_result(); Session *session = session_event->session(); session->set_trx_multi_operation_mode(false); Trx *trx = session->current_trx(); - CLogRecord *clog_record = nullptr; - - Db *db = session->get_current_db(); - CLogManager *clog_manager = db->get_clog_manager(); - RC rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record); - if (rc != RC::SUCCESS || clog_record == nullptr) { - sql_result->set_return_code(rc); - return rc; - } - - rc = clog_manager->clog_append_record(clog_record); - sql_result->set_return_code(rc); - - trx->next_current_id(); - - return rc; -} - -RC ExecuteStage::do_clog_sync(SQLStageEvent *sql_event) -{ - - SqlResult *sql_result = new SqlResult; - SessionEvent *session_event = sql_event->session_event(); - session_event->set_sql_result(sql_result); - - Db *db = session_event->session()->get_current_db(); - CLogManager *clog_manager = db->get_clog_manager(); - - RC rc = clog_manager->clog_sync(); + RC rc = trx->commit(); sql_result->set_return_code(rc); return rc; diff --git a/src/observer/sql/executor/execute_stage.h b/src/observer/sql/executor/execute_stage.h index 7732b46..95f3e6a 100644 --- a/src/observer/sql/executor/execute_stage.h +++ b/src/observer/sql/executor/execute_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -42,15 +42,10 @@ protected: RC do_help(SQLStageEvent *session_event); RC do_create_table(SQLStageEvent *sql_event); - RC do_create_index(SQLStageEvent *sql_event); RC do_show_tables(SQLStageEvent *sql_event); RC do_desc_table(SQLStageEvent *sql_event); - RC do_select(SQLStageEvent *sql_event); - RC do_insert(SQLStageEvent *sql_event); - RC do_delete(SQLStageEvent *sql_event); RC do_begin(SQLStageEvent *sql_event); RC do_commit(SQLStageEvent *sql_event); - RC do_clog_sync(SQLStageEvent *sql_event); protected: private: diff --git a/src/observer/sql/executor/sql_result.cpp b/src/observer/sql/executor/sql_result.cpp index 408c6da..10caa02 100644 --- a/src/observer/sql/executor/sql_result.cpp +++ b/src/observer/sql/executor/sql_result.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -14,6 +14,11 @@ See the Mulan PSL v2 for more details. */ #include "rc.h" #include "sql/executor/sql_result.h" +#include "session/session.h" +#include "storage/trx/trx.h" + +SqlResult::SqlResult(Session *session) : session_(session) +{} void SqlResult::set_tuple_schema(const TupleSchema &schema) { @@ -25,7 +30,10 @@ RC SqlResult::open() if (nullptr == operator_) { return RC::INVALID_ARGUMENT; } - return operator_->open(); + + Trx *trx = session_->current_trx(); + trx->start_if_need(); + return operator_->open(trx); } RC SqlResult::close() @@ -33,7 +41,24 @@ RC SqlResult::close() if (nullptr == operator_) { return RC::INVALID_ARGUMENT; } - return operator_->close(); + RC rc = operator_->close(); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to close operator. rc=%s", strrc(rc)); + } + + operator_.reset(); + + if (session_ && !session_->is_trx_multi_operation_mode()) { + if (rc == RC::SUCCESS) { + rc = session_->current_trx()->commit(); + } else { + RC rc2 = session_->current_trx()->rollback(); + if (rc2 != RC::SUCCESS) { + LOG_PANIC("rollback failed. rc=%s", strrc(rc2)); + } + } + } + return rc; } RC SqlResult::next_tuple(Tuple *&tuple) diff --git a/src/observer/sql/executor/sql_result.h b/src/observer/sql/executor/sql_result.h index 1c36879..aa4c966 100644 --- a/src/observer/sql/executor/sql_result.h +++ b/src/observer/sql/executor/sql_result.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,9 +20,12 @@ See the Mulan PSL v2 for more details. */ #include "sql/expr/tuple.h" #include "sql/operator/physical_operator.h" -class SqlResult { +class Session; + +class SqlResult +{ public: - SqlResult() = default; + SqlResult(Session *session); ~SqlResult() {} @@ -62,6 +65,7 @@ public: RC next_tuple(Tuple *&tuple); private: + Session *session_ = nullptr; std::unique_ptr operator_; TupleSchema tuple_schema_; RC return_code_ = RC::SUCCESS; diff --git a/src/observer/sql/expr/expression.cpp b/src/observer/sql/expr/expression.cpp index de4fad7..cdfe791 100644 --- a/src/observer/sql/expr/expression.cpp +++ b/src/observer/sql/expr/expression.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/expr/expression.h b/src/observer/sql/expr/expression.h index f4c0248..93bc2f9 100644 --- a/src/observer/sql/expr/expression.h +++ b/src/observer/sql/expr/expression.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -22,7 +22,8 @@ See the Mulan PSL v2 for more details. */ class Tuple; -enum class ExprType { +enum class ExprType +{ NONE, FIELD, VALUE, @@ -41,7 +42,8 @@ enum class ExprType { * 才能计算出来真实的值。但是有些表达式可能就表示某一个固定的 * 值,比如ValueExpr。 */ -class Expression { +class Expression +{ public: Expression() = default; virtual ~Expression() = default; @@ -63,7 +65,8 @@ public: virtual AttrType value_type() const = 0; }; -class FieldExpr : public Expression { +class FieldExpr : public Expression +{ public: FieldExpr() = default; FieldExpr(const Table *table, const FieldMeta *field) : field_(table, field) @@ -108,7 +111,8 @@ private: Field field_; }; -class ValueExpr : public Expression { +class ValueExpr : public Expression +{ public: ValueExpr() = default; ValueExpr(const Value &value) @@ -162,7 +166,8 @@ private: TupleCell tuple_cell_; }; -class CastExpr : public Expression { +class CastExpr : public Expression +{ public: CastExpr(std::unique_ptr child, AttrType cast_type); virtual ~CastExpr(); @@ -187,7 +192,8 @@ private: AttrType cast_type_; }; -class ComparisonExpr : public Expression { +class ComparisonExpr : public Expression +{ public: ComparisonExpr(CompOp comp, std::unique_ptr left, std::unique_ptr right); virtual ~ComparisonExpr(); @@ -237,7 +243,8 @@ private: * 多个表达式使用同一种关系(AND或OR)来联结 * 当前miniob仅有AND操作 */ -class ConjunctionExpr : public Expression { +class ConjunctionExpr : public Expression +{ public: enum class Type { AND, diff --git a/src/observer/sql/expr/tuple.h b/src/observer/sql/expr/tuple.h index 6038ce4..e637706 100644 --- a/src/observer/sql/expr/tuple.h +++ b/src/observer/sql/expr/tuple.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -25,7 +25,8 @@ See the Mulan PSL v2 for more details. */ class Table; -class TupleSchema { +class TupleSchema +{ public: void append_cell(const TupleCellSpec &cell) { @@ -52,7 +53,8 @@ private: std::vector cells_; }; -class Tuple { +class Tuple +{ public: Tuple() = default; virtual ~Tuple() = default; @@ -62,7 +64,8 @@ public: virtual RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const = 0; }; -class RowTuple : public Tuple { +class RowTuple : public Tuple +{ public: RowTuple() = default; virtual ~RowTuple() @@ -152,7 +155,8 @@ private: std::vector speces_; }; -class ProjectTuple : public Tuple { +class ProjectTuple : public Tuple +{ public: ProjectTuple() = default; virtual ~ProjectTuple() @@ -210,7 +214,8 @@ private: Tuple *tuple_ = nullptr; }; -class ValueListTuple : public Tuple { +class ValueListTuple : public Tuple +{ public: ValueListTuple() = default; virtual ~ValueListTuple() = default; @@ -248,7 +253,8 @@ private: * 将两个tuple合并为一个tuple * 在join算子中使用 */ -class JoinedTuple : public Tuple { +class JoinedTuple : public Tuple +{ public: JoinedTuple() = default; virtual ~JoinedTuple() = default; diff --git a/src/observer/sql/expr/tuple_cell.cpp b/src/observer/sql/expr/tuple_cell.cpp index 25f5dc4..f199de2 100644 --- a/src/observer/sql/expr/tuple_cell.cpp +++ b/src/observer/sql/expr/tuple_cell.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/expr/tuple_cell.h b/src/observer/sql/expr/tuple_cell.h index 140a9a1..2c101cc 100644 --- a/src/observer/sql/expr/tuple_cell.h +++ b/src/observer/sql/expr/tuple_cell.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -46,11 +46,12 @@ private: * 表示tuple中某个元素的值 * @note 可以与value做合并 */ -class TupleCell { +class TupleCell +{ public: TupleCell() = default; - TupleCell(FieldMeta *meta, char *data, int length = 4) : TupleCell(meta->type(), data) + TupleCell(const FieldMeta *meta, char *data, int length = 4) : TupleCell(meta->type(), data) {} TupleCell(AttrType attr_type, char *data, int length = 4) : attr_type_(attr_type) { diff --git a/src/observer/sql/operator/delete_logical_operator.cpp b/src/observer/sql/operator/delete_logical_operator.cpp index a070564..9c6306a 100644 --- a/src/observer/sql/operator/delete_logical_operator.cpp +++ b/src/observer/sql/operator/delete_logical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/operator/delete_logical_operator.h b/src/observer/sql/operator/delete_logical_operator.h index f055b0d..bc967aa 100644 --- a/src/observer/sql/operator/delete_logical_operator.h +++ b/src/observer/sql/operator/delete_logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -16,7 +16,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/logical_operator.h" -class DeleteLogicalOperator : public LogicalOperator { +class DeleteLogicalOperator : public LogicalOperator +{ public: DeleteLogicalOperator(Table *table); virtual ~DeleteLogicalOperator() = default; diff --git a/src/observer/sql/operator/delete_physical_operator.cpp b/src/observer/sql/operator/delete_physical_operator.cpp index 22fcfdc..22d2dc9 100644 --- a/src/observer/sql/operator/delete_physical_operator.cpp +++ b/src/observer/sql/operator/delete_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,19 +19,21 @@ See the Mulan PSL v2 for more details. */ #include "storage/trx/trx.h" #include "sql/stmt/delete_stmt.h" -RC DeletePhysicalOperator::open() +RC DeletePhysicalOperator::open(Trx *trx) { if (children_.empty()) { return RC::SUCCESS; } std::unique_ptr &child = children_[0]; - RC rc = child->open(); + RC rc = child->open(trx); if (rc != RC::SUCCESS) { LOG_WARN("failed to open child operator: %s", strrc(rc)); return rc; } + trx_ = trx; + return RC::SUCCESS; } @@ -52,7 +54,7 @@ RC DeletePhysicalOperator::next() RowTuple *row_tuple = static_cast(tuple); Record &record = row_tuple->record(); - rc = table_->delete_record(trx_, &record); + rc = trx_->delete_record(table_, record); if (rc != RC::SUCCESS) { LOG_WARN("failed to delete record: %s", strrc(rc)); return rc; diff --git a/src/observer/sql/operator/delete_physical_operator.h b/src/observer/sql/operator/delete_physical_operator.h index 0b262bb..b210034 100644 --- a/src/observer/sql/operator/delete_physical_operator.h +++ b/src/observer/sql/operator/delete_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,9 +20,10 @@ See the Mulan PSL v2 for more details. */ class Trx; class DeleteStmt; -class DeletePhysicalOperator : public PhysicalOperator { +class DeletePhysicalOperator : public PhysicalOperator +{ public: - DeletePhysicalOperator(Table *table, Trx *trx) : table_(table), trx_(trx) + DeletePhysicalOperator(Table *table) : table_(table) {} virtual ~DeletePhysicalOperator() = default; @@ -32,7 +33,7 @@ public: return PhysicalOperatorType::DELETE; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; diff --git a/src/observer/sql/operator/explain_logical_operator.h b/src/observer/sql/operator/explain_logical_operator.h index 070633e..fd47b25 100644 --- a/src/observer/sql/operator/explain_logical_operator.h +++ b/src/observer/sql/operator/explain_logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/operator/explain_physical_operator.cpp b/src/observer/sql/operator/explain_physical_operator.cpp index 67bef10..8cecefd 100644 --- a/src/observer/sql/operator/explain_physical_operator.cpp +++ b/src/observer/sql/operator/explain_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -18,7 +18,7 @@ See the Mulan PSL v2 for more details. */ using namespace std; -RC ExplainPhysicalOperator::open() +RC ExplainPhysicalOperator::open(Trx *) { ASSERT(children_.size() == 1, "explain must has 1 child"); return RC::SUCCESS; @@ -54,7 +54,7 @@ RC ExplainPhysicalOperator::next() physical_plan_ = ss.str(); - std::vector cells; + vector cells; TupleCell cell; cell.set_string(physical_plan_.c_str()); cells.emplace_back(cell); @@ -106,7 +106,7 @@ void ExplainPhysicalOperator::to_string( } ends[level + 1] = false; - std::vector> &children = oper->children(); + vector> &children = oper->children(); const auto size = static_cast(children.size()); for (auto i = 0; i < size - 1; i++) { to_string(os, children[i].get(), level + 1, false /*last_child*/, ends); diff --git a/src/observer/sql/operator/explain_physical_operator.h b/src/observer/sql/operator/explain_physical_operator.h index 72acc0b..c47005a 100644 --- a/src/observer/sql/operator/explain_physical_operator.h +++ b/src/observer/sql/operator/explain_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -16,7 +16,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/physical_operator.h" -class ExplainPhysicalOperator : public PhysicalOperator { +class ExplainPhysicalOperator : public PhysicalOperator +{ public: ExplainPhysicalOperator() = default; virtual ~ExplainPhysicalOperator() = default; @@ -26,7 +27,7 @@ public: return PhysicalOperatorType::EXPLAIN; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; Tuple *current_tuple() override; diff --git a/src/observer/sql/operator/index_scan_physical_operator.cpp b/src/observer/sql/operator/index_scan_physical_operator.cpp index ab54d77..0c0341f 100644 --- a/src/observer/sql/operator/index_scan_physical_operator.cpp +++ b/src/observer/sql/operator/index_scan_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -14,10 +14,17 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/index_scan_physical_operator.h" #include "storage/index/index.h" - -IndexScanPhysicalOperator::IndexScanPhysicalOperator(const Table *table, Index *index, const TupleCell *left_cell, - bool left_inclusive, const TupleCell *right_cell, bool right_inclusive) - : table_(table), index_(index), left_inclusive_(left_inclusive), right_inclusive_(right_inclusive) +#include "storage/trx/trx.h" + +IndexScanPhysicalOperator::IndexScanPhysicalOperator( + Table *table, Index *index, bool readonly, + const TupleCell *left_cell, bool left_inclusive, + const TupleCell *right_cell, bool right_inclusive) + : table_(table), + index_(index), + readonly_(readonly), + left_inclusive_(left_inclusive), + right_inclusive_(right_inclusive) { if (left_cell) { left_cell_ = *left_cell; @@ -27,7 +34,7 @@ IndexScanPhysicalOperator::IndexScanPhysicalOperator(const Table *table, Index * } } -RC IndexScanPhysicalOperator::open() +RC IndexScanPhysicalOperator::open(Trx *trx) { if (nullptr == table_ || nullptr == index_) { return RC::INTERNAL; @@ -54,6 +61,7 @@ RC IndexScanPhysicalOperator::open() tuple_.set_schema(table_, table_->table_meta().field_metas()); + trx_ = trx; return RC::SUCCESS; } @@ -62,9 +70,11 @@ RC IndexScanPhysicalOperator::next() RID rid; RC rc = RC::SUCCESS; + record_page_handler_.cleanup(); + bool filter_result = false; while (RC::SUCCESS == (rc = index_scanner_->next_entry(&rid))) { - rc = record_handler_->get_record(&rid, ¤t_record_); + rc = record_handler_->get_record(record_page_handler_, &rid, readonly_, ¤t_record_); if (rc != RC::SUCCESS) { return rc; } @@ -75,7 +85,14 @@ RC IndexScanPhysicalOperator::next() return rc; } - if (filter_result) { + if (!filter_result) { + continue; + } + + rc = trx_->visit_record(table_, current_record_, readonly_); + if (rc == RC::RECORD_INVISIBLE) { + continue; + } else { return rc; } } diff --git a/src/observer/sql/operator/index_scan_physical_operator.h b/src/observer/sql/operator/index_scan_physical_operator.h index edcadcf..8b4e2da 100644 --- a/src/observer/sql/operator/index_scan_physical_operator.h +++ b/src/observer/sql/operator/index_scan_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -16,10 +16,13 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/physical_operator.h" #include "sql/expr/tuple.h" +#include "storage/record/record_manager.h" -class IndexScanPhysicalOperator : public PhysicalOperator { +class IndexScanPhysicalOperator : public PhysicalOperator +{ public: - IndexScanPhysicalOperator(const Table *table, Index *index, const TupleCell *left_cell, bool left_inclusive, + IndexScanPhysicalOperator(Table *table, Index *index, bool readonly, + const TupleCell *left_cell, bool left_inclusive, const TupleCell *right_cell, bool right_inclusive); virtual ~IndexScanPhysicalOperator() = default; @@ -31,7 +34,7 @@ public: std::string param() const override; - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; @@ -44,18 +47,21 @@ private: RC filter(RowTuple &tuple, bool &result); private: - const Table *table_ = nullptr; + Trx * trx_ = nullptr; + Table *table_ = nullptr; Index *index_ = nullptr; + bool readonly_ = false; IndexScanner *index_scanner_ = nullptr; RecordFileHandler *record_handler_ = nullptr; + RecordPageHandler record_page_handler_; Record current_record_; RowTuple tuple_; TupleCell left_cell_; TupleCell right_cell_; - bool left_inclusive_; - bool right_inclusive_; + bool left_inclusive_ = false; + bool right_inclusive_ = false; std::vector> predicates_; }; diff --git a/src/observer/sql/operator/insert_logical_operator.cpp b/src/observer/sql/operator/insert_logical_operator.cpp new file mode 100644 index 0000000..3635c0d --- /dev/null +++ b/src/observer/sql/operator/insert_logical_operator.cpp @@ -0,0 +1,20 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by WangYunlai on 2023/4/25. +// + +#include "sql/operator/insert_logical_operator.h" + +InsertLogicalOperator::InsertLogicalOperator(Table *table, std::vector values) + : table_(table), values_(values) +{ +} diff --git a/src/observer/sql/operator/insert_logical_operator.h b/src/observer/sql/operator/insert_logical_operator.h new file mode 100644 index 0000000..e54bf1e --- /dev/null +++ b/src/observer/sql/operator/insert_logical_operator.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by WangYunlai on 2023/4/25. +// + +#pragma once + +#include + +#include "sql/operator/logical_operator.h" +#include "sql/parser/parse_defs.h" + +class InsertLogicalOperator : public LogicalOperator +{ +public: + InsertLogicalOperator(Table *table, std::vector values); + virtual ~InsertLogicalOperator() = default; + + LogicalOperatorType type() const override + { + return LogicalOperatorType::INSERT; + } + + Table *table() const { return table_; } + const std::vector &values() const { return values_; } + std::vector &values() { return values_; } + +private: + Table *table_ = nullptr; + std::vector values_; +}; \ No newline at end of file diff --git a/src/observer/sql/operator/insert_physical_operator.cpp b/src/observer/sql/operator/insert_physical_operator.cpp index c20d28b..682b9dc 100644 --- a/src/observer/sql/operator/insert_physical_operator.cpp +++ b/src/observer/sql/operator/insert_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -15,14 +15,29 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/insert_physical_operator.h" #include "sql/stmt/insert_stmt.h" #include "storage/common/table.h" +#include "storage/trx/trx.h" #include "rc.h" -RC InsertPhysicalOperator::open() +using namespace std; + +InsertPhysicalOperator::InsertPhysicalOperator(Table *table, vector &&values) + : table_(table), values_(move(values)) +{} + +RC InsertPhysicalOperator::open(Trx *trx) { - Table *table = insert_stmt_->table(); - const Value *values = insert_stmt_->values(); - int value_amount = insert_stmt_->value_amount(); - return table->insert_record(nullptr, value_amount, values); // TODO trx + Record record; + RC rc = table_->make_record(static_cast(values_.size()), values_.data(), record); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to make record. rc=%s", strrc(rc)); + return rc; + } + + rc = trx->insert_record(table_, record); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to insert record by transaction. rc=%s", strrc(rc)); + } + return rc; } RC InsertPhysicalOperator::next() diff --git a/src/observer/sql/operator/insert_physical_operator.h b/src/observer/sql/operator/insert_physical_operator.h index 00ecb64..bc08444 100644 --- a/src/observer/sql/operator/insert_physical_operator.h +++ b/src/observer/sql/operator/insert_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -14,16 +14,17 @@ See the Mulan PSL v2 for more details. */ #pragma once +#include #include "sql/operator/physical_operator.h" #include "sql/parser/parse.h" #include "rc.h" class InsertStmt; -class InsertPhysicalOperator : public PhysicalOperator { +class InsertPhysicalOperator : public PhysicalOperator +{ public: - InsertPhysicalOperator(InsertStmt *insert_stmt) : insert_stmt_(insert_stmt) - {} + InsertPhysicalOperator(Table *table, std::vector &&values); virtual ~InsertPhysicalOperator() = default; @@ -32,10 +33,13 @@ public: return PhysicalOperatorType::INSERT; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; + Tuple *current_tuple() override { return nullptr; } + private: - InsertStmt *insert_stmt_ = nullptr; + Table *table_ = nullptr; + std::vector values_; }; diff --git a/src/observer/sql/operator/join_logical_operator.h b/src/observer/sql/operator/join_logical_operator.h index 9b68754..42c4a0a 100644 --- a/src/observer/sql/operator/join_logical_operator.h +++ b/src/observer/sql/operator/join_logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/operator/join_physical_operator.cpp b/src/observer/sql/operator/join_physical_operator.cpp index 261781f..a653b21 100644 --- a/src/observer/sql/operator/join_physical_operator.cpp +++ b/src/observer/sql/operator/join_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,7 @@ See the Mulan PSL v2 for more details. */ NestedLoopJoinPhysicalOperator::NestedLoopJoinPhysicalOperator() {} -RC NestedLoopJoinPhysicalOperator::open() +RC NestedLoopJoinPhysicalOperator::open(Trx *trx) { if (children_.size() != 2) { LOG_WARN("nlj operator should have 2 children"); @@ -30,7 +30,8 @@ RC NestedLoopJoinPhysicalOperator::open() right_closed_ = true; round_done_ = true; - rc = left_->open(); + rc = left_->open(trx); + trx_ = trx; return rc; } @@ -112,7 +113,7 @@ RC NestedLoopJoinPhysicalOperator::right_next() } } - rc = right_->open(); + rc = right_->open(trx_); if (rc != RC::SUCCESS) { return rc; } diff --git a/src/observer/sql/operator/join_physical_operator.h b/src/observer/sql/operator/join_physical_operator.h index 5ee5681..55edc80 100644 --- a/src/observer/sql/operator/join_physical_operator.h +++ b/src/observer/sql/operator/join_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -22,7 +22,8 @@ See the Mulan PSL v2 for more details. */ * 最简单的两表(称为左表、右表)join算子 * 依次遍历左表的每一行,然后关联右表的每一行 */ -class NestedLoopJoinPhysicalOperator : public PhysicalOperator { +class NestedLoopJoinPhysicalOperator : public PhysicalOperator +{ public: NestedLoopJoinPhysicalOperator(); virtual ~NestedLoopJoinPhysicalOperator() = default; @@ -32,7 +33,7 @@ public: return PhysicalOperatorType::NESTED_LOOP_JOIN; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; Tuple *current_tuple() override; @@ -42,6 +43,8 @@ private: RC right_next(); //! 右表遍历下一条数据,如果上一轮结束了就重新开始新的一轮 private: + Trx *trx_ = nullptr; + //! 左表右表的真实对象是在PhysicalOperator::children_中,这里是为了写的时候更简单 PhysicalOperator *left_ = nullptr; PhysicalOperator *right_ = nullptr; diff --git a/src/observer/sql/operator/logical_operator.cpp b/src/observer/sql/operator/logical_operator.cpp index 51d0b51..4672f02 100644 --- a/src/observer/sql/operator/logical_operator.cpp +++ b/src/observer/sql/operator/logical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/operator/logical_operator.h b/src/observer/sql/operator/logical_operator.h index 8564612..e66a5c8 100644 --- a/src/observer/sql/operator/logical_operator.h +++ b/src/observer/sql/operator/logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,11 +19,13 @@ See the Mulan PSL v2 for more details. */ #include "sql/expr/expression.h" -enum class LogicalOperatorType { +enum class LogicalOperatorType +{ TABLE_GET, PREDICATE, PROJECTION, JOIN, + INSERT, DELETE, EXPLAIN, }; @@ -32,7 +34,8 @@ enum class LogicalOperatorType { * 逻辑算子描述当前执行计划要做什么 * 可以看OptimizeStage中相关的代码 */ -class LogicalOperator { +class LogicalOperator +{ public: LogicalOperator() = default; virtual ~LogicalOperator(); diff --git a/src/observer/sql/operator/physical_operator.cpp b/src/observer/sql/operator/physical_operator.cpp index eea6164..6f70ca9 100644 --- a/src/observer/sql/operator/physical_operator.cpp +++ b/src/observer/sql/operator/physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -27,6 +27,10 @@ std::string physical_operator_type_name(PhysicalOperatorType type) return "EXPLAIN"; case PhysicalOperatorType::PREDICATE: return "PREDICATE"; + case PhysicalOperatorType::INSERT: + return "INSERT"; + case PhysicalOperatorType::DELETE: + return "DELETE"; case PhysicalOperatorType::PROJECT: return "PROJECT"; case PhysicalOperatorType::STRING_LIST: diff --git a/src/observer/sql/operator/physical_operator.h b/src/observer/sql/operator/physical_operator.h index fbb739b..cb871c6 100644 --- a/src/observer/sql/operator/physical_operator.h +++ b/src/observer/sql/operator/physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -23,8 +23,10 @@ See the Mulan PSL v2 for more details. */ class Record; class TupleCellSpec; +class Trx; -enum class PhysicalOperatorType { +enum class PhysicalOperatorType +{ TABLE_SCAN, INDEX_SCAN, NESTED_LOOP_JOIN, @@ -39,10 +41,10 @@ enum class PhysicalOperatorType { /** * 与LogicalOperator对应,物理算子描述执行计划将如何执行 */ -class PhysicalOperator { +class PhysicalOperator +{ public: - PhysicalOperator() - {} + PhysicalOperator() = default; virtual ~PhysicalOperator(); @@ -54,7 +56,7 @@ public: virtual PhysicalOperatorType type() const = 0; - virtual RC open() = 0; + virtual RC open(Trx *trx) = 0; virtual RC next() = 0; virtual RC close() = 0; diff --git a/src/observer/sql/operator/predicate_logical_operator.cpp b/src/observer/sql/operator/predicate_logical_operator.cpp index a19c2d5..3c7fd12 100644 --- a/src/observer/sql/operator/predicate_logical_operator.cpp +++ b/src/observer/sql/operator/predicate_logical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/operator/predicate_logical_operator.h b/src/observer/sql/operator/predicate_logical_operator.h index aafd369..f92dcb0 100644 --- a/src/observer/sql/operator/predicate_logical_operator.h +++ b/src/observer/sql/operator/predicate_logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/logical_operator.h" #include "sql/expr/expression.h" -class PredicateLogicalOperator : public LogicalOperator { +class PredicateLogicalOperator : public LogicalOperator +{ public: PredicateLogicalOperator(std::unique_ptr expression); virtual ~PredicateLogicalOperator() = default; diff --git a/src/observer/sql/operator/predicate_physical_operator.cpp b/src/observer/sql/operator/predicate_physical_operator.cpp index 9cdb848..416640b 100644 --- a/src/observer/sql/operator/predicate_physical_operator.cpp +++ b/src/observer/sql/operator/predicate_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -23,14 +23,14 @@ PredicatePhysicalOperator::PredicatePhysicalOperator(std::unique_ptr ASSERT(expression_->value_type() == BOOLEANS, "predicate's expression should be BOOLEAN type"); } -RC PredicatePhysicalOperator::open() +RC PredicatePhysicalOperator::open(Trx *trx) { if (children_.size() != 1) { LOG_WARN("predicate operator must has one child"); return RC::INTERNAL; } - return children_[0]->open(); + return children_[0]->open(trx); } RC PredicatePhysicalOperator::next() diff --git a/src/observer/sql/operator/predicate_physical_operator.h b/src/observer/sql/operator/predicate_physical_operator.h index 8539628..8ecad52 100644 --- a/src/observer/sql/operator/predicate_physical_operator.h +++ b/src/observer/sql/operator/predicate_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,7 +20,8 @@ See the Mulan PSL v2 for more details. */ class FilterStmt; -class PredicatePhysicalOperator : public PhysicalOperator { +class PredicatePhysicalOperator : public PhysicalOperator +{ public: PredicatePhysicalOperator(std::unique_ptr expr); @@ -31,7 +32,7 @@ public: return PhysicalOperatorType::PREDICATE; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; diff --git a/src/observer/sql/operator/project_logical_operator.cpp b/src/observer/sql/operator/project_logical_operator.cpp index 945883e..8e253bd 100644 --- a/src/observer/sql/operator/project_logical_operator.cpp +++ b/src/observer/sql/operator/project_logical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/operator/project_logical_operator.h b/src/observer/sql/operator/project_logical_operator.h index 88dd3b5..4a856c0 100644 --- a/src/observer/sql/operator/project_logical_operator.h +++ b/src/observer/sql/operator/project_logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -24,7 +24,8 @@ See the Mulan PSL v2 for more details. */ /** * project 表示投影运算 */ -class ProjectLogicalOperator : public LogicalOperator { +class ProjectLogicalOperator : public LogicalOperator +{ public: ProjectLogicalOperator(const std::vector &fields); virtual ~ProjectLogicalOperator() = default; diff --git a/src/observer/sql/operator/project_physical_operator.cpp b/src/observer/sql/operator/project_physical_operator.cpp index 7226823..f8f8c35 100644 --- a/src/observer/sql/operator/project_physical_operator.cpp +++ b/src/observer/sql/operator/project_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,14 +17,14 @@ See the Mulan PSL v2 for more details. */ #include "storage/record/record.h" #include "storage/common/table.h" -RC ProjectPhysicalOperator::open() +RC ProjectPhysicalOperator::open(Trx *trx) { if (children_.empty()) { return RC::SUCCESS; } PhysicalOperator *child = children_[0].get(); - RC rc = child->open(); + RC rc = child->open(trx); if (rc != RC::SUCCESS) { LOG_WARN("failed to open child operator: %s", strrc(rc)); return rc; diff --git a/src/observer/sql/operator/project_physical_operator.h b/src/observer/sql/operator/project_physical_operator.h index 301ea3e..e69028a 100644 --- a/src/observer/sql/operator/project_physical_operator.h +++ b/src/observer/sql/operator/project_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/physical_operator.h" #include "rc.h" -class ProjectPhysicalOperator : public PhysicalOperator { +class ProjectPhysicalOperator : public PhysicalOperator +{ public: ProjectPhysicalOperator() {} @@ -31,7 +32,7 @@ public: return PhysicalOperatorType::PROJECT; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; diff --git a/src/observer/sql/operator/string_list_physical_operator.h b/src/observer/sql/operator/string_list_physical_operator.h index 19fba78..1957fa9 100644 --- a/src/observer/sql/operator/string_list_physical_operator.h +++ b/src/observer/sql/operator/string_list_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,8 @@ See the Mulan PSL v2 for more details. */ #include #include "sql/operator/physical_operator.h" -class StringListPhysicalOperator : public PhysicalOperator { +class StringListPhysicalOperator : public PhysicalOperator +{ public: StringListPhysicalOperator() {} @@ -46,7 +47,7 @@ public: return PhysicalOperatorType::STRING_LIST; } - RC open() override + RC open(Trx *) override { return RC::SUCCESS; } diff --git a/src/observer/sql/operator/table_get_logical_operator.cpp b/src/observer/sql/operator/table_get_logical_operator.cpp index 4e1f14e..b1f975d 100644 --- a/src/observer/sql/operator/table_get_logical_operator.cpp +++ b/src/observer/sql/operator/table_get_logical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -14,8 +14,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/table_get_logical_operator.h" -TableGetLogicalOperator::TableGetLogicalOperator(Table *table, const std::vector &fields) - : table_(table), fields_(fields) +TableGetLogicalOperator::TableGetLogicalOperator(Table *table, const std::vector &fields, bool readonly) + : table_(table), fields_(fields), readonly_(readonly) {} void TableGetLogicalOperator::set_predicates(std::vector> &&exprs) diff --git a/src/observer/sql/operator/table_get_logical_operator.h b/src/observer/sql/operator/table_get_logical_operator.h index cf8011c..448f3bc 100644 --- a/src/observer/sql/operator/table_get_logical_operator.h +++ b/src/observer/sql/operator/table_get_logical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,9 +20,10 @@ See the Mulan PSL v2 for more details. */ * 表示从表中获取数据的算子 * 比如使用全表扫描、通过索引获取数据等 */ -class TableGetLogicalOperator : public LogicalOperator { +class TableGetLogicalOperator : public LogicalOperator +{ public: - TableGetLogicalOperator(Table *table, const std::vector &fields); + TableGetLogicalOperator(Table *table, const std::vector &fields, bool readonly); virtual ~TableGetLogicalOperator() = default; LogicalOperatorType type() const override @@ -30,10 +31,8 @@ public: return LogicalOperatorType::TABLE_GET; } - Table *table() const - { - return table_; - } + Table *table() const { return table_; } + bool readonly() const { return readonly_; } void set_predicates(std::vector> &&exprs); std::vector> &predicates() @@ -44,6 +43,7 @@ public: private: Table *table_ = nullptr; std::vector fields_; + bool readonly_ = false; // 与当前表相关的过滤操作,可以尝试在遍历数据时执行 // 这里的表达式都是比较简单的比较运算,并且左右两边都是取字段表达式或值表达式 diff --git a/src/observer/sql/operator/table_scan_physical_operator.cpp b/src/observer/sql/operator/table_scan_physical_operator.cpp index e274d49..d5ea9e0 100644 --- a/src/observer/sql/operator/table_scan_physical_operator.cpp +++ b/src/observer/sql/operator/table_scan_physical_operator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -16,12 +16,15 @@ See the Mulan PSL v2 for more details. */ #include "storage/common/table.h" #include "rc.h" -RC TableScanPhysicalOperator::open() +using namespace std; + +RC TableScanPhysicalOperator::open(Trx *trx) { - RC rc = table_->get_record_scanner(record_scanner_); + RC rc = table_->get_record_scanner(record_scanner_, trx, readonly_); if (rc == RC::SUCCESS) { tuple_.set_schema(table_, table_->table_meta().field_metas()); } + trx_ = trx; return rc; } @@ -65,21 +68,21 @@ Tuple *TableScanPhysicalOperator::current_tuple() return &tuple_; } -std::string TableScanPhysicalOperator::param() const +string TableScanPhysicalOperator::param() const { return table_->name(); } -void TableScanPhysicalOperator::set_predicates(std::vector> &&exprs) +void TableScanPhysicalOperator::set_predicates(vector> &&exprs) { - predicates_ = std::move(exprs); + predicates_ = move(exprs); } RC TableScanPhysicalOperator::filter(RowTuple &tuple, bool &result) { RC rc = RC::SUCCESS; TupleCell value; - for (std::unique_ptr &expr : predicates_) { + for (unique_ptr &expr : predicates_) { rc = expr->get_value(tuple, value); if (rc != RC::SUCCESS) { return rc; diff --git a/src/observer/sql/operator/table_scan_physical_operator.h b/src/observer/sql/operator/table_scan_physical_operator.h index 489534f..fa5a35e 100644 --- a/src/observer/sql/operator/table_scan_physical_operator.h +++ b/src/observer/sql/operator/table_scan_physical_operator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,9 +20,11 @@ See the Mulan PSL v2 for more details. */ class Table; -class TableScanPhysicalOperator : public PhysicalOperator { +class TableScanPhysicalOperator : public PhysicalOperator +{ public: - TableScanPhysicalOperator(Table *table) : table_(table) + TableScanPhysicalOperator(Table *table, bool readonly) + : table_(table), readonly_(readonly) {} virtual ~TableScanPhysicalOperator() = default; @@ -34,7 +36,7 @@ public: return PhysicalOperatorType::TABLE_SCAN; } - RC open() override; + RC open(Trx *trx) override; RC next() override; RC close() override; @@ -46,9 +48,11 @@ private: RC filter(RowTuple &tuple, bool &result); private: - Table *table_ = nullptr; - RecordFileScanner record_scanner_; - Record current_record_; - RowTuple tuple_; - std::vector> predicates_; + Table * table_ = nullptr; + Trx * trx_ = nullptr; + bool readonly_ = false; + RecordFileScanner record_scanner_; + Record current_record_; + RowTuple tuple_; + std::vector> predicates_; // TODO chang predicate to table tuple filter }; diff --git a/src/observer/sql/optimizer/comparison_simplification_rule.cpp b/src/observer/sql/optimizer/comparison_simplification_rule.cpp index 5a3b2b3..10d89fd 100644 --- a/src/observer/sql/optimizer/comparison_simplification_rule.cpp +++ b/src/observer/sql/optimizer/comparison_simplification_rule.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/comparison_simplification_rule.h b/src/observer/sql/optimizer/comparison_simplification_rule.h index 06a628a..5a76e24 100644 --- a/src/observer/sql/optimizer/comparison_simplification_rule.h +++ b/src/observer/sql/optimizer/comparison_simplification_rule.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,7 +19,8 @@ See the Mulan PSL v2 for more details. */ class LogicalOperator; -class ComparisonSimplificationRule : public ExpressionRewriteRule { +class ComparisonSimplificationRule : public ExpressionRewriteRule +{ public: ComparisonSimplificationRule() = default; virtual ~ComparisonSimplificationRule() = default; diff --git a/src/observer/sql/optimizer/conjunction_simplification_rule.cpp b/src/observer/sql/optimizer/conjunction_simplification_rule.cpp index 213cd87..31e8f25 100644 --- a/src/observer/sql/optimizer/conjunction_simplification_rule.cpp +++ b/src/observer/sql/optimizer/conjunction_simplification_rule.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/conjunction_simplification_rule.h b/src/observer/sql/optimizer/conjunction_simplification_rule.h index 2978923..882a009 100644 --- a/src/observer/sql/optimizer/conjunction_simplification_rule.h +++ b/src/observer/sql/optimizer/conjunction_simplification_rule.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -23,7 +23,8 @@ class LogicalOperator; * 简化多个表达式联结的运算 * 比如只有一个表达式,或者表达式可以直接出来 */ -class ConjunctionSimplificationRule : public ExpressionRewriteRule { +class ConjunctionSimplificationRule : public ExpressionRewriteRule +{ public: ConjunctionSimplificationRule() = default; virtual ~ConjunctionSimplificationRule() = default; diff --git a/src/observer/sql/optimizer/expression_rewriter.cpp b/src/observer/sql/optimizer/expression_rewriter.cpp index 9e481de..3a8eb6f 100644 --- a/src/observer/sql/optimizer/expression_rewriter.cpp +++ b/src/observer/sql/optimizer/expression_rewriter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/expression_rewriter.h b/src/observer/sql/optimizer/expression_rewriter.h index c11535e..4948d60 100644 --- a/src/observer/sql/optimizer/expression_rewriter.h +++ b/src/observer/sql/optimizer/expression_rewriter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -21,7 +21,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/expr/expression.h" #include "sql/optimizer/rewrite_rule.h" -class ExpressionRewriter : public RewriteRule { +class ExpressionRewriter : public RewriteRule +{ public: ExpressionRewriter(); virtual ~ExpressionRewriter() = default; diff --git a/src/observer/sql/optimizer/optimize_stage.cpp b/src/observer/sql/optimizer/optimize_stage.cpp index 5cd0dc6..bb95a60 100644 --- a/src/observer/sql/optimizer/optimize_stage.cpp +++ b/src/observer/sql/optimizer/optimize_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -27,6 +27,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/project_logical_operator.h" #include "sql/operator/predicate_logical_operator.h" #include "sql/operator/table_get_logical_operator.h" +#include "sql/operator/insert_logical_operator.h" #include "sql/operator/delete_logical_operator.h" #include "sql/operator/join_logical_operator.h" #include "sql/operator/project_logical_operator.h" @@ -35,6 +36,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/stmt/stmt.h" #include "sql/stmt/filter_stmt.h" #include "sql/stmt/select_stmt.h" +#include "sql/stmt/insert_stmt.h" #include "sql/stmt/delete_stmt.h" #include "sql/stmt/explain_stmt.h" #include "event/sql_event.h" @@ -101,12 +103,11 @@ void OptimizeStage::handle_event(StageEvent *event) { LOG_TRACE("Enter"); SQLStageEvent *sql_event = static_cast(event); + SqlResult *sql_result = sql_event->session_event()->sql_result(); RC rc = handle_request(sql_event); if (rc != RC::UNIMPLENMENT && rc != RC::SUCCESS) { - SqlResult *sql_result = new SqlResult; sql_result->set_return_code(rc); - sql_event->session_event()->set_sql_result(sql_result); } else { execute_stage_->handle_event(event); } @@ -114,7 +115,7 @@ void OptimizeStage::handle_event(StageEvent *event) } RC OptimizeStage::handle_request(SQLStageEvent *sql_event) { - std::unique_ptr logical_operator; + unique_ptr logical_operator; RC rc = create_logical_plan(sql_event, logical_operator); if (rc != RC::SUCCESS) { if (rc != RC::UNIMPLENMENT) { @@ -135,7 +136,7 @@ RC OptimizeStage::handle_request(SQLStageEvent *sql_event) return rc; } - std::unique_ptr physical_operator; + unique_ptr physical_operator; rc = generate_physical_plan(logical_operator, physical_operator); if (rc != RC::SUCCESS) { LOG_WARN("failed to generate physical plan. rc=%s", strrc(rc)); @@ -147,14 +148,14 @@ RC OptimizeStage::handle_request(SQLStageEvent *sql_event) return rc; } -RC OptimizeStage::optimize(std::unique_ptr &oper) +RC OptimizeStage::optimize(unique_ptr &oper) { // do nothing return RC::SUCCESS; } RC OptimizeStage::generate_physical_plan( - std::unique_ptr &logical_operator, std::unique_ptr &physical_operator) + unique_ptr &logical_operator, unique_ptr &physical_operator) { RC rc = RC::SUCCESS; rc = physical_plan_generator_.create(*logical_operator, physical_operator); @@ -171,7 +172,7 @@ void OptimizeStage::callback_event(StageEvent *event, CallbackContext *context) return; } -RC OptimizeStage::rewrite(std::unique_ptr &logical_operator) +RC OptimizeStage::rewrite(unique_ptr &logical_operator) { RC rc = RC::SUCCESS; bool change_made = false; @@ -187,7 +188,7 @@ RC OptimizeStage::rewrite(std::unique_ptr &logical_operator) return rc; } -RC OptimizeStage::create_logical_plan(Stmt *stmt, std::unique_ptr &logical_operator) +RC OptimizeStage::create_logical_plan(Stmt *stmt, unique_ptr &logical_operator) { RC rc = RC::SUCCESS; switch (stmt->type()) { @@ -196,6 +197,11 @@ RC OptimizeStage::create_logical_plan(Stmt *stmt, std::unique_ptr(stmt); + rc = create_insert_logical_plan(insert_stmt, logical_operator); + } break; + case StmtType::DELETE: { DeleteStmt *delete_stmt = static_cast(stmt); rc = create_delete_logical_plan(delete_stmt, logical_operator); @@ -211,7 +217,7 @@ RC OptimizeStage::create_logical_plan(Stmt *stmt, std::unique_ptr &logical_operator) +RC OptimizeStage::create_logical_plan(SQLStageEvent *sql_event, unique_ptr &logical_operator) { Stmt *stmt = sql_event->stmt(); if (nullptr == stmt) { @@ -222,9 +228,9 @@ RC OptimizeStage::create_logical_plan(SQLStageEvent *sql_event, std::unique_ptr< } RC OptimizeStage::create_select_logical_plan( - SelectStmt *select_stmt, std::unique_ptr &logical_operator) + SelectStmt *select_stmt, unique_ptr &logical_operator) { - std::unique_ptr table_oper(nullptr); + unique_ptr table_oper(nullptr); const std::vector &tables = select_stmt->tables(); const std::vector &all_fields = select_stmt->query_fields(); @@ -236,25 +242,25 @@ RC OptimizeStage::create_select_logical_plan( } } - std::unique_ptr table_get_oper(new TableGetLogicalOperator(table, fields)); + unique_ptr table_get_oper(new TableGetLogicalOperator(table, fields, true/*readonly*/)); if (table_oper == nullptr) { table_oper = std::move(table_get_oper); } else { JoinLogicalOperator *join_oper = new JoinLogicalOperator; join_oper->add_child(std::move(table_oper)); join_oper->add_child(std::move(table_get_oper)); - table_oper = std::unique_ptr(join_oper); + table_oper = unique_ptr(join_oper); } } - std::unique_ptr predicate_oper; + unique_ptr predicate_oper; RC rc = create_predicate_logical_plan(select_stmt->filter_stmt(), predicate_oper); if (rc != RC::SUCCESS) { LOG_WARN("failed to create predicate logical plan. rc=%s", strrc(rc)); return rc; } - std::unique_ptr project_oper(new ProjectLogicalOperator(all_fields)); + unique_ptr project_oper(new ProjectLogicalOperator(all_fields)); if (predicate_oper) { predicate_oper->add_child(move(table_oper)); project_oper->add_child(move(predicate_oper)); @@ -267,19 +273,19 @@ RC OptimizeStage::create_select_logical_plan( } RC OptimizeStage::create_predicate_logical_plan( - FilterStmt *filter_stmt, std::unique_ptr &logical_operator) + FilterStmt *filter_stmt, unique_ptr &logical_operator) { - std::vector> cmp_exprs; + std::vector> cmp_exprs; const std::vector &filter_units = filter_stmt->filter_units(); for (const FilterUnit *filter_unit : filter_units) { const FilterObj &filter_obj_left = filter_unit->left(); const FilterObj &filter_obj_right = filter_unit->right(); - std::unique_ptr left(filter_obj_left.is_attr + unique_ptr left(filter_obj_left.is_attr ? static_cast(new FieldExpr(filter_obj_left.field)) : static_cast(new ValueExpr(filter_obj_left.value))); - std::unique_ptr right(filter_obj_right.is_attr + unique_ptr right(filter_obj_right.is_attr ? static_cast(new FieldExpr(filter_obj_right.field)) : static_cast(new ValueExpr(filter_obj_right.value))); @@ -287,18 +293,29 @@ RC OptimizeStage::create_predicate_logical_plan( cmp_exprs.emplace_back(cmp_expr); } - std::unique_ptr predicate_oper; + unique_ptr predicate_oper; if (!cmp_exprs.empty()) { - std::unique_ptr conjunction_expr(new ConjunctionExpr(ConjunctionExpr::Type::AND, cmp_exprs)); - predicate_oper = std::unique_ptr(new PredicateLogicalOperator(move(conjunction_expr))); + unique_ptr conjunction_expr(new ConjunctionExpr(ConjunctionExpr::Type::AND, cmp_exprs)); + predicate_oper = unique_ptr(new PredicateLogicalOperator(move(conjunction_expr))); } logical_operator = move(predicate_oper); return RC::SUCCESS; } +RC OptimizeStage::create_insert_logical_plan( + InsertStmt *insert_stmt, unique_ptr &logical_operator) +{ + Table *table = insert_stmt->table(); + vector values(insert_stmt->values(), insert_stmt->values() + insert_stmt->value_amount()); + + InsertLogicalOperator *insert_operator = new InsertLogicalOperator(table, values); + logical_operator.reset(insert_operator); + return RC::SUCCESS; +} + RC OptimizeStage::create_delete_logical_plan( - DeleteStmt *delete_stmt, std::unique_ptr &logical_operator) + DeleteStmt *delete_stmt, unique_ptr &logical_operator) { Table *table = delete_stmt->table(); FilterStmt *filter_stmt = delete_stmt->filter_stmt(); @@ -307,15 +324,15 @@ RC OptimizeStage::create_delete_logical_plan( const FieldMeta *field_meta = table->table_meta().field(i); fields.push_back(Field(table, field_meta)); } - std::unique_ptr table_get_oper(new TableGetLogicalOperator(table, fields)); + unique_ptr table_get_oper(new TableGetLogicalOperator(table, fields, false/*readonly*/)); - std::unique_ptr predicate_oper; + unique_ptr predicate_oper; RC rc = create_predicate_logical_plan(filter_stmt, predicate_oper); if (rc != RC::SUCCESS) { return rc; } - std::unique_ptr delete_oper(new DeleteLogicalOperator(table)); + unique_ptr delete_oper(new DeleteLogicalOperator(table)); if (predicate_oper) { predicate_oper->add_child(move(table_get_oper)); @@ -329,17 +346,17 @@ RC OptimizeStage::create_delete_logical_plan( } RC OptimizeStage::create_explain_logical_plan( - ExplainStmt *explain_stmt, std::unique_ptr &logical_operator) + ExplainStmt *explain_stmt, unique_ptr &logical_operator) { Stmt *child_stmt = explain_stmt->child(); - std::unique_ptr child_oper; + unique_ptr child_oper; RC rc = create_logical_plan(child_stmt, child_oper); if (rc != RC::SUCCESS) { LOG_WARN("failed to create explain's child operator. rc=%s", strrc(rc)); return rc; } - logical_operator = std::unique_ptr(new ExplainLogicalOperator); + logical_operator = unique_ptr(new ExplainLogicalOperator); logical_operator->add_child(std::move(child_oper)); return rc; } diff --git a/src/observer/sql/optimizer/optimize_stage.h b/src/observer/sql/optimizer/optimize_stage.h index 13809e0..75c2ccb 100644 --- a/src/observer/sql/optimizer/optimize_stage.h +++ b/src/observer/sql/optimizer/optimize_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -27,11 +27,13 @@ class SQLStageEvent; class LogicalOperator; class Stmt; class SelectStmt; +class InsertStmt; class DeleteStmt; class FilterStmt; class ExplainStmt; -class OptimizeStage : public common::Stage { +class OptimizeStage : public common::Stage +{ public: ~OptimizeStage(); static Stage *make_stage(const std::string &tag); @@ -53,6 +55,7 @@ private: RC create_logical_plan(Stmt *stmt, std::unique_ptr &logical_operator); RC create_select_logical_plan(SelectStmt *select_stmt, std::unique_ptr &logical_operator); RC create_predicate_logical_plan(FilterStmt *filter_stmt, std::unique_ptr &logical_operator); + RC create_insert_logical_plan(InsertStmt *insert_stmt, std::unique_ptr &logical_operator); RC create_delete_logical_plan(DeleteStmt *delete_stmt, std::unique_ptr &logical_operator); RC create_explain_logical_plan(ExplainStmt *explain_stmt, std::unique_ptr &logical_operator); diff --git a/src/observer/sql/optimizer/physical_plan_generator.cpp b/src/observer/sql/optimizer/physical_plan_generator.cpp index 2a82c1e..6b0ffc4 100644 --- a/src/observer/sql/optimizer/physical_plan_generator.cpp +++ b/src/observer/sql/optimizer/physical_plan_generator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,6 +20,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/predicate_physical_operator.h" #include "sql/operator/project_logical_operator.h" #include "sql/operator/project_physical_operator.h" +#include "sql/operator/insert_logical_operator.h" +#include "sql/operator/insert_physical_operator.h" #include "sql/operator/delete_logical_operator.h" #include "sql/operator/delete_physical_operator.h" #include "sql/operator/explain_logical_operator.h" @@ -31,7 +33,7 @@ See the Mulan PSL v2 for more details. */ using namespace std; -RC PhysicalPlanGenerator::create(LogicalOperator &logical_operator, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create(LogicalOperator &logical_operator, unique_ptr &oper) { RC rc = RC::SUCCESS; @@ -48,6 +50,10 @@ RC PhysicalPlanGenerator::create(LogicalOperator &logical_operator, std::unique_ return create_plan(static_cast(logical_operator), oper); } break; + case LogicalOperatorType::INSERT: { + return create_plan(static_cast(logical_operator), oper); + } break; + case LogicalOperatorType::DELETE: { return create_plan(static_cast(logical_operator), oper); } break; @@ -67,9 +73,9 @@ RC PhysicalPlanGenerator::create(LogicalOperator &logical_operator, std::unique_ return rc; } -RC PhysicalPlanGenerator::create_plan(TableGetLogicalOperator &table_get_oper, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create_plan(TableGetLogicalOperator &table_get_oper, unique_ptr &oper) { - std::vector> &predicates = table_get_oper.predicates(); + vector> &predicates = table_get_oper.predicates(); // 看看是否有可以用于索引查找的表达式 Table *table = table_get_oper.table(); @@ -83,8 +89,8 @@ RC PhysicalPlanGenerator::create_plan(TableGetLogicalOperator &table_get_oper, s continue; } - std::unique_ptr &left_expr = comparison_expr->left(); - std::unique_ptr &right_expr = comparison_expr->right(); + unique_ptr &left_expr = comparison_expr->left(); + unique_ptr &right_expr = comparison_expr->right(); // 左右比较的一边最少是一个值 if (left_expr->type() != ExprType::VALUE && right_expr->type() != ExprType::VALUE) { continue; @@ -118,48 +124,51 @@ RC PhysicalPlanGenerator::create_plan(TableGetLogicalOperator &table_get_oper, s const TupleCell &tuple_cell = value_expr->get_tuple_cell(); IndexScanPhysicalOperator *index_scan_oper = new IndexScanPhysicalOperator( - table, index, &tuple_cell, true /*left_inclusive*/, &tuple_cell, true /*right_inclusive*/); - index_scan_oper->set_predicates(std::move(predicates)); - oper = std::unique_ptr(index_scan_oper); + table, index, table_get_oper.readonly(), + &tuple_cell, true /*left_inclusive*/, + &tuple_cell, true /*right_inclusive*/); + + index_scan_oper->set_predicates(move(predicates)); + oper = unique_ptr(index_scan_oper); LOG_TRACE("use index scan"); } else { - auto table_scan_oper = new TableScanPhysicalOperator(table); - table_scan_oper->set_predicates(std::move(predicates)); - oper = std::unique_ptr(table_scan_oper); + auto table_scan_oper = new TableScanPhysicalOperator(table, table_get_oper.readonly()); + table_scan_oper->set_predicates(move(predicates)); + oper = unique_ptr(table_scan_oper); LOG_TRACE("use table scan"); } return RC::SUCCESS; } -RC PhysicalPlanGenerator::create_plan(PredicateLogicalOperator &pred_oper, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create_plan(PredicateLogicalOperator &pred_oper, unique_ptr &oper) { - std::vector> &children_opers = pred_oper.children(); + vector> &children_opers = pred_oper.children(); ASSERT(children_opers.size() == 1, "predicate logical operator's sub oper number should be 1"); LogicalOperator &child_oper = *children_opers.front(); - std::unique_ptr child_phy_oper; + unique_ptr child_phy_oper; RC rc = create(child_oper, child_phy_oper); if (rc != RC::SUCCESS) { LOG_WARN("failed to create child operator of predicate operator. rc=%s", strrc(rc)); return rc; } - std::vector> &expressions = pred_oper.expressions(); + vector> &expressions = pred_oper.expressions(); ASSERT(expressions.size() == 1, "predicate logical operator's children should be 1"); - std::unique_ptr expression = std::move(expressions.front()); - oper = std::unique_ptr(new PredicatePhysicalOperator(std::move(expression))); - oper->add_child(std::move(child_phy_oper)); + unique_ptr expression = move(expressions.front()); + oper = unique_ptr(new PredicatePhysicalOperator(move(expression))); + oper->add_child(move(child_phy_oper)); return rc; } -RC PhysicalPlanGenerator::create_plan(ProjectLogicalOperator &project_oper, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create_plan(ProjectLogicalOperator &project_oper, unique_ptr &oper) { - std::vector> &child_opers = project_oper.children(); + vector> &child_opers = project_oper.children(); - std::unique_ptr child_phy_oper; + unique_ptr child_phy_oper; RC rc = RC::SUCCESS; if (!child_opers.empty()) { @@ -172,26 +181,35 @@ RC PhysicalPlanGenerator::create_plan(ProjectLogicalOperator &project_oper, std: } ProjectPhysicalOperator *project_operator = new ProjectPhysicalOperator; - const std::vector &project_fields = project_oper.fields(); + const vector &project_fields = project_oper.fields(); for (const Field &field : project_fields) { project_operator->add_projection(field.table(), field.meta()); } if (child_phy_oper) { - project_operator->add_child(std::move(child_phy_oper)); + project_operator->add_child(move(child_phy_oper)); } - oper = std::unique_ptr(project_operator); + oper = unique_ptr(project_operator); LOG_TRACE("create a project physical operator"); return rc; } -RC PhysicalPlanGenerator::create_plan(DeleteLogicalOperator &delete_oper, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create_plan(InsertLogicalOperator &insert_oper, unique_ptr &oper) +{ + Table *table = insert_oper.table(); + vector &values = insert_oper.values(); + InsertPhysicalOperator *insert_phy_oper = new InsertPhysicalOperator(table, move(values)); + oper.reset(insert_phy_oper); + return RC::SUCCESS; +} + +RC PhysicalPlanGenerator::create_plan(DeleteLogicalOperator &delete_oper, unique_ptr &oper) { - std::vector> &child_opers = delete_oper.children(); + vector> &child_opers = delete_oper.children(); - std::unique_ptr child_physical_oper; + unique_ptr child_physical_oper; RC rc = RC::SUCCESS; if (!child_opers.empty()) { @@ -203,7 +221,7 @@ RC PhysicalPlanGenerator::create_plan(DeleteLogicalOperator &delete_oper, std::u } } - oper = std::unique_ptr(new DeletePhysicalOperator(delete_oper.table(), nullptr)); + oper = unique_ptr(new DeletePhysicalOperator(delete_oper.table())); if (child_physical_oper) { oper->add_child(move(child_physical_oper)); @@ -211,49 +229,49 @@ RC PhysicalPlanGenerator::create_plan(DeleteLogicalOperator &delete_oper, std::u return rc; } -RC PhysicalPlanGenerator::create_plan(ExplainLogicalOperator &explain_oper, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create_plan(ExplainLogicalOperator &explain_oper, unique_ptr &oper) { - std::vector> &child_opers = explain_oper.children(); + vector> &child_opers = explain_oper.children(); RC rc = RC::SUCCESS; - std::unique_ptr explain_physical_oper(new ExplainPhysicalOperator); - for (std::unique_ptr &child_oper : child_opers) { - std::unique_ptr child_physical_oper; + unique_ptr explain_physical_oper(new ExplainPhysicalOperator); + for (unique_ptr &child_oper : child_opers) { + unique_ptr child_physical_oper; rc = create(*child_oper, child_physical_oper); if (rc != RC::SUCCESS) { LOG_WARN("failed to create child physical operator. rc=%s", strrc(rc)); return rc; } - explain_physical_oper->add_child(std::move(child_physical_oper)); + explain_physical_oper->add_child(move(child_physical_oper)); } - oper = std::move(explain_physical_oper); + oper = move(explain_physical_oper); return rc; } -RC PhysicalPlanGenerator::create_plan(JoinLogicalOperator &join_oper, std::unique_ptr &oper) +RC PhysicalPlanGenerator::create_plan(JoinLogicalOperator &join_oper, unique_ptr &oper) { RC rc = RC::SUCCESS; - std::vector> &child_opers = join_oper.children(); + vector> &child_opers = join_oper.children(); if (child_opers.size() != 2) { LOG_WARN("join operator should have 2 children, but have %d", child_opers.size()); return RC::INTERNAL; } - std::unique_ptr join_physical_oper(new NestedLoopJoinPhysicalOperator); + unique_ptr join_physical_oper(new NestedLoopJoinPhysicalOperator); for (auto &child_oper : child_opers) { - std::unique_ptr child_physical_oper; + unique_ptr child_physical_oper; rc = create(*child_oper, child_physical_oper); if (rc != RC::SUCCESS) { LOG_WARN("failed to create physical child oper. rc=%s", strrc(rc)); return rc; } - join_physical_oper->add_child(std::move(child_physical_oper)); + join_physical_oper->add_child(move(child_physical_oper)); } - oper = std::move(join_physical_oper); + oper = move(join_physical_oper); return rc; } diff --git a/src/observer/sql/optimizer/physical_plan_generator.h b/src/observer/sql/optimizer/physical_plan_generator.h index fca9819..1d567af 100644 --- a/src/observer/sql/optimizer/physical_plan_generator.h +++ b/src/observer/sql/optimizer/physical_plan_generator.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -23,6 +23,7 @@ See the Mulan PSL v2 for more details. */ class TableGetLogicalOperator; class PredicateLogicalOperator; class ProjectLogicalOperator; +class InsertLogicalOperator; class DeleteLogicalOperator; class ExplainLogicalOperator; class JoinLogicalOperator; @@ -35,10 +36,11 @@ public: RC create(LogicalOperator &logical_operator, std::unique_ptr &oper); private: - RC create_plan(TableGetLogicalOperator &table_get_oper, std::unique_ptr &oper); - RC create_plan(PredicateLogicalOperator &pred_oper, std::unique_ptr &oper); - RC create_plan(ProjectLogicalOperator &project_oper, std::unique_ptr &oper); - RC create_plan(DeleteLogicalOperator &delete_oper, std::unique_ptr &oper); - RC create_plan(ExplainLogicalOperator &explain_oper, std::unique_ptr &oper); - RC create_plan(JoinLogicalOperator &join_oper, std::unique_ptr &oper); + RC create_plan(TableGetLogicalOperator &logical_oper, std::unique_ptr &oper); + RC create_plan(PredicateLogicalOperator &logical_oper, std::unique_ptr &oper); + RC create_plan(ProjectLogicalOperator &logical_oper, std::unique_ptr &oper); + RC create_plan(InsertLogicalOperator &logical_oper, std::unique_ptr &oper); + RC create_plan(DeleteLogicalOperator &logical_oper, std::unique_ptr &oper); + RC create_plan(ExplainLogicalOperator &logical_oper, std::unique_ptr &oper); + RC create_plan(JoinLogicalOperator &logical_oper, std::unique_ptr &oper); }; diff --git a/src/observer/sql/optimizer/predicate_pushdown_rewriter.cpp b/src/observer/sql/optimizer/predicate_pushdown_rewriter.cpp index 23c3163..a2df7fe 100644 --- a/src/observer/sql/optimizer/predicate_pushdown_rewriter.cpp +++ b/src/observer/sql/optimizer/predicate_pushdown_rewriter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/predicate_pushdown_rewriter.h b/src/observer/sql/optimizer/predicate_pushdown_rewriter.h index a3921ff..ff8fad3 100644 --- a/src/observer/sql/optimizer/predicate_pushdown_rewriter.h +++ b/src/observer/sql/optimizer/predicate_pushdown_rewriter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -21,7 +21,8 @@ See the Mulan PSL v2 for more details. */ * 将一些谓词表达式下推到表数据扫描中 * 这样可以提前过滤一些数据 */ -class PredicatePushdownRewriter : public RewriteRule { +class PredicatePushdownRewriter : public RewriteRule +{ public: PredicatePushdownRewriter() = default; virtual ~PredicatePushdownRewriter() = default; diff --git a/src/observer/sql/optimizer/predicate_rewrite.cpp b/src/observer/sql/optimizer/predicate_rewrite.cpp index e94f65a..7c268bb 100644 --- a/src/observer/sql/optimizer/predicate_rewrite.cpp +++ b/src/observer/sql/optimizer/predicate_rewrite.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/predicate_rewrite.h b/src/observer/sql/optimizer/predicate_rewrite.h index a8ca79f..a1b0a7b 100644 --- a/src/observer/sql/optimizer/predicate_rewrite.h +++ b/src/observer/sql/optimizer/predicate_rewrite.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -16,7 +16,8 @@ See the Mulan PSL v2 for more details. */ #include "sql/optimizer/rewrite_rule.h" -class PredicateRewriteRule : public RewriteRule { +class PredicateRewriteRule : public RewriteRule +{ public: PredicateRewriteRule() = default; virtual ~PredicateRewriteRule() = default; diff --git a/src/observer/sql/optimizer/rewrite_rule.h b/src/observer/sql/optimizer/rewrite_rule.h index 1869928..0ddd2c5 100644 --- a/src/observer/sql/optimizer/rewrite_rule.h +++ b/src/observer/sql/optimizer/rewrite_rule.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/rewriter.cpp b/src/observer/sql/optimizer/rewriter.cpp index 237f3dc..dd025cb 100644 --- a/src/observer/sql/optimizer/rewriter.cpp +++ b/src/observer/sql/optimizer/rewriter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/optimizer/rewriter.h b/src/observer/sql/optimizer/rewriter.h index 54a3dac..9ea4805 100644 --- a/src/observer/sql/optimizer/rewriter.h +++ b/src/observer/sql/optimizer/rewriter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,7 +20,8 @@ See the Mulan PSL v2 for more details. */ class LogicalOperator; -class Rewriter { +class Rewriter +{ public: Rewriter(); virtual ~Rewriter() = default; diff --git a/src/observer/sql/parser/parse.cpp b/src/observer/sql/parser/parse.cpp index fea5ad5..6615afb 100644 --- a/src/observer/sql/parser/parse.cpp +++ b/src/observer/sql/parser/parse.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/parser/parse.h b/src/observer/sql/parser/parse.h index ad3d130..87dd475 100644 --- a/src/observer/sql/parser/parse.h +++ b/src/observer/sql/parser/parse.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/parser/parse_defs.h b/src/observer/sql/parser/parse_defs.h index db9da7e..d6df389 100644 --- a/src/observer/sql/parser/parse_defs.h +++ b/src/observer/sql/parser/parse_defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -26,12 +26,14 @@ See the Mulan PSL v2 for more details. */ #define MAX_DATA 50 // 属性结构体 -struct RelAttr { +struct RelAttr +{ std::string relation_name; // relation name (may be NULL) 表名 std::string attribute_name; // attribute name 属性名 }; -enum CompOp { +enum CompOp +{ EQUAL_TO, //"=" 0 LESS_EQUAL, //"<=" 1 NOT_EQUAL, //"<>" 2 @@ -42,7 +44,8 @@ enum CompOp { }; // 属性值类型 -enum AttrType { +enum AttrType +{ UNDEFINED, CHARS, INTS, @@ -51,7 +54,8 @@ enum AttrType { }; // 属性值 -struct Value { +struct Value +{ AttrType type; // type of value int int_value; float float_value; @@ -62,7 +66,8 @@ struct Value { int length(); }; -struct Condition { +struct Condition +{ int left_is_attr; // TRUE if left-hand side is an attribute // 1时,操作符左边是属性名,0时,是属性值 Value left_value; // left-hand side value if left_is_attr = FALSE @@ -75,84 +80,98 @@ struct Condition { }; // struct of select -struct Selects { +struct Selects +{ std::vector attributes; // attributes in select clause std::vector relations; std::vector conditions; }; // struct of insert -struct Inserts { +struct Inserts +{ std::string relation_name; // Relation to insert into std::vector values; }; // struct of delete -struct Deletes { +struct Deletes +{ std::string relation_name; // Relation to delete from std::vector conditions; }; // struct of update -struct Updates { +struct Updates +{ std::string relation_name; // Relation to update std::string attribute_name; // Attribute to update Value value; // update value std::vector conditions; }; -struct AttrInfo { +struct AttrInfo +{ AttrType type; // Type of attribute std::string name; // Attribute name size_t length; // Length of attribute }; // struct of craete_table -struct CreateTable { +struct CreateTable +{ std::string relation_name; // Relation name std::vector attr_infos; // attributes }; // struct of drop_table -struct DropTable { +struct DropTable +{ std::string relation_name; // Relation name }; // struct of create_index -struct CreateIndex { +struct CreateIndex +{ std::string index_name; // Index name std::string relation_name; // Relation name std::string attribute_name; // Attribute name }; // struct of drop_index -struct DropIndex { +struct DropIndex +{ std::string index_name; // Index name std::string relation_name; // Relation name }; -struct DescTable { +struct DescTable +{ std::string relation_name; }; -struct LoadData { +struct LoadData +{ std::string relation_name; std::string file_name; }; class Command; -struct Explain { +struct Explain +{ std::unique_ptr cmd; }; -struct Error { +struct Error +{ std::string error_msg; int line; int column; }; // 修改yacc中相关数字编码为宏定义 -enum SqlCommandFlag { +enum SqlCommandFlag +{ SCF_ERROR = 0, SCF_SELECT, SCF_INSERT, @@ -175,7 +194,8 @@ enum SqlCommandFlag { SCF_EXPLAIN, }; // struct of flag and sql_struct -class Command { +class Command +{ public: enum SqlCommandFlag flag; Error error; @@ -200,7 +220,8 @@ public: * 表示语法解析后的数据 * 叫ParsedSqlNode 可能会更清晰一点 */ -class ParsedSqlResult { +class ParsedSqlResult +{ public: void add_command(std::unique_ptr command); std::vector> &commands() diff --git a/src/observer/sql/parser/parse_stage.cpp b/src/observer/sql/parser/parse_stage.cpp index 144c564..5041878 100644 --- a/src/observer/sql/parser/parse_stage.cpp +++ b/src/observer/sql/parser/parse_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -121,16 +121,15 @@ void ParseStage::callback_event(StageEvent *event, CallbackContext *context) RC ParseStage::handle_request(StageEvent *event) { SQLStageEvent *sql_event = static_cast(event); + SqlResult *sql_result = sql_event->session_event()->sql_result(); const std::string &sql = sql_event->sql(); ParsedSqlResult parsed_sql_result; - SqlResult *sql_result = new SqlResult; parse(sql.c_str(), &parsed_sql_result); if (parsed_sql_result.commands().empty()) { sql_result->set_return_code(RC::SUCCESS); sql_result->set_state_string(""); - sql_event->session_event()->set_sql_result(sql_result); return RC::INTERNAL; } @@ -143,11 +142,9 @@ RC ParseStage::handle_request(StageEvent *event) // set error information to event sql_result->set_return_code(RC::SQL_SYNTAX); sql_result->set_state_string("Failed to parse sql"); - sql_event->session_event()->set_sql_result(sql_result); return RC::INTERNAL; } - delete sql_result; sql_event->set_command(std::move(cmd)); return RC::SUCCESS; } diff --git a/src/observer/sql/parser/parse_stage.h b/src/observer/sql/parser/parse_stage.h index 2824d89..f6905a1 100644 --- a/src/observer/sql/parser/parse_stage.h +++ b/src/observer/sql/parser/parse_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/parser/resolve_stage.cpp b/src/observer/sql/parser/resolve_stage.cpp index e53c531..4bddf57 100644 --- a/src/observer/sql/parser/resolve_stage.cpp +++ b/src/observer/sql/parser/resolve_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -94,6 +94,7 @@ void ResolveStage::handle_event(StageEvent *event) } SessionEvent *session_event = sql_event->session_event(); + SqlResult *sql_result = session_event->sql_result(); Db *db = session_event->session()->get_current_db(); if (nullptr == db) { @@ -106,9 +107,7 @@ void ResolveStage::handle_event(StageEvent *event) RC rc = Stmt::create_stmt(db, *cmd, stmt); if (rc != RC::SUCCESS && rc != RC::UNIMPLENMENT) { LOG_WARN("failed to create stmt. rc=%d:%s", rc, strrc(rc)); - SqlResult *sql_result = new SqlResult; sql_result->set_return_code(rc); - session_event->set_sql_result(sql_result); return; } diff --git a/src/observer/sql/parser/resolve_stage.h b/src/observer/sql/parser/resolve_stage.h index c2714c0..e4bf324 100644 --- a/src/observer/sql/parser/resolve_stage.h +++ b/src/observer/sql/parser/resolve_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/13. // -#ifndef __OBSERVER_SQL_RESOLVE_STAGE_H__ -#define __OBSERVER_SQL_RESOLVE_STAGE_H__ +#pragma once #include "common/seda/stage.h" @@ -36,5 +35,3 @@ protected: private: Stage *plan_cache_stage_ = nullptr; }; - -#endif //__OBSERVER_SQL_RESOLVE_STAGE_H__ diff --git a/src/observer/sql/plan_cache/plan_cache_stage.cpp b/src/observer/sql/plan_cache/plan_cache_stage.cpp index bad18bc..e3a012e 100644 --- a/src/observer/sql/plan_cache/plan_cache_stage.cpp +++ b/src/observer/sql/plan_cache/plan_cache_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/plan_cache/plan_cache_stage.h b/src/observer/sql/plan_cache/plan_cache_stage.h index bf39c02..e764777 100644 --- a/src/observer/sql/plan_cache/plan_cache_stage.h +++ b/src/observer/sql/plan_cache/plan_cache_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/13. // -#ifndef __OBSERVER_SQL_PLAN_CACHE_STAGE_H__ -#define __OBSERVER_SQL_PLAN_CACHE_STAGE_H__ +#pragma once #include "common/seda/stage.h" @@ -36,5 +35,3 @@ protected: private: Stage *optimizer_stage_ = nullptr; }; - -#endif //__OBSERVER_SQL_PLAN_CACHE_STAGE_H__ diff --git a/src/observer/sql/query_cache/query_cache_stage.cpp b/src/observer/sql/query_cache/query_cache_stage.cpp index 35e8122..b6b300e 100644 --- a/src/observer/sql/query_cache/query_cache_stage.cpp +++ b/src/observer/sql/query_cache/query_cache_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/query_cache/query_cache_stage.h b/src/observer/sql/query_cache/query_cache_stage.h index 2bbcbb5..834b1f3 100644 --- a/src/observer/sql/query_cache/query_cache_stage.h +++ b/src/observer/sql/query_cache/query_cache_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/13. // -#ifndef __OBSERVER_SQL_QUERY_CACHE_STAGE_H__ -#define __OBSERVER_SQL_QUERY_CACHE_STAGE_H__ +#pragma once #include "common/seda/stage.h" @@ -36,5 +35,3 @@ protected: private: Stage *parser_stage_ = nullptr; }; - -#endif //__OBSERVER_SQL_QUERY_CACHE_STAGE_H__ diff --git a/src/observer/sql/stmt/create_index_stmt.cpp b/src/observer/sql/stmt/create_index_stmt.cpp new file mode 100644 index 0000000..900b0f4 --- /dev/null +++ b/src/observer/sql/stmt/create_index_stmt.cpp @@ -0,0 +1,57 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/25. +// + +#include "sql/stmt/create_index_stmt.h" +#include "storage/common/table.h" +#include "storage/common/db.h" +#include "common/lang/string.h" +#include "common/log/log.h" + +using namespace std; +using namespace common; + +RC CreateIndexStmt::create(Db *db, const CreateIndex &create_index, Stmt *&stmt) +{ + stmt = nullptr; + + const char *table_name = create_index.relation_name.c_str(); + if (is_blank(table_name) || is_blank(create_index.index_name.c_str()) || is_blank(create_index.attribute_name.c_str())) { + LOG_WARN("invalid argument. db=%p, table_name=%p, index name=%s, attribute name=%s", + db, table_name, create_index.index_name.c_str(), create_index.attribute_name.c_str()); + return RC::INVALID_ARGUMENT; + } + + // check whether the table exists + Table *table = db->find_table(table_name); + if (nullptr == table) { + LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + const FieldMeta *field_meta = table->table_meta().field(create_index.attribute_name.c_str()); + if (nullptr == field_meta) { + LOG_WARN("no such field in table. db=%s, table=%s, field name=%s", + db->name(), table_name, create_index.attribute_name.c_str()); + return RC::SCHEMA_FIELD_NOT_EXIST; + } + + Index *index = table->find_index(create_index.index_name.c_str()); + if (nullptr != index) { + LOG_WARN("index with name(%s) already exists. table name=%s", create_index.index_name.c_str(), table_name); + return RC::SCHEMA_INDEX_NAME_REPEAT; + } + + stmt = new CreateIndexStmt(table, field_meta, create_index.index_name); + return RC::SUCCESS; +} diff --git a/src/observer/sql/stmt/create_index_stmt.h b/src/observer/sql/stmt/create_index_stmt.h new file mode 100644 index 0000000..fae5639 --- /dev/null +++ b/src/observer/sql/stmt/create_index_stmt.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/25. +// + +#pragma once + +#include + +#include "sql/stmt/stmt.h" + +struct CreateIndex; +class Table; +class FieldMeta; + +class CreateIndexStmt : public Stmt +{ +public: + CreateIndexStmt(Table *table, const FieldMeta *field_meta, const std::string &index_name) + : table_(table), + field_meta_(field_meta), + index_name_(index_name) + {} + + virtual ~CreateIndexStmt() = default; + + StmtType type() const override { return StmtType::CREATE_INDEX; } + + Table *table() const { return table_; } + const FieldMeta *field_meta() const { return field_meta_; } + const std::string &index_name() const { return index_name_; } + +public: + static RC create(Db *db, const CreateIndex &create_index, Stmt *&stmt); + +private: + Table *table_ = nullptr; + const FieldMeta *field_meta_ = nullptr; + std::string index_name_; +}; diff --git a/src/observer/sql/stmt/delete_stmt.cpp b/src/observer/sql/stmt/delete_stmt.cpp index 7319acd..8941cd6 100644 --- a/src/observer/sql/stmt/delete_stmt.cpp +++ b/src/observer/sql/stmt/delete_stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/delete_stmt.h b/src/observer/sql/stmt/delete_stmt.h index 5dfd1d4..5641e99 100644 --- a/src/observer/sql/stmt/delete_stmt.h +++ b/src/observer/sql/stmt/delete_stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/explain_stmt.cpp b/src/observer/sql/stmt/explain_stmt.cpp index 91602b4..f7c88aa 100644 --- a/src/observer/sql/stmt/explain_stmt.cpp +++ b/src/observer/sql/stmt/explain_stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/explain_stmt.h b/src/observer/sql/stmt/explain_stmt.h index 5a92bff..31b2745 100644 --- a/src/observer/sql/stmt/explain_stmt.h +++ b/src/observer/sql/stmt/explain_stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,8 @@ See the Mulan PSL v2 for more details. */ #include #include "sql/stmt/stmt.h" -class ExplainStmt : public Stmt { +class ExplainStmt : public Stmt +{ public: ExplainStmt(std::unique_ptr child_stmt); virtual ~ExplainStmt() = default; diff --git a/src/observer/sql/stmt/filter_stmt.cpp b/src/observer/sql/stmt/filter_stmt.cpp index afbba03..5183b93 100644 --- a/src/observer/sql/stmt/filter_stmt.cpp +++ b/src/observer/sql/stmt/filter_stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/filter_stmt.h b/src/observer/sql/stmt/filter_stmt.h index 374efb3..5e0b290 100644 --- a/src/observer/sql/stmt/filter_stmt.h +++ b/src/observer/sql/stmt/filter_stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/insert_stmt.cpp b/src/observer/sql/stmt/insert_stmt.cpp index 4c8d21b..9ad1f0e 100644 --- a/src/observer/sql/stmt/insert_stmt.cpp +++ b/src/observer/sql/stmt/insert_stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -26,9 +26,7 @@ RC InsertStmt::create(Db *db, const Inserts &inserts, Stmt *&stmt) const char *table_name = inserts.relation_name.c_str(); if (nullptr == db || nullptr == table_name || inserts.values.empty()) { LOG_WARN("invalid argument. db=%p, table_name=%p, value_num=%d", - db, - table_name, - static_cast(inserts.values.size())); + db, table_name, static_cast(inserts.values.size())); return RC::INVALID_ARGUMENT; } @@ -57,10 +55,7 @@ RC InsertStmt::create(Db *db, const Inserts &inserts, Stmt *&stmt) const AttrType value_type = values[i].type; if (field_type != value_type) { // TODO try to convert the value type to field type LOG_WARN("field type mismatch. table=%s, field=%s, field type=%d, value_type=%d", - table_name, - field_meta->name(), - field_type, - value_type); + table_name, field_meta->name(), field_type, value_type); return RC::SCHEMA_FIELD_TYPE_MISMATCH; } } diff --git a/src/observer/sql/stmt/insert_stmt.h b/src/observer/sql/stmt/insert_stmt.h index cd13b7c..bf6dcb7 100644 --- a/src/observer/sql/stmt/insert_stmt.h +++ b/src/observer/sql/stmt/insert_stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,7 +20,8 @@ See the Mulan PSL v2 for more details. */ class Table; class Db; -class InsertStmt : public Stmt { +class InsertStmt : public Stmt +{ public: InsertStmt() = default; InsertStmt(Table *table, const Value *values, int value_amount); diff --git a/src/observer/sql/stmt/select_stmt.cpp b/src/observer/sql/stmt/select_stmt.cpp index 7824be7..6e431ec 100644 --- a/src/observer/sql/stmt/select_stmt.cpp +++ b/src/observer/sql/stmt/select_stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/select_stmt.h b/src/observer/sql/stmt/select_stmt.h index 230525d..bb25177 100644 --- a/src/observer/sql/stmt/select_stmt.h +++ b/src/observer/sql/stmt/select_stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -25,7 +25,8 @@ class FilterStmt; class Db; class Table; -class SelectStmt : public Stmt { +class SelectStmt : public Stmt +{ public: SelectStmt() = default; ~SelectStmt() override; diff --git a/src/observer/sql/stmt/stmt.cpp b/src/observer/sql/stmt/stmt.cpp index ff00193..b4702ec 100644 --- a/src/observer/sql/stmt/stmt.cpp +++ b/src/observer/sql/stmt/stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -18,6 +18,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/stmt/delete_stmt.h" #include "sql/stmt/select_stmt.h" #include "sql/stmt/explain_stmt.h" +#include "sql/stmt/create_index_stmt.h" RC Stmt::create_stmt(Db *db, const Command &cmd, Stmt *&stmt) { @@ -37,6 +38,10 @@ RC Stmt::create_stmt(Db *db, const Command &cmd, Stmt *&stmt) case SCF_EXPLAIN: { return ExplainStmt::create(db, cmd.explain, stmt); } + + case SCF_CREATE_INDEX: { + return CreateIndexStmt::create(db, cmd.create_index, stmt); + } default: { LOG_INFO("Command::type %d doesn't need to create statement.", cmd.flag); } break; diff --git a/src/observer/sql/stmt/stmt.h b/src/observer/sql/stmt/stmt.h index ace75a7..9f795cf 100644 --- a/src/observer/sql/stmt/stmt.h +++ b/src/observer/sql/stmt/stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,7 +19,8 @@ See the Mulan PSL v2 for more details. */ class Db; -enum class StmtType { +enum class StmtType +{ SELECT, INSERT, UPDATE, @@ -42,7 +43,12 @@ enum class StmtType { PREDICATE, }; -class Stmt { +/** + * Stmt for Statement + * + */ +class Stmt +{ public: Stmt() = default; virtual ~Stmt() = default; diff --git a/src/observer/sql/stmt/update_stmt.cpp b/src/observer/sql/stmt/update_stmt.cpp index 742bd23..827e0da 100644 --- a/src/observer/sql/stmt/update_stmt.cpp +++ b/src/observer/sql/stmt/update_stmt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/sql/stmt/update_stmt.h b/src/observer/sql/stmt/update_stmt.h index f563263..4b8f7f7 100644 --- a/src/observer/sql/stmt/update_stmt.h +++ b/src/observer/sql/stmt/update_stmt.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,7 +19,8 @@ See the Mulan PSL v2 for more details. */ class Table; -class UpdateStmt : public Stmt { +class UpdateStmt : public Stmt +{ public: UpdateStmt() = default; UpdateStmt(Table *table, Value *values, int value_amount); diff --git a/src/observer/storage/buffer/frame.cpp b/src/observer/storage/buffer/frame.cpp index 77156b0..178ed92 100644 --- a/src/observer/storage/buffer/frame.cpp +++ b/src/observer/storage/buffer/frame.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -15,6 +15,8 @@ See the Mulan PSL v2 for more details. */ #include "storage/buffer/frame.h" #include "session/thread_data.h" +using namespace std; + FrameId::FrameId(int file_desc, PageNum page_num) : file_desc_(file_desc), page_num_(page_num) {} @@ -42,9 +44,9 @@ PageNum FrameId::page_num() const return page_num_; } -std::string to_string(const FrameId &frame_id) +string to_string(const FrameId &frame_id) { - std::stringstream ss; + stringstream ss; ss << "fd:" << frame_id.file_desc() << ",page_num:" << frame_id.page_num(); return ss.str(); } @@ -70,17 +72,12 @@ void Frame::write_latch() void Frame::write_latch(intptr_t xid) { { - std::scoped_lock debug_lock(debug_lock_); + scoped_lock debug_lock(debug_lock_); ASSERT(pin_count_.load() > 0, "frame lock. write lock failed while pin count is invalid. " "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(write_locker_ != xid, - "frame lock write twice." - "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(read_lockers_.find(xid) == read_lockers_.end(), "frame lock write while holding the read lock." "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", @@ -89,11 +86,11 @@ void Frame::write_latch(intptr_t xid) lock_.lock(); write_locker_ = xid; + write_recursive_count_++; LOG_DEBUG("frame write lock success." - "this=%p, pin=%d, pageNum=%d, write locker=%lx, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, write_locker_, file_desc_, xid, lbt()); - // pthread_rwlock_wrlock(&rwlock_); + "this=%p, pin=%d, pageNum=%d, write locker=%lx(recursive=%d), fd=%d, xid=%lx, lbt=%s", + this, pin_count_.load(), page_.page_num, write_locker_, write_recursive_count_, file_desc_, xid, lbt()); } void Frame::write_unlatch() @@ -118,9 +115,10 @@ void Frame::write_unlatch(intptr_t xid) LOG_DEBUG("frame write unlock success. this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - write_locker_ = 0; + if (--write_recursive_count_ == 0) { + write_locker_ = 0; + } lock_.unlock(); -// pthread_rwlock_unlock(&rwlock_); } void Frame::read_latch() @@ -136,24 +134,21 @@ void Frame::read_latch(intptr_t xid) "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(read_lockers_.find(xid) == read_lockers_.end(), - "frame lock read double times." - "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(xid != write_locker_, "frame lock read while holding the write lock." "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - - read_lockers_.insert(xid); } - lock_.lock(); - LOG_DEBUG("frame read lock success." - "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); -// pthread_rwlock_rdlock(&rwlock_); + lock_.lock_shared(); + + { + scoped_lock debug_lock(debug_lock_); + int recursive_count = ++read_lockers_[xid]; + LOG_DEBUG("frame read lock success." + "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, recursive=%d, lbt=%s", + this, pin_count_.load(), page_.page_num, file_desc_, xid, recursive_count, lbt()); + } } bool Frame::try_read_latch() @@ -165,24 +160,19 @@ bool Frame::try_read_latch() "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(read_lockers_.find(xid) == read_lockers_.end(), - "frame try to lock read double times." - "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(xid != write_locker_, "frame try to lock read while holding the write lock." "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); } - bool ret = lock_.try_lock(); + bool ret = lock_.try_lock_shared(); if (ret) { debug_lock_.lock(); - read_lockers_.insert(xid); + int recursive_count = ++read_lockers_[xid]; LOG_DEBUG("frame read lock success." - "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); + "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, recursive=%d, lbt=%s", + this, pin_count_.load(), page_.page_num, file_desc_, xid, recursive_count, lbt()); debug_lock_.unlock(); } @@ -203,20 +193,27 @@ void Frame::read_unlatch(intptr_t xid) "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - ASSERT(read_lockers_.find(xid) != read_lockers_.end(), +#if DEBUG + auto read_lock_iter = read_lockers_.find(xid); + int recursive_count = read_lock_iter != read_lockers_.end() ? read_lock_iter->second : 0; + ASSERT(recursive_count > 0, "frame unlock while not holding read lock." - "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", - this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); + "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, recursive=%d, lbt=%s", + this, pin_count_.load(), page_.page_num, file_desc_, xid, recursive_count, lbt()); + + if (1 == recursive_count) { + read_lockers_.erase(xid); + } + +#endif // DEBUG - read_lockers_.erase(xid); } LOG_DEBUG("frame read unlock success." "this=%p, pin=%d, pageNum=%d, fd=%d, xid=%lx, lbt=%s", this, pin_count_.load(), page_.page_num, file_desc_, xid, lbt()); - lock_.unlock(); -// pthread_rwlock_unlock(&rwlock_); + lock_.unlock_shared(); } void Frame::pin() @@ -226,7 +223,8 @@ void Frame::pin() intptr_t xid = get_default_debug_xid(); int pin_count = ++pin_count_; - LOG_DEBUG("after frame pin. this=%p, write locker=%lx, read locker has xid %d? pin=%d, fd=%d, pageNum=%d, xid=%lx, lbt=%s", + LOG_DEBUG("after frame pin. " + "this=%p, write locker=%lx, read locker has xid %d? pin=%d, fd=%d, pageNum=%d, xid=%lx, lbt=%s", this, write_locker_, read_lockers_.find(xid) != read_lockers_.end(), pin_count, file_desc_, page_.page_num, xid, lbt()); } @@ -273,9 +271,9 @@ void Frame::access() acc_time_ = current_time(); } -std::string to_string(const Frame &frame) +string to_string(const Frame &frame) { - std::stringstream ss; + stringstream ss; ss << "frame id:" << to_string(frame.frame_id()) << ", dirty=" << frame.dirty() << ", pin=" << frame.pin_count() diff --git a/src/observer/storage/buffer/frame.h b/src/observer/storage/buffer/frame.h index 46238ca..6ace6bd 100644 --- a/src/observer/storage/buffer/frame.h +++ b/src/observer/storage/buffer/frame.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -44,6 +44,21 @@ private: class Frame { public: + ~Frame() + { + LOG_INFO("deallocate frame. this=%p, lbt=%s", this, common::lbt()); + } + + /** + * reinit 和 reset 在 MemPoolSimple 中使用 + * 在 MemPoolSimple 分配和释放一个Frame对象时,不会调用构造函数和析构函数, + * 而是调用reinit和reset。 + */ + void reinit() + {} + void reset() + {} + void clear_page() { memset(&page_, 0, sizeof(page_)); @@ -110,15 +125,14 @@ private: int file_desc_ = -1; Page page_; - //读写锁 - pthread_rwlock_t rwlock_ = PTHREAD_RWLOCK_INITIALIZER; /// 在非并发编译时,加锁解锁动作将什么都不做 - common::Mutex lock_; + common::RecursiveSharedMutex lock_; /// 使用一些手段来做测试,提前检测出头疼的死锁问题 /// 如果编译时没有增加调试选项,这些代码什么都不做 common::DebugMutex debug_lock_; intptr_t write_locker_ = 0; - std::set read_lockers_; + int write_recursive_count_ = 0; + std::unordered_map read_lockers_; }; diff --git a/src/observer/storage/buffer/page.h b/src/observer/storage/buffer/page.h index 3d7926e..fb19d06 100644 --- a/src/observer/storage/buffer/page.h +++ b/src/observer/storage/buffer/page.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/storage/clog/clog.cpp b/src/observer/storage/clog/clog.cpp index dc18775..9605404 100644 --- a/src/observer/storage/clog/clog.cpp +++ b/src/observer/storage/clog/clog.cpp @@ -1,6 +1,4 @@ -/* Copyright (c) 2021-2022 Xie Meiyi(xiemeiyi@hust.edu.cn), -Huazhong University of Science and Technology -and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021-2022 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/storage/clog/clog.h b/src/observer/storage/clog/clog.h index ef9a4c2..4ba8794 100644 --- a/src/observer/storage/clog/clog.h +++ b/src/observer/storage/clog/clog.h @@ -1,6 +1,4 @@ -/* Copyright (c) 2021-2022 Xie Meiyi(xiemeiyi@hust.edu.cn), -Huazhong University of Science and Technology -and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021-2022 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/storage/common/condition_filter.cpp b/src/observer/storage/common/condition_filter.cpp index b52eabf..9e2570d 100644 --- a/src/observer/storage/common/condition_filter.cpp +++ b/src/observer/storage/common/condition_filter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Wangyunlai on 2021/5/7. +// Created by Wangyunlai on 2021/5/7. // #include diff --git a/src/observer/storage/common/condition_filter.h b/src/observer/storage/common/condition_filter.h index 2fa6e61..265fede 100644 --- a/src/observer/storage/common/condition_filter.h +++ b/src/observer/storage/common/condition_filter.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,11 +9,10 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Wangyunlai on 2021/5/7. +// Created by Wangyunlai on 2021/5/7. // -#ifndef __OBSERVER_STORAGE_COMMON_CONDITION_FILTER_H_ -#define __OBSERVER_STORAGE_COMMON_CONDITION_FILTER_H_ +#pragma once #include "rc.h" #include "sql/parser/parse.h" @@ -21,14 +20,16 @@ See the Mulan PSL v2 for more details. */ class Record; class Table; -struct ConDesc { +struct ConDesc +{ bool is_attr; // 是否属性,false 表示是值 int attr_length; // 如果是属性,表示属性值长度 int attr_offset; // 如果是属性,表示在记录中的偏移量 Value value; // 如果是值类型,这里记录值的数据 }; -class ConditionFilter { +class ConditionFilter +{ public: virtual ~ConditionFilter(); @@ -40,7 +41,8 @@ public: virtual bool filter(const Record &rec) const = 0; }; -class DefaultConditionFilter : public ConditionFilter { +class DefaultConditionFilter : public ConditionFilter +{ public: DefaultConditionFilter(); virtual ~DefaultConditionFilter(); @@ -78,7 +80,8 @@ private: CompOp comp_op_ = NO_OP; }; -class CompositeConditionFilter : public ConditionFilter { +class CompositeConditionFilter : public ConditionFilter +{ public: CompositeConditionFilter() = default; virtual ~CompositeConditionFilter(); @@ -105,5 +108,3 @@ private: int filter_num_ = 0; bool memory_owner_ = false; // filters_的内存是否由自己来控制 }; - -#endif // __OBSERVER_STORAGE_COMMON_CONDITION_FILTER_H_ diff --git a/src/observer/storage/common/db.cpp b/src/observer/storage/common/db.cpp index 954d980..6cad753 100644 --- a/src/observer/storage/common/db.cpp +++ b/src/observer/storage/common/db.cpp @@ -73,7 +73,7 @@ RC Db::create_table(const char *table_name, int attribute_count, const AttrInfo std::string table_file_path = table_meta_file(path_.c_str(), table_name); Table *table = new Table(); rc = table->create( - table_file_path.c_str(), table_name, path_.c_str(), attribute_count, attributes, get_clog_manager()); + table_file_path.c_str(), table_name, path_.c_str(), attribute_count, attributes); if (rc != RC::SUCCESS) { LOG_ERROR("Failed to create table %s.", table_name); delete table; @@ -106,7 +106,7 @@ RC Db::open_all_tables() RC rc = RC::SUCCESS; for (const std::string &filename : table_meta_files) { Table *table = new Table(); - rc = table->open(filename.c_str(), path_.c_str(), clog_manager_); + rc = table->open(filename.c_str(), path_.c_str()); if (rc != RC::SUCCESS) { delete table; LOG_ERROR("Failed to open table. filename=%s", filename.c_str()); @@ -157,6 +157,7 @@ RC Db::sync() return rc; } +#if 0 RC Db::recover() { RC rc = RC::SUCCESS; @@ -225,6 +226,7 @@ RC Db::recover() return rc; } +#endif CLogManager *Db::get_clog_manager() { diff --git a/src/observer/storage/common/db.h b/src/observer/storage/common/db.h index 037bd3a..39379b3 100644 --- a/src/observer/storage/common/db.h +++ b/src/observer/storage/common/db.h @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Meiyi & Longda & Wangyunlai on 2021/5/12. // -#ifndef __OBSERVER_STORAGE_COMMON_DB_H__ -#define __OBSERVER_STORAGE_COMMON_DB_H__ +#pragma once #include #include @@ -42,7 +41,7 @@ public: RC sync(); - RC recover(); + // RC recover(); CLogManager *get_clog_manager(); @@ -55,5 +54,3 @@ private: std::unordered_map opened_tables_; CLogManager *clog_manager_ = nullptr; }; - -#endif // __OBSERVER_STORAGE_COMMON_DB_H__ \ No newline at end of file diff --git a/src/observer/storage/common/field.cpp b/src/observer/storage/common/field.cpp new file mode 100644 index 0000000..1164201 --- /dev/null +++ b/src/observer/storage/common/field.cpp @@ -0,0 +1,33 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/04/24. +// + +#include "storage/common/field.h" +#include "sql/expr/tuple_cell.h" +#include "storage/record/record.h" +#include "common/log/log.h" + +void Field::set_int(Record &record, int value) +{ + ASSERT(field_->type() == AttrType::INTS, "could not set int value to a non-int field"); + ASSERT(field_->len() == sizeof(value), "invalid field len"); + + char *field_data = record.data() + field_->offset(); + memcpy(field_data, &value, sizeof(value)); +} + +int Field::get_int(const Record &record) +{ + TupleCell cell(field_, const_cast(record.data() + field_->offset()), field_->len()); + return cell.get_int(); +} diff --git a/src/observer/storage/common/field.h b/src/observer/storage/common/field.h index 492e661..07d9a2b 100644 --- a/src/observer/storage/common/field.h +++ b/src/observer/storage/common/field.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,7 +17,8 @@ See the Mulan PSL v2 for more details. */ #include "storage/common/table.h" #include "storage/common/field_meta.h" -class Field { +class Field +{ public: Field() = default; Field(const Table *table, const FieldMeta *field) : table_(table), field_(field) @@ -56,6 +57,9 @@ public: this->field_ = field; } + void set_int(Record &record, int value); + int get_int(const Record &record); + private: const Table *table_ = nullptr; const FieldMeta *field_ = nullptr; diff --git a/src/observer/storage/common/field_meta.cpp b/src/observer/storage/common/field_meta.cpp index 5146e62..255aa90 100644 --- a/src/observer/storage/common/field_meta.cpp +++ b/src/observer/storage/common/field_meta.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -28,6 +28,12 @@ const static Json::StaticString FIELD_VISIBLE("visible"); FieldMeta::FieldMeta() : attr_type_(AttrType::UNDEFINED), attr_offset_(-1), attr_len_(0), visible_(false) {} +FieldMeta::FieldMeta(const char *name, AttrType attr_type, int attr_offset, int attr_len, bool visible) +{ + [[maybe_unused]] RC rc = this->init(name, attr_type, attr_offset, attr_len, visible); + ASSERT(rc == RC::SUCCESS, "failed to init field meta. rc=%s", strrc(rc)); +} + RC FieldMeta::init(const char *name, AttrType attr_type, int attr_offset, int attr_len, bool visible) { if (common::is_blank(name)) { diff --git a/src/observer/storage/common/field_meta.h b/src/observer/storage/common/field_meta.h index ad4acdd..533ff89 100644 --- a/src/observer/storage/common/field_meta.h +++ b/src/observer/storage/common/field_meta.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -24,9 +24,11 @@ class Value; } // namespace Json // Take care of shallow copy -class FieldMeta { +class FieldMeta +{ public: FieldMeta(); + FieldMeta(const char *name, AttrType attr_type, int attr_offset, int attr_len, bool visible); ~FieldMeta() = default; RC init(const char *name, AttrType attr_type, int attr_offset, int attr_len, bool visible); diff --git a/src/observer/storage/common/index_meta.cpp b/src/observer/storage/common/index_meta.cpp index a1860cd..35e41f6 100644 --- a/src/observer/storage/common/index_meta.cpp +++ b/src/observer/storage/common/index_meta.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Wangyunlai.wyl on 2021/5/18. +// Created by Wangyunlai.wyl on 2021/5/18. // #include "storage/common/index_meta.h" diff --git a/src/observer/storage/common/index_meta.h b/src/observer/storage/common/index_meta.h index 06cdff1..6b56be5 100644 --- a/src/observer/storage/common/index_meta.h +++ b/src/observer/storage/common/index_meta.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,11 +9,10 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Wangyunlai on 2021/5/12. +// Created by Wangyunlai on 2021/5/12. // -#ifndef __OBSERVER_STORAGE_COMMON_INDEX_META_H__ -#define __OBSERVER_STORAGE_COMMON_INDEX_META_H__ +#pragma once #include #include "rc.h" @@ -25,7 +24,8 @@ namespace Json { class Value; } // namespace Json -class IndexMeta { +class IndexMeta +{ public: IndexMeta() = default; @@ -45,4 +45,3 @@ protected: std::string name_; // index's name std::string field_; // field's name }; -#endif // __OBSERVER_STORAGE_COMMON_INDEX_META_H__ \ No newline at end of file diff --git a/src/observer/storage/common/meta_util.cpp b/src/observer/storage/common/meta_util.cpp index fccd8ad..4a82bc9 100644 --- a/src/observer/storage/common/meta_util.cpp +++ b/src/observer/storage/common/meta_util.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -8,7 +8,7 @@ EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ -// Created by Meiyi & wangyunlai.wyl on 2021/5/18. +// Created by wangyunlai.wyl on 2021/5/18. // #include "common/defs.h" diff --git a/src/observer/storage/common/meta_util.h b/src/observer/storage/common/meta_util.h index 7acfefe..72067bd 100644 --- a/src/observer/storage/common/meta_util.h +++ b/src/observer/storage/common/meta_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -8,11 +8,10 @@ EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ -// Created by Meiyi & wangyunlai.wyl on 2021/5/18. +// Created by wangyunlai.wyl on 2021/5/18. // -#ifndef __OBSERVER_STORAGE_COMMON_META_UTIL_H_ -#define __OBSERVER_STORAGE_COMMON_META_UTIL_H_ +#pragma once #include @@ -24,5 +23,3 @@ static constexpr const char *TABLE_INDEX_SUFFIX = ".index"; std::string table_meta_file(const char *base_dir, const char *table_name); std::string table_data_file(const char *base_dir, const char *table_name); std::string table_index_file(const char *base_dir, const char *table_name, const char *index_name); - -#endif //__OBSERVER_STORAGE_COMMON_META_UTIL_H_ diff --git a/src/observer/storage/common/table.cpp b/src/observer/storage/common/table.cpp index cf5ed8b..66f1f01 100644 --- a/src/observer/storage/common/table.cpp +++ b/src/observer/storage/common/table.cpp @@ -28,7 +28,6 @@ See the Mulan PSL v2 for more details. */ #include "storage/index/index.h" #include "storage/index/bplus_tree_index.h" #include "storage/trx/trx.h" -#include "storage/clog/clog.h" Table::~Table() { @@ -51,8 +50,11 @@ Table::~Table() LOG_INFO("Table has been closed: %s", name()); } -RC Table::create(const char *path, const char *name, const char *base_dir, int attribute_count, - const AttrInfo attributes[], CLogManager *clog_manager) +RC Table::create(const char *path, + const char *name, + const char *base_dir, + int attribute_count, + const AttrInfo attributes[]) { if (common::is_blank(name)) { @@ -115,12 +117,11 @@ RC Table::create(const char *path, const char *name, const char *base_dir, int a } base_dir_ = base_dir; - clog_manager_ = clog_manager; LOG_INFO("Successfully create table %s:%s", base_dir, name); return rc; } -RC Table::open(const char *meta_file, const char *base_dir, CLogManager *clog_manager) +RC Table::open(const char *meta_file, const char *base_dir) { // 加载元数据文件 std::fstream fs; @@ -153,9 +154,7 @@ RC Table::open(const char *meta_file, const char *base_dir, CLogManager *clog_ma const FieldMeta *field_meta = table_meta_.field(index_meta->field()); if (field_meta == nullptr) { LOG_ERROR("Found invalid index meta info which has a non-exists field. table=%s, index=%s, field=%s", - name(), - index_meta->name(), - index_meta->field()); + name(), index_meta->name(), index_meta->field()); // skip cleanup // do all cleanup action in destructive Table function return RC::GENERIC_ERROR; @@ -166,12 +165,8 @@ RC Table::open(const char *meta_file, const char *base_dir, CLogManager *clog_ma rc = index->open(index_file.c_str(), *index_meta, *field_meta); if (rc != RC::SUCCESS) { delete index; - LOG_ERROR("Failed to open index. table=%s, index=%s, file=%s, rc=%d:%s", - name(), - index_meta->name(), - index_file.c_str(), - rc, - strrc(rc)); + LOG_ERROR("Failed to open index. table=%s, index=%s, file=%s, rc=%s", + name(), index_meta->name(), index_file.c_str(), strrc(rc)); // skip cleanup // do all cleanup action in destructive Table function. return rc; @@ -179,145 +174,57 @@ RC Table::open(const char *meta_file, const char *base_dir, CLogManager *clog_ma indexes_.push_back(index); } - if (clog_manager_ == nullptr) { - clog_manager_ = clog_manager; - } return rc; } -RC Table::commit_insert(Trx *trx, const RID &rid) -{ - Record record; - RC rc = record_handler_->get_record(&rid, &record); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to get record %s: %s", this->name(), rid.to_string().c_str()); - return rc; - } - - return trx->commit_insert(this, record); -} - -RC Table::rollback_insert(Trx *trx, const RID &rid) -{ - - Record record; - RC rc = record_handler_->get_record(&rid, &record); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to get record %s: %s", this->name(), rid.to_string().c_str()); - return rc; - } - - // remove all indexes - rc = delete_entry_of_indexes(record.data(), rid, false); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to delete indexes of record(rid=%d.%d) while rollback insert, rc=%d:%s", - rid.page_num, - rid.slot_num, - rc, - strrc(rc)); - return rc; - } - - rc = record_handler_->delete_record(&rid); - return rc; -} - -RC Table::insert_record(Trx *trx, Record *record) +RC Table::insert_record(Record &record) { RC rc = RC::SUCCESS; - - if (trx != nullptr) { - trx->init_trx_info(this, *record); - } - rc = record_handler_->insert_record(record->data(), table_meta_.record_size(), &record->rid()); + rc = record_handler_->insert_record(record.data(), table_meta_.record_size(), &record.rid()); if (rc != RC::SUCCESS) { - LOG_ERROR("Insert record failed. table name=%s, rc=%d:%s", table_meta_.name(), rc, strrc(rc)); + LOG_ERROR("Insert record failed. table name=%s, rc=%s", table_meta_.name(), strrc(rc)); return rc; } - if (trx != nullptr) { - rc = trx->insert_record(this, record); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to log operation(insertion) to trx"); - - RC rc2 = record_handler_->delete_record(&record->rid()); - if (rc2 != RC::SUCCESS) { - LOG_ERROR("Failed to rollback record data when insert index entries failed. table name=%s, rc=%d:%s", - name(), - rc2, - strrc(rc2)); - } - return rc; - } - } - - rc = insert_entry_of_indexes(record->data(), record->rid()); - if (rc != RC::SUCCESS) { - RC rc2 = delete_entry_of_indexes(record->data(), record->rid(), true); + rc = insert_entry_of_indexes(record.data(), record.rid()); + if (rc != RC::SUCCESS) { // 可能出现了键值重复 + RC rc2 = delete_entry_of_indexes(record.data(), record.rid(), false/*error_on_not_exists*/); if (rc2 != RC::SUCCESS) { LOG_ERROR("Failed to rollback index data when insert index entries failed. table name=%s, rc=%d:%s", - name(), - rc2, - strrc(rc2)); + name(), rc2, strrc(rc2)); } - rc2 = record_handler_->delete_record(&record->rid()); + rc2 = record_handler_->delete_record(&record.rid()); if (rc2 != RC::SUCCESS) { LOG_PANIC("Failed to rollback record data when insert index entries failed. table name=%s, rc=%d:%s", - name(), - rc2, - strrc(rc2)); - } - return rc; - } - - if (trx != nullptr) { - // append clog record - CLogRecord *clog_record = nullptr; - rc = clog_manager_->clog_gen_record( - CLogType::REDO_INSERT, trx->get_current_id(), clog_record, name(), table_meta_.record_size(), record); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to create a clog record. rc=%d:%s", rc, strrc(rc)); - return rc; - } - rc = clog_manager_->clog_append_record(clog_record); - if (rc != RC::SUCCESS) { - return rc; + name(), rc2, strrc(rc2)); } } return rc; } -RC Table::recover_insert_record(Record *record) +RC Table::visit_record(const RID &rid, bool readonly, std::function visitor) { - RC rc = RC::SUCCESS; - - rc = record_handler_->recover_insert_record(record->data(), table_meta_.record_size(), &record->rid()); - if (rc != RC::SUCCESS) { - LOG_ERROR("Insert record failed. table name=%s, rc=%d:%s", table_meta_.name(), rc, strrc(rc)); - return rc; - } - - return rc; + return record_handler_->visit_record(rid, readonly, visitor); } -RC Table::insert_record(Trx *trx, int value_num, const Value *values) +RC Table::get_record(const RID &rid, Record &record) { - if (value_num <= 0 || nullptr == values) { - LOG_ERROR("Invalid argument. table name: %s, value num=%d, values=%p", name(), value_num, values); - return RC::INVALID_ARGUMENT; - } + const int record_size = table_meta_.record_size(); + char *record_data = (char *)malloc(record_size); + ASSERT(nullptr != record_data, "failed to malloc memory. record data size=%d", record_size); - char *record_data; - RC rc = make_record(value_num, values, record_data); + auto copier = [&record, record_data, record_size](Record &record_src) { + memcpy(record_data, record_src.data(), record_size); + record.set_rid(record_src.rid()); + }; + RC rc = record_handler_->visit_record(rid, true/*readonly*/, copier); if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to create a record. rc=%d:%s", rc, strrc(rc)); + free(record_data); + LOG_WARN("failed to visit record. rid=%s, table=%s, rc=%s", rid.to_string().c_str(), name(), strrc(rc)); return rc; } - Record record; - record.set_data(record_data); - rc = insert_record(trx, &record); - delete[] record_data; + record.set_data_owner(record_data, record_size); return rc; } @@ -331,7 +238,7 @@ const TableMeta &Table::table_meta() const return table_meta_; } -RC Table::make_record(int value_num, const Value *values, char *&record_out) +RC Table::make_record(int value_num, const Value *values, Record &record) { // 检查字段类型是否一致 if (value_num + table_meta_.sys_field_num() != table_meta_.field_num()) { @@ -345,17 +252,14 @@ RC Table::make_record(int value_num, const Value *values, char *&record_out) const Value &value = values[i]; if (field->type() != value.type) { LOG_ERROR("Invalid value type. table name =%s, field name=%s, type=%d, but given=%d", - table_meta_.name(), - field->name(), - field->type(), - value.type); + table_meta_.name(), field->name(), field->type(), value.type); return RC::SCHEMA_FIELD_TYPE_MISMATCH; } } // 复制所有字段的值 int record_size = table_meta_.record_size(); - char *record = new char[record_size]; + char *record_data = (char *)malloc(record_size); for (int i = 0; i < value_num; i++) { const FieldMeta *field = table_meta_.field(i + normal_field_start_index); @@ -367,10 +271,10 @@ RC Table::make_record(int value_num, const Value *values, char *&record_out) copy_len = data_len + 1; } } - memcpy(record + field->offset(), value.data(), copy_len); + memcpy(record_data + field->offset(), value.data(), copy_len); } - record_out = record; + record.set_data_owner(record_data, record_size); return RC::SUCCESS; } @@ -387,7 +291,7 @@ RC Table::init_record_handler(const char *base_dir) record_handler_ = new RecordFileHandler(); rc = record_handler_->init(data_buffer_pool_); if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to init record handler. rc=%d:%s", rc, strrc(rc)); + LOG_ERROR("Failed to init record handler. rc=%s", strrc(rc)); data_buffer_pool_->close_file(); data_buffer_pool_ = nullptr; delete record_handler_; @@ -398,180 +302,27 @@ RC Table::init_record_handler(const char *base_dir) return rc; } -RC Table::get_record_scanner(RecordFileScanner &scanner) -{ - RC rc = scanner.open_scan(*data_buffer_pool_, nullptr); - if (rc != RC::SUCCESS) { - LOG_ERROR("failed to open scanner. rc=%d:%s", rc, strrc(rc)); - } - return rc; -} - -/** - * 为了不把Record暴露出去,封装一下 - */ -class RecordReaderScanAdapter { -public: - explicit RecordReaderScanAdapter(void (*record_reader)(const char *data, void *context), void *context) - : record_reader_(record_reader), context_(context) - {} - - void consume(const Record *record) - { - record_reader_(record->data(), context_); - } - -private: - void (*record_reader_)(const char *, void *); - void *context_; -}; - -static RC scan_record_reader_adapter(Record *record, void *context) +RC Table::get_record_scanner(RecordFileScanner &scanner, Trx *trx, bool readonly) { - RecordReaderScanAdapter &adapter = *(RecordReaderScanAdapter *)context; - adapter.consume(record); - return RC::SUCCESS; -} - -RC Table::scan_record( - Trx *trx, ConditionFilter *filter, int limit, void *context, void (*record_reader)(const char *data, void *context)) -{ - RecordReaderScanAdapter adapter(record_reader, context); - return scan_record(trx, filter, limit, (void *)&adapter, scan_record_reader_adapter); -} - -RC Table::scan_record( - Trx *trx, ConditionFilter *filter, int limit, void *context, RC (*record_reader)(Record *record, void *context)) -{ - if (nullptr == record_reader) { - return RC::INVALID_ARGUMENT; - } - - if (0 == limit) { - return RC::SUCCESS; - } - - if (limit < 0) { - limit = INT_MAX; - } - - IndexScanner *index_scanner = find_index_for_scan(filter); - if (index_scanner != nullptr) { - return scan_record_by_index(trx, index_scanner, filter, limit, context, record_reader); - } - - RC rc = RC::SUCCESS; - RecordFileScanner scanner; - rc = scanner.open_scan(*data_buffer_pool_, filter); + RC rc = scanner.open_scan(this, *data_buffer_pool_, trx, readonly, nullptr); if (rc != RC::SUCCESS) { - LOG_ERROR("failed to open scanner. rc=%d:%s", rc, strrc(rc)); - return rc; - } - - int record_count = 0; - Record record; - while (scanner.has_next()) { - rc = scanner.next(record); - if (rc != RC::SUCCESS) { - LOG_WARN("failed to fetch next record. rc=%d:%s", rc, strrc(rc)); - return rc; - } - if (trx == nullptr || trx->is_visible(this, &record)) { - rc = record_reader(&record, context); - if (rc != RC::SUCCESS) { - break; - } - record_count++; - } - } - - scanner.close_scan(); - return rc; -} - -RC Table::scan_record_by_index(Trx *trx, IndexScanner *scanner, ConditionFilter *filter, int limit, void *context, - RC (*record_reader)(Record *, void *)) -{ - RC rc = RC::SUCCESS; - RID rid; - Record record; - int record_count = 0; - while (record_count < limit) { - rc = scanner->next_entry(&rid); - if (rc != RC::SUCCESS) { - if (RC::RECORD_EOF == rc) { - rc = RC::SUCCESS; - break; - } - LOG_ERROR("Failed to scan table by index. rc=%d:%s", rc, strrc(rc)); - break; - } - - rc = record_handler_->get_record(&rid, &record); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to fetch record of rid=%d:%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc)); - break; - } - - if ((trx == nullptr || trx->is_visible(this, &record)) && (filter == nullptr || filter->filter(record))) { - rc = record_reader(&record, context); - if (rc != RC::SUCCESS) { - LOG_TRACE("Record reader break the table scanning. rc=%d:%s", rc, strrc(rc)); - break; - } - } - - record_count++; + LOG_ERROR("failed to open scanner. rc=%s", strrc(rc)); } - - scanner->destroy(); return rc; } -class IndexInserter { -public: - explicit IndexInserter(Index *index) : index_(index) - {} - - RC insert_index(const Record *record) - { - return index_->insert_entry(record->data(), &record->rid()); - } - -private: - Index *index_; -}; - -static RC insert_index_record_reader_adapter(Record *record, void *context) -{ - IndexInserter &inserter = *(IndexInserter *)context; - return inserter.insert_index(record); -} - -RC Table::create_index(Trx *trx, const char *index_name, const char *attribute_name) +RC Table::create_index(Trx *trx, const FieldMeta *field_meta, const char *index_name) { - if (common::is_blank(index_name) || common::is_blank(attribute_name)) { + if (common::is_blank(index_name) || nullptr == field_meta) { LOG_INFO("Invalid input arguments, table name is %s, index_name is blank or attribute_name is blank", name()); return RC::INVALID_ARGUMENT; } - if (table_meta_.index(index_name) != nullptr || table_meta_.find_index_by_field((attribute_name))) { - LOG_INFO("Invalid input arguments, table name is %s, index %s exist or attribute %s exist index", - name(), - index_name, - attribute_name); - return RC::SCHEMA_INDEX_EXIST; - } - - const FieldMeta *field_meta = table_meta_.field(attribute_name); - if (!field_meta) { - LOG_INFO("Invalid input arguments, there is no field of %s in table:%s.", attribute_name, name()); - return RC::SCHEMA_FIELD_MISSING; - } IndexMeta new_index_meta; RC rc = new_index_meta.init(index_name, *field_meta); if (rc != RC::SUCCESS) { - LOG_INFO("Failed to init IndexMeta in table:%s, index_name:%s, field_name:%s", name(), index_name, attribute_name); + LOG_INFO("Failed to init IndexMeta in table:%s, index_name:%s, field_name:%s", + name(), index_name, field_meta->name()); return rc; } @@ -586,22 +337,44 @@ RC Table::create_index(Trx *trx, const char *index_name, const char *attribute_n } // 遍历当前的所有数据,插入这个索引 - IndexInserter index_inserter(index); - rc = scan_record(trx, nullptr, -1, &index_inserter, insert_index_record_reader_adapter); + RecordFileScanner scanner; + rc = get_record_scanner(scanner, trx, true/*readonly*/); if (rc != RC::SUCCESS) { - // rollback - delete index; - LOG_ERROR("Failed to insert index to all records. table=%s, rc=%d:%s", name(), rc, strrc(rc)); + LOG_WARN("failed to create scanner while creating index. table=%s, index=%s, rc=%s", + name(), index_name, strrc(rc)); return rc; } + + Record record; + while (scanner.has_next()) { + rc = scanner.next(record); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to scan records while creating index. table=%s, index=%s, rc=%s", + name(), index_name, strrc(rc)); + return rc; + } + rc = index->insert_entry(record.data(), &record.rid()); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to insert record into index while creating index. table=%s, index=%s, rc=%s", + name(), index_name, strrc(rc)); + return rc; + } + } + scanner.close_scan(); + LOG_INFO("inserted all records into new index. table=%s, index=%s", name(), index_name); + indexes_.push_back(index); + /// 接下来将这个索引放到表的元数据中 TableMeta new_table_meta(table_meta_); rc = new_table_meta.add_index(new_index_meta); if (rc != RC::SUCCESS) { LOG_ERROR("Failed to add index (%s) on table (%s). error=%d:%s", index_name, name(), rc, strrc(rc)); return rc; } + + /// 内存中有一份元数据,磁盘文件也有一份元数据。修改磁盘文件时,先创建一个临时文件,写入完成后再rename为正式文件 + /// 这样可以防止文件内容不完整 // 创建元数据临时文件 std::string tmp_file = table_meta_file(base_dir_.c_str(), name()) + ".tmp"; std::fstream fs; @@ -622,154 +395,29 @@ RC Table::create_index(Trx *trx, const char *index_name, const char *attribute_n if (ret != 0) { LOG_ERROR("Failed to rename tmp meta file (%s) to normal meta file (%s) while creating index (%s) on table (%s). " "system error=%d:%s", - tmp_file.c_str(), - meta_file.c_str(), - index_name, - name(), - errno, - strerror(errno)); + tmp_file.c_str(), meta_file.c_str(), index_name, name(), errno, strerror(errno)); return RC::IOERR; } table_meta_.swap(new_table_meta); LOG_INFO("Successfully added a new index (%s) on the table (%s)", index_name, name()); - - return rc; -} - -RC Table::update_record(Trx *trx, const char *attribute_name, const Value *value, int condition_num, - const Condition conditions[], int *updated_count) -{ - return RC::GENERIC_ERROR; -} - -class RecordDeleter { -public: - RecordDeleter(Table &table, Trx *trx) : table_(table), trx_(trx) - {} - - RC delete_record(Record *record) - { - RC rc = RC::SUCCESS; - rc = table_.delete_record(trx_, record); - if (rc == RC::SUCCESS) { - deleted_count_++; - } - return rc; - } - - int deleted_count() const - { - return deleted_count_; - } - -private: - Table &table_; - Trx *trx_; - int deleted_count_ = 0; -}; - -static RC record_reader_delete_adapter(Record *record, void *context) -{ - RecordDeleter &record_deleter = *(RecordDeleter *)context; - return record_deleter.delete_record(record); -} - -RC Table::delete_record(Trx *trx, ConditionFilter *filter, int *deleted_count) -{ - RecordDeleter deleter(*this, trx); - RC rc = scan_record(trx, filter, -1, &deleter, record_reader_delete_adapter); - if (deleted_count != nullptr) { - *deleted_count = deleter.deleted_count(); - } - return rc; -} - -RC Table::delete_record(Trx *trx, Record *record) -{ - RC rc = RC::SUCCESS; - - rc = delete_entry_of_indexes(record->data(), record->rid(), false); // 重复代码 refer to commit_delete - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to delete indexes of record (rid=%d.%d). rc=%d:%s", - record->rid().page_num, - record->rid().slot_num, - rc, - strrc(rc)); - return rc; - } - - rc = record_handler_->delete_record(&record->rid()); - if (rc != RC::SUCCESS) { - LOG_ERROR( - "Failed to delete record (rid=%d.%d). rc=%d:%s", record->rid().page_num, record->rid().slot_num, rc, strrc(rc)); - return rc; - } - - if (trx != nullptr) { - rc = trx->delete_record(this, record); - - CLogRecord *clog_record = nullptr; - rc = clog_manager_->clog_gen_record(CLogType::REDO_DELETE, trx->get_current_id(), clog_record, name(), 0, record); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to create a clog record. rc=%d:%s", rc, strrc(rc)); - return rc; - } - rc = clog_manager_->clog_append_record(clog_record); - if (rc != RC::SUCCESS) { - return rc; - } - } - return rc; } -RC Table::recover_delete_record(Record *record) +RC Table::delete_record(const Record &record) { RC rc = RC::SUCCESS; - rc = record_handler_->delete_record(&record->rid()); - - return rc; -} - -RC Table::commit_delete(Trx *trx, const RID &rid) -{ - RC rc = RC::SUCCESS; - Record record; - rc = record_handler_->get_record(&rid, &record); - if (rc != RC::SUCCESS) { - return rc; - } - rc = delete_entry_of_indexes(record.data(), record.rid(), false); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to delete indexes of record(rid=%d.%d). rc=%d:%s", - rid.page_num, - rid.slot_num, - rc, - strrc(rc)); // panic? - } - - rc = record_handler_->delete_record(&rid); - if (rc != RC::SUCCESS) { - return rc; + for (Index *index : indexes_) { + rc = index->delete_entry(record.data(), &record.rid()); + ASSERT(RC::SUCCESS == rc, + "failed to delete entry from index. table name=%s, index name=%s, rid=%s, rc=%s", + name(), index->index_meta().name(), record.rid().to_string().c_str(), strrc(rc)); } - + rc = record_handler_->delete_record(&record.rid()); return rc; } -RC Table::rollback_delete(Trx *trx, const RID &rid) -{ - RC rc = RC::SUCCESS; - Record record; - rc = record_handler_->get_record(&rid, &record); - if (rc != RC::SUCCESS) { - return rc; - } - - return trx->rollback_delete(this, record); // update record in place -} - RC Table::insert_entry_of_indexes(const char *record, const RID &rid) { RC rc = RC::SUCCESS; @@ -815,103 +463,6 @@ Index *Table::find_index_by_field(const char *field_name) const return nullptr; } -IndexScanner *Table::find_index_for_scan(const DefaultConditionFilter &filter) -{ - const ConDesc *field_cond_desc = nullptr; - const ConDesc *value_cond_desc = nullptr; - if (filter.left().is_attr && !filter.right().is_attr) { - field_cond_desc = &filter.left(); - value_cond_desc = &filter.right(); - } else if (filter.right().is_attr && !filter.left().is_attr) { - field_cond_desc = &filter.right(); - value_cond_desc = &filter.left(); - } - if (field_cond_desc == nullptr || value_cond_desc == nullptr) { - return nullptr; - } - - const FieldMeta *field_meta = table_meta_.find_field_by_offset(field_cond_desc->attr_offset); - if (nullptr == field_meta) { - LOG_PANIC("Cannot find field by offset %d. table=%s", field_cond_desc->attr_offset, name()); - return nullptr; - } - - const IndexMeta *index_meta = table_meta_.find_index_by_field(field_meta->name()); - if (nullptr == index_meta) { - return nullptr; - } - - Index *index = find_index(index_meta->name()); - if (nullptr == index) { - return nullptr; - } - - const char *left_key = nullptr; - const char *right_key = nullptr; - int left_len = 4; - int right_len = 4; - bool left_inclusive = false; - bool right_inclusive = false; - switch (filter.comp_op()) { - case EQUAL_TO: { - left_key = (const char *)value_cond_desc->value.data(); - right_key = (const char *)value_cond_desc->value.data(); - left_inclusive = true; - right_inclusive = true; - } break; - case LESS_EQUAL: { - right_key = (const char *)value_cond_desc->value.data(); - right_inclusive = true; - } break; - case GREAT_EQUAL: { - left_key = (const char *)value_cond_desc->value.data(); - left_inclusive = true; - } break; - case LESS_THAN: { - right_key = (const char *)value_cond_desc->value.data(); - right_inclusive = false; - } break; - case GREAT_THAN: { - left_key = (const char *)value_cond_desc->value.data(); - left_inclusive = false; - } break; - default: { - return nullptr; - } - } - - if (filter.attr_type() == CHARS) { - left_len = left_key != nullptr ? strlen(left_key) : 0; - right_len = right_key != nullptr ? strlen(right_key) : 0; - } - return index->create_scanner(left_key, left_len, left_inclusive, right_key, right_len, right_inclusive); -} - -IndexScanner *Table::find_index_for_scan(const ConditionFilter *filter) -{ - if (nullptr == filter) { - return nullptr; - } - - // remove dynamic_cast - const DefaultConditionFilter *default_condition_filter = dynamic_cast(filter); - if (default_condition_filter != nullptr) { - return find_index_for_scan(*default_condition_filter); - } - - const CompositeConditionFilter *composite_condition_filter = dynamic_cast(filter); - if (composite_condition_filter != nullptr) { - int filter_num = composite_condition_filter->filter_num(); - for (int i = 0; i < filter_num; i++) { - IndexScanner *scanner = find_index_for_scan(&composite_condition_filter->filter(i)); - if (scanner != nullptr) { - return scanner; // 可以找到一个最优的,比如比较符号是= - } - } - } - return nullptr; -} - RC Table::sync() { RC rc = RC::SUCCESS; diff --git a/src/observer/storage/common/table.h b/src/observer/storage/common/table.h index c21ec7e..cecc52b 100644 --- a/src/observer/storage/common/table.h +++ b/src/observer/storage/common/table.h @@ -14,6 +14,7 @@ See the Mulan PSL v2 for more details. */ #pragma once +#include #include "storage/common/table_meta.h" struct RID; @@ -27,10 +28,10 @@ class Index; class IndexScanner; class RecordDeleter; class Trx; -class CLogManager; // TODO remove the routines with condition -class Table { +class Table +{ public: Table() = default; ~Table(); @@ -42,32 +43,26 @@ public: * @param base_dir 表数据存放的路径 * @param attribute_count 字段个数 * @param attributes 字段 - * @param clog_manager clog管理器,用于维护redo log */ - RC create(const char *path, const char *name, const char *base_dir, int attribute_count, const AttrInfo attributes[], - CLogManager *clog_manager); + RC create(const char *path, const char *name, const char *base_dir, int attribute_count, const AttrInfo attributes[]); /** * 打开一个表 * @param meta_file 保存表元数据的文件完整路径 * @param base_dir 表所在的文件夹,表记录数据文件、索引数据文件存放位置 - * @param clog_manager clog管理器 */ - RC open(const char *meta_file, const char *base_dir, CLogManager *clog_manager); + RC open(const char *meta_file, const char *base_dir); - RC insert_record(Trx *trx, int value_num, const Value *values); - RC update_record(Trx *trx, const char *attribute_name, const Value *value, int condition_num, - const Condition conditions[], int *updated_count); - RC delete_record(Trx *trx, ConditionFilter *filter, int *deleted_count); - RC delete_record(Trx *trx, Record *record); - RC recover_delete_record(Record *record); + RC make_record(int value_num, const Value *values, Record &record); + RC insert_record(Record &record); + RC delete_record(const Record &record); + RC visit_record(const RID &rid, bool readonly, std::function visitor); + RC get_record(const RID &rid, Record &record); - RC scan_record(Trx *trx, ConditionFilter *filter, int limit, void *context, - void (*record_reader)(const char *data, void *context)); + // TODO refactor + RC create_index(Trx *trx, const FieldMeta *field_meta, const char *index_name); - RC create_index(Trx *trx, const char *index_name, const char *attribute_name); - - RC get_record_scanner(RecordFileScanner &scanner); + RC get_record_scanner(RecordFileScanner &scanner, Trx *trx, bool readonly); RecordFileHandler *record_handler() const { @@ -75,48 +70,27 @@ public: } public: + int32_t table_id() const { return table_id_; } const char *name() const; const TableMeta &table_meta() const; RC sync(); -public: - RC commit_insert(Trx *trx, const RID &rid); - RC commit_delete(Trx *trx, const RID &rid); - RC rollback_insert(Trx *trx, const RID &rid); - RC rollback_delete(Trx *trx, const RID &rid); - -private: - RC scan_record( - Trx *trx, ConditionFilter *filter, int limit, void *context, RC (*record_reader)(Record *record, void *context)); - RC scan_record_by_index(Trx *trx, IndexScanner *scanner, ConditionFilter *filter, int limit, void *context, - RC (*record_reader)(Record *record, void *context)); - IndexScanner *find_index_for_scan(const ConditionFilter *filter); - IndexScanner *find_index_for_scan(const DefaultConditionFilter &filter); - RC insert_record(Trx *trx, Record *record); - -public: - RC recover_insert_record(Record *record); - private: - friend class RecordUpdater; - friend class RecordDeleter; - RC insert_entry_of_indexes(const char *record, const RID &rid); RC delete_entry_of_indexes(const char *record, const RID &rid, bool error_on_not_exists); private: RC init_record_handler(const char *base_dir); - RC make_record(int value_num, const Value *values, char *&record_out); public: Index *find_index(const char *index_name) const; Index *find_index_by_field(const char *field_name) const; private: + int32_t table_id_ = -1; std::string base_dir_; - CLogManager *clog_manager_; TableMeta table_meta_; DiskBufferPool *data_buffer_pool_ = nullptr; /// 数据文件关联的buffer pool RecordFileHandler *record_handler_ = nullptr; /// 记录操作 diff --git a/src/observer/storage/common/table_meta.cpp b/src/observer/storage/common/table_meta.cpp index 53eeef6..3bfce47 100644 --- a/src/observer/storage/common/table_meta.cpp +++ b/src/observer/storage/common/table_meta.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -20,12 +20,12 @@ See the Mulan PSL v2 for more details. */ #include "common/log/log.h" #include "storage/trx/trx.h" +using namespace std; + static const Json::StaticString FIELD_TABLE_NAME("table_name"); static const Json::StaticString FIELD_FIELDS("fields"); static const Json::StaticString FIELD_INDEXES("indexes"); -std::vector TableMeta::sys_fields_; - TableMeta::TableMeta(const TableMeta &other) : name_(other.name_), fields_(other.fields_), indexes_(other.indexes_), record_size_(other.record_size_) {} @@ -38,19 +38,6 @@ void TableMeta::swap(TableMeta &other) noexcept std::swap(record_size_, other.record_size_); } -RC TableMeta::init_sys_fields() -{ - sys_fields_.reserve(1); - FieldMeta field_meta; - RC rc = field_meta.init(Trx::trx_field_name(), Trx::trx_field_type(), 0, Trx::trx_field_len(), false); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to init trx field. rc = %d:%s", rc, strrc(rc)); - return rc; - } - - sys_fields_.push_back(field_meta); - return rc; -} RC TableMeta::init(const char *name, int field_num, const AttrInfo attributes[]) { if (common::is_blank(name)) { @@ -64,26 +51,28 @@ RC TableMeta::init(const char *name, int field_num, const AttrInfo attributes[]) } RC rc = RC::SUCCESS; - if (sys_fields_.empty()) { - rc = init_sys_fields(); - if (rc != RC::SUCCESS) { - LOG_ERROR("Failed to init_sys_fields, name:%s ", name); - return rc; + + int field_offset = 0; + int trx_field_num = 0; + const vector *trx_fields = TrxKit::instance()->trx_fields(); + if (trx_fields != nullptr) { + fields_.resize(field_num + trx_fields->size()); + + for (size_t i = 0; i < trx_fields->size(); i++) { + const FieldMeta &field_meta = (*trx_fields)[i]; + fields_[i] = FieldMeta(field_meta.name(), field_meta.type(), field_offset, field_meta.len(), false/*visible*/); + field_offset += field_meta.len(); } - } - fields_.resize(field_num + sys_fields_.size()); - for (size_t i = 0; i < sys_fields_.size(); i++) { - fields_[i] = sys_fields_[i]; + trx_field_num = static_cast(trx_fields->size()); + } else { + fields_.resize(field_num); } - // 当前实现下,所有类型都是4字节对齐的,所以不再考虑字节对齐问题 - int field_offset = sys_fields_.back().offset() + sys_fields_.back().len(); - for (int i = 0; i < field_num; i++) { const AttrInfo &attr_info = attributes[i]; - rc = fields_[i + sys_fields_.size()].init( - attr_info.name.c_str(), attr_info.type, field_offset, attr_info.length, true); + rc = fields_[i + trx_field_num].init(attr_info.name.c_str(), + attr_info.type, field_offset, attr_info.length, true/*visible*/); if (rc != RC::SUCCESS) { LOG_ERROR("Failed to init field meta. table name=%s, field name: %s", name, attr_info.name.c_str()); return rc; @@ -115,6 +104,11 @@ const FieldMeta *TableMeta::trx_field() const return &fields_[0]; } +const std::pair TableMeta::trx_fields() const +{ + return std::pair{fields_.data(), sys_field_num()}; +} + const FieldMeta *TableMeta::field(int index) const { return &fields_[index]; @@ -148,7 +142,11 @@ int TableMeta::field_num() const int TableMeta::sys_field_num() const { - return sys_fields_.size(); + const vector *trx_fields = TrxKit::instance()->trx_fields(); + if (nullptr == trx_fields) { + return 0; + } + return static_cast(trx_fields->size()); } const IndexMeta *TableMeta::index(const char *name) const @@ -222,10 +220,6 @@ int TableMeta::serialize(std::ostream &ss) const int TableMeta::deserialize(std::istream &is) { - if (sys_fields_.empty()) { - init_sys_fields(); - } - Json::Value table_value; Json::CharReaderBuilder builder; std::string errors; @@ -264,8 +258,8 @@ int TableMeta::deserialize(std::istream &is) } } - std::sort( - fields.begin(), fields.end(), [](const FieldMeta &f1, const FieldMeta &f2) { return f1.offset() < f2.offset(); }); + auto comparator = [](const FieldMeta &f1, const FieldMeta &f2) { return f1.offset() < f2.offset(); }; + std::sort(fields.begin(), fields.end(), comparator); name_.swap(table_name); fields_.swap(fields); diff --git a/src/observer/storage/common/table_meta.h b/src/observer/storage/common/table_meta.h index 46c2da9..2053b5c 100644 --- a/src/observer/storage/common/table_meta.h +++ b/src/observer/storage/common/table_meta.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Wangyunlai on 2021/5/12. +// Created by Wangyunlai on 2021/5/12. // #pragma once @@ -22,7 +22,8 @@ See the Mulan PSL v2 for more details. */ #include "storage/common/index_meta.h" #include "common/lang/serializable.h" -class TableMeta : public common::Serializable { +class TableMeta : public common::Serializable +{ public: TableMeta() = default; ~TableMeta() = default; @@ -45,6 +46,8 @@ public: { return &fields_; } + auto trx_fields() const -> const std::pair; + int field_num() const; // sys field included int sys_field_num() const; @@ -62,16 +65,10 @@ public: void to_string(std::string &output) const override; void desc(std::ostream &os) const; -protected: - static RC init_sys_fields(); - protected: std::string name_; std::vector fields_; // 包含sys_fields std::vector indexes_; int record_size_ = 0; - - //@@@ TODO why used static variable? - static std::vector sys_fields_; }; diff --git a/src/observer/storage/default/default_handler.cpp b/src/observer/storage/default/default_handler.cpp index b155a80..7d34ef2 100644 --- a/src/observer/storage/default/default_handler.cpp +++ b/src/observer/storage/default/default_handler.cpp @@ -123,9 +123,6 @@ RC DefaultHandler::open_db(const char *dbname) if ((ret = db->init(dbname, dbpath.c_str())) != RC::SUCCESS) { LOG_ERROR("Failed to open db: %s. error=%d", dbname, ret); } - if ((ret = db->recover()) != RC::SUCCESS) { - LOG_ERROR("Failed to recover db: %s. error=%d", dbname, ret); - } opened_dbs_[dbname] = db; return RC::SUCCESS; @@ -156,59 +153,6 @@ RC DefaultHandler::drop_table(const char *dbname, const char *relation_name) return RC::GENERIC_ERROR; } -RC DefaultHandler::create_index( - Trx *trx, const char *dbname, const char *relation_name, const char *index_name, const char *attribute_name) -{ - Table *table = find_table(dbname, relation_name); - if (nullptr == table) { - return RC::SCHEMA_TABLE_NOT_EXIST; - } - return table->create_index(trx, index_name, attribute_name); -} - -RC DefaultHandler::drop_index(Trx *trx, const char *dbname, const char *relation_name, const char *index_name) -{ - - return RC::GENERIC_ERROR; -} - -RC DefaultHandler::insert_record( - Trx *trx, const char *dbname, const char *relation_name, int value_num, const Value *values) -{ - Table *table = find_table(dbname, relation_name); - if (nullptr == table) { - return RC::SCHEMA_TABLE_NOT_EXIST; - } - - return table->insert_record(trx, value_num, values); -} -RC DefaultHandler::delete_record(Trx *trx, const char *dbname, const char *relation_name, int condition_num, - const Condition *conditions, int *deleted_count) -{ - Table *table = find_table(dbname, relation_name); - if (nullptr == table) { - return RC::SCHEMA_TABLE_NOT_EXIST; - } - - CompositeConditionFilter condition_filter; - RC rc = condition_filter.init(*table, conditions, condition_num); - if (rc != RC::SUCCESS) { - return rc; - } - return table->delete_record(trx, &condition_filter, deleted_count); -} - -RC DefaultHandler::update_record(Trx *trx, const char *dbname, const char *relation_name, const char *attribute_name, - const Value *value, int condition_num, const Condition *conditions, int *updated_count) -{ - Table *table = find_table(dbname, relation_name); - if (nullptr == table) { - return RC::SCHEMA_TABLE_NOT_EXIST; - } - - return table->update_record(trx, attribute_name, value, condition_num, conditions, updated_count); -} - Db *DefaultHandler::find_db(const char *dbname) const { std::map::const_iterator iter = opened_dbs_.find(dbname); diff --git a/src/observer/storage/default/default_handler.h b/src/observer/storage/default/default_handler.h index 4378a1d..1ee17e4 100644 --- a/src/observer/storage/default/default_handler.h +++ b/src/observer/storage/default/default_handler.h @@ -11,8 +11,7 @@ See the Mulan PSL v2 for more details. */ // // Created by Meiyi & Longda on 2021/5/11. // -#ifndef __OBSERVER_STORAGE_DEFAULT_ENGINE_H__ -#define __OBSERVER_STORAGE_DEFAULT_ENGINE_H__ +#pragma once #include #include @@ -90,57 +89,6 @@ public: */ RC drop_table(const char *dbname, const char *relation_name); - /** - * 该函数在关系relName的属性attrName上创建名为indexName的索引。 - * 函数首先检查在标记属性上是否已经存在一个索引, - * 如果存在,则返回一个非零的错误码。 - * 否则,创建该索引。 - * 创建索引的工作包括:①创建并打开索引文件; - * ②逐个扫描被索引的记录,并向索引文件中插入索引项;③关闭索引 - * @return - */ - RC create_index( - Trx *trx, const char *dbname, const char *relation_name, const char *index_name, const char *attribute_name); - - /** - * 该函数用来删除名为indexName的索引。 - * 函数首先检查索引是否存在,如果不存在,则返回一个非零的错误码。否则,销毁该索引 - * @param index_name - * @return - */ - RC drop_index(Trx *trx, const char *dbname, const char *relation_name, const char *index_name); - - /** - * 该函数用来在relName表中插入具有指定属性值的新元组, - * nValues为属性值个数,values为对应的属性值数组。 - * 函数根据给定的属性值构建元组,调用记录管理模块的函数插入该元组, - * 然后在该表的每个索引中为该元组创建合适的索引项 - * @return - */ - RC insert_record(Trx *trx, const char *dbname, const char *relation_name, int value_num, const Value *values); - - /** - * 该函数用来删除relName表中所有满足指定条件的元组以及该元组对应的索引项。 - * 如果没有指定条件,则此方法删除relName关系中所有元组。 - * 如果包含多个条件,则这些条件之间为与关系 - * @param relName - * @param nConditions - * @param conditions - * @return - */ - RC delete_record(Trx *trx, const char *dbname, const char *relation_name, int condition_num, - const Condition *conditions, int *deleted_count); - - /** - * 该函数用于更新relName表中所有满足指定条件的元组, - * 在每一个更新的元组中将属性attrName的值设置为一个新的值。 - * 如果没有指定条件,则此方法更新relName中所有元组。 - * 如果要更新一个被索引的属性,应当先删除每个被更新元组对应的索引条目,然后插入一个新的索引条目 - * @return - */ - RC update_record(Trx *trx, const char *dbname, const char *relation_name, const char *attribute_name, - const Value *value, int condition_num, const Condition *conditions, int *updated_count); - public: Db *find_db(const char *dbname) const; Table *find_table(const char *dbname, const char *table_name) const; @@ -156,5 +104,3 @@ private: std::string db_dir_; std::map opened_dbs_; }; // class Handler - -#endif // __OBSERVER_STORAGE_DEFAULT_ENGINE_H__ diff --git a/src/observer/storage/default/default_storage_stage.cpp b/src/observer/storage/default/default_storage_stage.cpp index 0b33b68..2017f1b 100644 --- a/src/observer/storage/default/default_storage_stage.cpp +++ b/src/observer/storage/default/default_storage_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & Longda on 2021/4/13. +// Created by Longda on 2021/4/13. // #include @@ -143,20 +143,16 @@ void DefaultStorageStage::handle_event(StageEvent *event) TimerStat timerStat(*query_metric_); SQLStageEvent *sql_event = static_cast(event); - Command *cmd = sql_event->command().get(); - SessionEvent *session_event = sql_event->session_event(); - Session *session = session_event->session(); + SqlResult *sql_result = session_event->sql_result(); Db *db = session->get_current_db(); const char *dbname = db->name(); - Trx *current_trx = session->current_trx(); RC rc = RC::SUCCESS; - char response[256]; switch (cmd->flag) { case SCF_LOAD_DATA: { /* @@ -165,11 +161,13 @@ void DefaultStorageStage::handle_event(StageEvent *event) */ const char *table_name = cmd->load_data.relation_name.c_str(); const char *file_name = cmd->load_data.file_name.c_str(); - std::string result = load_data(dbname, table_name, file_name); - snprintf(response, sizeof(response), "%s", result.c_str()); + load_data(dbname, table_name, file_name, sql_result); } break; default: + char response[256]; snprintf(response, sizeof(response), "Unsupported sql: %d\n", cmd->flag); + sql_result->set_return_code(RC::UNIMPLENMENT); + sql_result->set_state_string(response); break; } @@ -180,8 +178,6 @@ void DefaultStorageStage::handle_event(StageEvent *event) } } - session_event->set_response(response); - LOG_TRACE("Exit\n"); } @@ -202,8 +198,10 @@ void DefaultStorageStage::callback_event(StageEvent *event, CallbackContext *con * @param errmsg 如果出现错误,通过这个参数返回错误信息 * @return 成功返回RC::SUCCESS */ -RC insert_record_from_file( - Table *table, std::vector &file_values, std::vector &record_values, std::stringstream &errmsg) +RC insert_record_from_file(Table *table, + std::vector &file_values, + std::vector &record_values, + std::stringstream &errmsg) { const int field_num = record_values.size(); @@ -268,29 +266,38 @@ RC insert_record_from_file( } if (RC::SUCCESS == rc) { - rc = table->insert_record(nullptr, field_num, record_values.data()); + Record record; + rc = table->make_record(field_num, record_values.data(), record); if (rc != RC::SUCCESS) { errmsg << "insert failed."; + } else if (RC::SUCCESS != (rc = table->insert_record(record))) { + errmsg << "insert failed."; } } return rc; } -std::string DefaultStorageStage::load_data(const char *db_name, const char *table_name, const char *file_name) +void DefaultStorageStage::load_data(const char *db_name, + const char *table_name, + const char *file_name, + SqlResult *sql_result) { - std::stringstream result_string; Table *table = handler_->find_table(db_name, table_name); if (nullptr == table) { result_string << "No such table " << db_name << "." << table_name << std::endl; - return result_string.str(); + sql_result->set_return_code(RC::SCHEMA_TABLE_NOT_EXIST); + sql_result->set_state_string(result_string.str()); + return; } std::fstream fs; fs.open(file_name, std::ios_base::in | std::ios_base::binary); if (!fs.is_open()) { result_string << "Failed to open file: " << file_name << ". system error=" << strerror(errno) << std::endl; - return result_string.str(); + sql_result->set_return_code(RC::FILE_NOT_EXIST); + sql_result->set_state_string(result_string.str()); + return; } struct timespec begin_time; @@ -332,5 +339,6 @@ std::string DefaultStorageStage::load_data(const char *db_name, const char *tabl result_string << strrc(rc) << ". total " << line_num << " line(s) handled and " << insertion_count << " record(s) loaded, total cost " << cost_nano / 1000000000.0 << " second(s)" << std::endl; } - return result_string.str(); + sql_result->set_return_code(RC::SUCCESS); + sql_result->set_state_string(result_string.str()); } diff --git a/src/observer/storage/default/default_storage_stage.h b/src/observer/storage/default/default_storage_stage.h index e55e1f1..9af92f8 100644 --- a/src/observer/storage/default/default_storage_stage.h +++ b/src/observer/storage/default/default_storage_stage.h @@ -12,13 +12,13 @@ See the Mulan PSL v2 for more details. */ // Created by Meiyi & Longda on 2021/4/13. // -#ifndef __OBSERVER_STORAGE_DEFAULT_STORAGE_STAGE_H__ -#define __OBSERVER_STORAGE_DEFAULT_STORAGE_STAGE_H__ +#pragma once #include "common/seda/stage.h" #include "common/metrics/metrics.h" class DefaultHandler; +class SqlResult; class DefaultStorageStage : public common::Stage { public: @@ -36,7 +36,7 @@ protected: void callback_event(common::StageEvent *event, common::CallbackContext *context) override; private: - std::string load_data(const char *db_name, const char *table_name, const char *file_name); + void load_data(const char *db_name, const char *table_name, const char *file_name, SqlResult *sql_result); protected: common::SimpleTimer *query_metric_ = nullptr; @@ -45,5 +45,3 @@ protected: private: DefaultHandler *handler_; }; - -#endif //__OBSERVER_STORAGE_DEFAULT_STORAGE_STAGE_H__ diff --git a/src/observer/storage/default/disk_buffer_pool.cpp b/src/observer/storage/default/disk_buffer_pool.cpp index f00606d..3ee7372 100644 --- a/src/observer/storage/default/disk_buffer_pool.cpp +++ b/src/observer/storage/default/disk_buffer_pool.cpp @@ -21,8 +21,19 @@ See the Mulan PSL v2 for more details. */ #include "common/io/io.h" using namespace common; +using namespace std; -static const int MEM_POOL_ITEM_NUM = 128; +static const int MEM_POOL_ITEM_NUM = 20; + +//////////////////////////////////////////////////////////////////////////////// + +string BPFileHeader::to_string() const +{ + stringstream ss; + ss << "pageCount:" << page_count + << ", allocatedCount:" << allocated_pages; + return ss.str(); +} //////////////////////////////////////////////////////////////////////////////// @@ -138,7 +149,7 @@ RC BPFrameManager::free(int file_desc, PageNum page_num, Frame *frame) RC BPFrameManager::free_internal(const FrameId &frame_id, Frame *frame) { Frame *frame_source = nullptr; - bool found = frames_.get(frame_id, frame_source); + [[maybe_unused]] bool found = frames_.get(frame_id, frame_source); ASSERT(found && frame == frame_source && frame->pin_count() == 1, "failed to free frame. found=%d, frameId=%s, frame_source=%p, frame=%p, pinCount=%d, lbt=%s", found, to_string(frame_id).c_str(), frame_source, frame, frame->pin_count(), lbt()); @@ -246,7 +257,8 @@ RC DiskBufferPool::open_file(const char *file_name) file_header_ = (BPFileHeader *)hdr_frame_->data(); - LOG_INFO("Successfully open %s. file_desc=%d, hdr_frame=%p", file_name, file_desc_, hdr_frame_); + LOG_INFO("Successfully open %s. file_desc=%d, hdr_frame=%p, file header=%s", + file_name, file_desc_, hdr_frame_, file_header_->to_string().c_str()); return RC::SUCCESS; } @@ -354,6 +366,9 @@ RC DiskBufferPool::allocate_page(Frame **frame) return rc; } + LOG_INFO("allocate new page. file=%s, pageNum=%d, pin=%d", + file_name_.c_str(), page_num, allocated_frame->pin_count()); + file_header_->allocated_pages++; file_header_->page_count++; @@ -492,7 +507,7 @@ RC DiskBufferPool::flush_page_internal(Frame &frame) return RC::IOERR_WRITE; } frame.clear_dirty(); - LOG_DEBUG("Flush block. file desc=%d, pageNum=%d", file_desc_, page.page_num); + LOG_DEBUG("Flush block. file desc=%d, pageNum=%d, pin count=%d", file_desc_, page.page_num, frame.pin_count()); return RC::SUCCESS; } @@ -583,8 +598,8 @@ RC DiskBufferPool::load_page(PageNum page_num, Frame *frame) Page &page = frame->page(); int ret = readn(file_desc_, &page, BP_PAGE_SIZE); if (ret != 0) { - LOG_ERROR("Failed to load page %s:%d, due to failed to read data:%s, ret=%d, page count=%d", - file_name_.c_str(), page_num, strerror(errno), ret, file_header_->allocated_pages); + LOG_ERROR("Failed to load page %s, file_desc:%d, page num:%d, due to failed to read data:%s, ret=%d, page count=%d", + file_name_.c_str(), file_desc_, page_num, strerror(errno), ret, file_header_->allocated_pages); return RC::IOERR_READ; } return RC::SUCCESS; @@ -693,11 +708,12 @@ RC BufferPoolManager::close_file(const char *_file_name) { std::string file_name(_file_name); - std::scoped_lock lock_guard(lock_); + lock_.lock(); auto iter = buffer_pools_.find(file_name); if (iter == buffer_pools_.end()) { - LOG_WARN("file has not opened: %s", _file_name); + LOG_TRACE("file has not opened: %s", _file_name); + lock_.unlock(); return RC::INTERNAL; } @@ -716,6 +732,8 @@ RC BufferPoolManager::close_file(const char *_file_name) DiskBufferPool *bp = iter->second; buffer_pools_.erase(iter); + lock_.unlock(); + delete bp; return RC::SUCCESS; } diff --git a/src/observer/storage/default/disk_buffer_pool.h b/src/observer/storage/default/disk_buffer_pool.h index 23d4a64..aa00d0a 100644 --- a/src/observer/storage/default/disk_buffer_pool.h +++ b/src/observer/storage/default/disk_buffer_pool.h @@ -56,6 +56,8 @@ struct BPFileHeader * 能够分配的最大的页面个数,即bitmap的字节数 乘以8 */ static const int MAX_PAGE_NUM = (BP_PAGE_DATA_SIZE - sizeof(page_count) - sizeof(allocated_pages)) * 8; + + std::string to_string() const; }; class BPFrameManager diff --git a/src/observer/storage/index/bplus_tree.h b/src/observer/storage/index/bplus_tree.h index 0c4f76f..69c368c 100644 --- a/src/observer/storage/index/bplus_tree.h +++ b/src/observer/storage/index/bplus_tree.h @@ -67,6 +67,7 @@ public: } default: { ASSERT(false, "unknown attr type. %d", attr_type_); + return 0; } } } @@ -142,6 +143,7 @@ public: ASSERT(false, "unknown attr type. %d", attr_type_); } } + return std::string(); } private: diff --git a/src/observer/storage/index/bplus_tree_index.cpp b/src/observer/storage/index/bplus_tree_index.cpp index dbddff5..4d13e38 100644 --- a/src/observer/storage/index/bplus_tree_index.cpp +++ b/src/observer/storage/index/bplus_tree_index.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & wangyunlai.wyl on 2021/5/19. +// Created by wangyunlai.wyl on 2021/5/19. // #include "storage/index/bplus_tree_index.h" diff --git a/src/observer/storage/index/bplus_tree_index.h b/src/observer/storage/index/bplus_tree_index.h index 4d2e544..5d4b1ae 100644 --- a/src/observer/storage/index/bplus_tree_index.h +++ b/src/observer/storage/index/bplus_tree_index.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,11 +9,10 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & wangyunlai.wyl on 2021/5/19. +// Created by wangyunlai.wyl on 2021/5/19. // -#ifndef __OBSERVER_STORAGE_COMMON_BPLUS_TREE_INDEX_H_ -#define __OBSERVER_STORAGE_COMMON_BPLUS_TREE_INDEX_H_ +#pragma once #include "storage/index/index.h" #include "storage/index/bplus_tree.h" @@ -57,5 +56,3 @@ public: private: BplusTreeScanner tree_scanner_; }; - -#endif //__OBSERVER_STORAGE_COMMON_BPLUS_TREE_INDEX_H_ diff --git a/src/observer/storage/index/index.cpp b/src/observer/storage/index/index.cpp index 105c037..6fa5153 100644 --- a/src/observer/storage/index/index.cpp +++ b/src/observer/storage/index/index.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Meiyi & wangyunlai.wyl on 2021/5/19. +// Created by wangyunlai.wyl on 2021/5/19. // #include "storage/index/index.h" diff --git a/src/observer/storage/index/index.h b/src/observer/storage/index/index.h index b8feb6c..f61b8ef 100644 --- a/src/observer/storage/index/index.h +++ b/src/observer/storage/index/index.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Meiyi & Wangyunlai on 2021/5/11. // -#ifndef __OBSERVER_STORAGE_COMMON_INDEX_H_ -#define __OBSERVER_STORAGE_COMMON_INDEX_H_ +#pragma once #include #include @@ -71,5 +70,3 @@ public: virtual RC next_entry(RID *rid) = 0; virtual RC destroy() = 0; }; - -#endif // __OBSERVER_STORAGE_COMMON_INDEX_H_ diff --git a/src/observer/storage/mem/mem_storage_stage.cpp b/src/observer/storage/mem/mem_storage_stage.cpp index e20000e..57bd9fd 100644 --- a/src/observer/storage/mem/mem_storage_stage.cpp +++ b/src/observer/storage/mem/mem_storage_stage.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/storage/mem/mem_storage_stage.h b/src/observer/storage/mem/mem_storage_stage.h index 468d2ac..3a7278d 100644 --- a/src/observer/storage/mem/mem_storage_stage.h +++ b/src/observer/storage/mem/mem_storage_stage.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021/4/13. // -#ifndef __OBSERVER_STORAGE_MEM_STORAGE_STAGE_H__ -#define __OBSERVER_STORAGE_MEM_STORAGE_STAGE_H__ +#pragma once #include "common/seda/stage.h" #include "common/metrics/metrics.h" @@ -39,5 +38,3 @@ protected: private: }; - -#endif //__OBSERVER_STORAGE_MEM_STORAGE_STAGE_H__ diff --git a/src/observer/storage/persist/persist.cpp b/src/observer/storage/persist/persist.cpp index 30e9638..18450ff 100644 --- a/src/observer/storage/persist/persist.cpp +++ b/src/observer/storage/persist/persist.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/storage/persist/persist.h b/src/observer/storage/persist/persist.h index 6b65b6c..916eed1 100644 --- a/src/observer/storage/persist/persist.h +++ b/src/observer/storage/persist/persist.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -11,8 +11,7 @@ See the Mulan PSL v2 for more details. */ // // Created by qiling on 2021/4/13. // -#ifndef __OBSERVER_STORAGE_PERSIST_HANDLER_H_ -#define __OBSERVER_STORAGE_PERSIST_HANDLER_H_ +#pragma once #include #include @@ -24,7 +23,8 @@ See the Mulan PSL v2 for more details. */ #include "rc.h" -class PersistHandler { +class PersistHandler +{ public: PersistHandler(); ~PersistHandler(); @@ -63,5 +63,3 @@ private: std::string file_name_; int file_desc_ = -1; }; - -#endif //__OBSERVER_STORAGE_PERSIST_HANDLER_H_ diff --git a/src/observer/storage/record/record.h b/src/observer/storage/record/record.h index 1a0be72..98a3269 100644 --- a/src/observer/storage/record/record.h +++ b/src/observer/storage/record/record.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -21,12 +21,14 @@ See the Mulan PSL v2 for more details. */ #include "rc.h" #include "defs.h" +#include "common/log/log.h" #include "storage/common/index_meta.h" #include "storage/common/field_meta.h" class Field; -struct RID { +struct RID +{ PageNum page_num; // record's page number SlotNum slot_num; // record's slot number // bool valid; // true means a valid record @@ -81,15 +83,59 @@ struct RID { } }; -class Record { +class Record +{ public: Record() = default; - ~Record() = default; + ~Record() + { + if (owner_ && data_ != nullptr) { + free(data_); + data_ = nullptr; + } + } - void set_data(char *data) + Record(const Record &other) { + rid_ = other.rid_; + data_ = other.data_; + len_ = other.len_; + owner_ = other.owner_; + + if (other.owner_) { + char *tmp = (char *)malloc(other.len_); + ASSERT(nullptr != tmp, "failed to allocate memory. size=%d", other.len_); + memcpy(tmp, other.data_, other.len_); + data_ = tmp; + } + } + + Record &operator =(const Record &other) + { + if (this == &other) { + return *this; + } + + this->~Record(); + new (this) Record(other); + return *this; + } + + void set_data(char *data, int len = 0) + { + this->data_ = data; + this->len_ = len; + } + void set_data_owner(char *data, int len) + { + ASSERT(len != 0, "the len of data should not be 0"); + this->~Record(); + this->data_ = data; + this->len_ = len; + this->owner_ = true; } + char *data() { return this->data_; @@ -115,12 +161,12 @@ public: const RID &rid() const { return rid_; - }; + } private: RID rid_; - // the data buffer - // record will not release the memory char *data_ = nullptr; + int len_ = 0; + bool owner_ = false; }; diff --git a/src/observer/storage/record/record_manager.cpp b/src/observer/storage/record/record_manager.cpp index 09e3d98..9ade2b7 100644 --- a/src/observer/storage/record/record_manager.cpp +++ b/src/observer/storage/record/record_manager.cpp @@ -16,6 +16,7 @@ See the Mulan PSL v2 for more details. */ #include "common/log/log.h" #include "common/lang/bitmap.h" #include "storage/common/condition_filter.h" +#include "storage/trx/trx.h" using namespace common; @@ -52,12 +53,12 @@ RecordPageIterator::RecordPageIterator() RecordPageIterator::~RecordPageIterator() {} -void RecordPageIterator::init(RecordPageHandler &record_page_handler) +void RecordPageIterator::init(RecordPageHandler &record_page_handler, SlotNum start_slot_num /*=0*/) { record_page_handler_ = &record_page_handler; page_num_ = record_page_handler.get_page_num(); bitmap_.init(record_page_handler.bitmap_, record_page_handler.page_header_->record_capacity); - next_slot_num_ = bitmap_.next_setted_bit(0); + next_slot_num_ = bitmap_.next_setted_bit(start_slot_num); } bool RecordPageIterator::has_next() @@ -83,7 +84,7 @@ RecordPageHandler::~RecordPageHandler() cleanup(); } -RC RecordPageHandler::init(DiskBufferPool &buffer_pool, PageNum page_num) +RC RecordPageHandler::init(DiskBufferPool &buffer_pool, PageNum page_num, bool readonly) { if (disk_buffer_pool_ != nullptr) { LOG_WARN("Disk buffer pool has been opened for page_num %d.", page_num); @@ -96,6 +97,12 @@ RC RecordPageHandler::init(DiskBufferPool &buffer_pool, PageNum page_num) return ret; } + if (readonly) { + frame_->read_latch(); + } else { + frame_->write_latch(); + } + readonly_ = readonly; char *data = frame_->data(); disk_buffer_pool_ = &buffer_pool; @@ -134,7 +141,7 @@ RC RecordPageHandler::recover_init(DiskBufferPool &buffer_pool, PageNum page_num RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, PageNum page_num, int record_size) { - RC ret = init(buffer_pool, page_num); + RC ret = init(buffer_pool, page_num, false/*readonly*/); if (ret != RC::SUCCESS) { LOG_ERROR("Failed to init empty page page_num:record_size %d:%d.", page_num, record_size); return ret; @@ -162,6 +169,11 @@ RC RecordPageHandler::init_empty_page(DiskBufferPool &buffer_pool, PageNum page_ RC RecordPageHandler::cleanup() { if (disk_buffer_pool_ != nullptr) { + if (readonly_) { + frame_->read_unlatch(); + } else { + frame_->write_unlatch(); + } disk_buffer_pool_->unpin_page(frame_); disk_buffer_pool_ = nullptr; } @@ -171,6 +183,8 @@ RC RecordPageHandler::cleanup() RC RecordPageHandler::insert_record(const char *data, RID *rid) { + ASSERT(readonly_ == false, "cannot insert record into page while the page is readonly"); + if (page_header_->record_num == page_header_->record_capacity) { LOG_WARN("Page is full, page_num %d:%d.", frame_->page_num()); return RC::RECORD_NOMEM; @@ -224,6 +238,8 @@ RC RecordPageHandler::recover_insert_record(const char *data, RID *rid) RC RecordPageHandler::delete_record(const RID *rid) { + ASSERT(readonly_ == false, "cannot delete record from page while the page is readonly"); + if (rid->slot_num >= page_header_->record_capacity) { LOG_ERROR("Invalid slot_num %d, exceed page's record capacity, page_num %d.", rid->slot_num, frame_->page_num()); return RC::INVALID_ARGUMENT; @@ -238,11 +254,10 @@ RC RecordPageHandler::delete_record(const RID *rid) if (page_header_->record_num == 0) { // PageNum page_num = get_page_num(); cleanup(); - // disk_buffer_pool->dispose_page(page_num); // TODO 确认是否可以不删除页面 } return RC::SUCCESS; } else { - LOG_ERROR("Invalid slot_num %d, slot is empty, page_num %d.", rid->slot_num, frame_->page_num()); + LOG_DEBUG("Invalid slot_num %d, slot is empty, page_num %d.", rid->slot_num, frame_->page_num()); return RC::RECORD_RECORD_NOT_EXIST; } } @@ -280,6 +295,11 @@ bool RecordPageHandler::is_full() const //////////////////////////////////////////////////////////////////////////////// +RecordFileHandler::~RecordFileHandler() +{ + this->close(); +} + RC RecordFileHandler::init(DiskBufferPool *buffer_pool) { if (disk_buffer_pool_ != nullptr) { @@ -298,6 +318,7 @@ RC RecordFileHandler::init(DiskBufferPool *buffer_pool) void RecordFileHandler::close() { if (disk_buffer_pool_ != nullptr) { + free_pages_.clear(); disk_buffer_pool_ = nullptr; } } @@ -306,6 +327,7 @@ RC RecordFileHandler::init_free_pages() { // 遍历当前文件上所有页面,找到没有满的页面 // 这个效率很低,会降低启动速度 + // NOTE: 由于是初始化时的动作,所以不需要加锁控制并发 RC rc = RC::SUCCESS; BufferPoolIterator bp_iterator; @@ -314,7 +336,7 @@ RC RecordFileHandler::init_free_pages() PageNum current_page_num = 0; while (bp_iterator.has_next()) { current_page_num = bp_iterator.next(); - rc = record_page_handler.init(*disk_buffer_pool_, current_page_num); + rc = record_page_handler.init(*disk_buffer_pool_, current_page_num, true/*readonly*/); if (rc != RC::SUCCESS) { LOG_WARN("failed to init record page handler. page num=%d, rc=%d:%s", current_page_num, rc, strrc(rc)); return rc; @@ -325,6 +347,7 @@ RC RecordFileHandler::init_free_pages() } record_page_handler.cleanup(); } + LOG_INFO("record file handler init free pages done. free page num=%d, rc=%s", free_pages_.size(), strrc(rc)); return rc; } @@ -336,10 +359,12 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) RecordPageHandler record_page_handler; bool page_found = false; PageNum current_page_num = 0; + lock_.lock(); while (!free_pages_.empty()) { current_page_num = *free_pages_.begin(); - ret = record_page_handler.init(*disk_buffer_pool_, current_page_num); + ret = record_page_handler.init(*disk_buffer_pool_, current_page_num, false/*readonly*/); if (ret != RC::SUCCESS) { + lock_.unlock(); LOG_WARN("failed to init record page handler. page num=%d, rc=%d:%s", current_page_num, ret, strrc(ret)); return ret; } @@ -351,6 +376,7 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) record_page_handler.cleanup(); free_pages_.erase(free_pages_.begin()); } + lock_.unlock(); // 如果找到了一个有效的页面,那么此时已经拿到了页面的写锁 // 找不到就分配一个新的页面 if (!page_found) { @@ -363,15 +389,21 @@ RC RecordFileHandler::insert_record(const char *data, int record_size, RID *rid) current_page_num = frame->page_num(); ret = record_page_handler.init_empty_page(*disk_buffer_pool_, current_page_num, record_size); if (ret != RC::SUCCESS) { + frame->unpin(); LOG_ERROR("Failed to init empty page. ret:%d", ret); // this is for allocate_page - disk_buffer_pool_->unpin_page(frame); return ret; } - // this is for allocate_page - disk_buffer_pool_->unpin_page(frame); + frame->unpin(); // frame 在allocate_page的时候,是有一个pin的,在init_empty_page时又会增加一个,所以这里手动释放一个 + + // 这里的加锁顺序看起来与上面是相反的,但是不会出现死锁 + // 上面的逻辑是先加lock锁,然后加页面写锁,这里是先加上 + // 了页面写锁,然后加lock的锁,但是不会引起死锁。 + // 为什么? + lock_.lock(); free_pages_.insert(current_page_num); + lock_.unlock(); } // 找到空闲位置 @@ -396,28 +428,29 @@ RC RecordFileHandler::delete_record(const RID *rid) { RC rc = RC::SUCCESS; RecordPageHandler page_handler; - if ((rc != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) { + if ((rc = page_handler.init(*disk_buffer_pool_, rid->page_num, false/*readonly*/)) != RC::SUCCESS) { LOG_ERROR("Failed to init record page handler.page number=%d. rc=%s", rid->page_num, strrc(rc)); return rc; } rc = page_handler.delete_record(rid); + page_handler.cleanup(); // 📢 这里注意要清理掉资源,否则会与insert_record中的加锁顺序冲突而可能出现死锁 if (rc == RC::SUCCESS) { + lock_.lock(); free_pages_.insert(rid->page_num); + lock_.unlock(); } return rc; } -RC RecordFileHandler::get_record(const RID *rid, Record *rec) +RC RecordFileHandler::get_record(RecordPageHandler &page_handler, const RID *rid, bool readonly, Record *rec) { - // lock? RC ret = RC::SUCCESS; if (nullptr == rid || nullptr == rec) { - LOG_ERROR("Invalid rid %p or rec %p, one of them is null. ", rid, rec); + LOG_ERROR("Invalid rid %p or rec %p, one of them is null.", rid, rec); return RC::INVALID_ARGUMENT; } - RecordPageHandler page_handler; - if ((ret != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) { + if ((ret != page_handler.init(*disk_buffer_pool_, rid->page_num, readonly)) != RC::SUCCESS) { LOG_ERROR("Failed to init record page handler.page number=%d", rid->page_num); return ret; } @@ -425,13 +458,46 @@ RC RecordFileHandler::get_record(const RID *rid, Record *rec) return page_handler.get_record(rid, rec); } +RC RecordFileHandler::visit_record(const RID &rid, bool readonly, std::function visitor) +{ + RC rc = RC::SUCCESS; + + RecordPageHandler page_handler; + if ((rc != page_handler.init(*disk_buffer_pool_, rid.page_num, readonly)) != RC::SUCCESS) { + LOG_ERROR("Failed to init record page handler.page number=%d", rid.page_num); + return rc; + } + + Record record; + rc = page_handler.get_record(&rid, &record); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to get record from record page handle. rid=%s, rc=%s", rid.to_string().c_str(), strrc(rc)); + return rc; + } + + visitor(record); + return rc; +} + //////////////////////////////////////////////////////////////////////////////// -RC RecordFileScanner::open_scan(DiskBufferPool &buffer_pool, ConditionFilter *condition_filter) +RecordFileScanner::~RecordFileScanner() +{ + close_scan(); +} + +RC RecordFileScanner::open_scan(Table *table, + DiskBufferPool &buffer_pool, + Trx *trx, + bool readonly, + ConditionFilter *condition_filter) { close_scan(); + table_ = table; disk_buffer_pool_ = &buffer_pool; + trx_ = trx; + readonly_ = readonly; RC rc = bp_iterator_.init(buffer_pool); if (rc != RC::SUCCESS) { @@ -460,7 +526,7 @@ RC RecordFileScanner::fetch_next_record() while (bp_iterator_.has_next()) { PageNum page_num = bp_iterator_.next(); record_page_handler_.cleanup(); - rc = record_page_handler_.init(*disk_buffer_pool_, page_num); + rc = record_page_handler_.init(*disk_buffer_pool_, page_num, readonly_); if (rc != RC::SUCCESS) { LOG_WARN("failed to init record page handler. rc=%d:%s", rc, strrc(rc)); return rc; @@ -485,9 +551,19 @@ RC RecordFileScanner::fetch_next_record_in_page() return rc; } - if (condition_filter_ == nullptr || condition_filter_->filter(next_record_)) { + if (condition_filter_ != nullptr && !condition_filter_->filter(next_record_)) { + continue; + } + + if (trx_ == nullptr) { return rc; } + + rc = trx_->visit_record(table_, next_record_, readonly_); + if (rc == RC::RECORD_INVISIBLE) { + continue; + } + return rc; } next_record_.rid().slot_num = -1; diff --git a/src/observer/storage/record/record_manager.h b/src/observer/storage/record/record_manager.h index 4720684..9e2cbb5 100644 --- a/src/observer/storage/record/record_manager.h +++ b/src/observer/storage/record/record_manager.h @@ -16,11 +16,14 @@ See the Mulan PSL v2 for more details. */ #include #include #include "storage/default/disk_buffer_pool.h" +#include "storage/trx/latch_memo.h" #include "storage/record/record.h" #include "common/lang/bitmap.h" class ConditionFilter; class RecordPageHandler; +class Trx; +class Table; /** * 数据文件,按照页面来组织,每一页都存放一些记录/数据行 @@ -46,7 +49,7 @@ public: RecordPageIterator(); ~RecordPageIterator(); - void init(RecordPageHandler &record_page_handler); + void init(RecordPageHandler &record_page_handler, SlotNum start_slot_num = 0); bool has_next(); RC next(Record &record); @@ -71,7 +74,7 @@ class RecordPageHandler public: RecordPageHandler() = default; ~RecordPageHandler(); - RC init(DiskBufferPool &buffer_pool, PageNum page_num); + RC init(DiskBufferPool &buffer_pool, PageNum page_num, bool readonly); RC recover_init(DiskBufferPool &buffer_pool, PageNum page_num); RC init_empty_page(DiskBufferPool &buffer_pool, PageNum page_num, int record_size); RC cleanup(); @@ -95,6 +98,7 @@ protected: protected: DiskBufferPool *disk_buffer_pool_ = nullptr; + bool readonly_ = false; Frame *frame_ = nullptr; PageHeader *page_header_ = nullptr; char *bitmap_ = nullptr; @@ -107,6 +111,8 @@ class RecordFileHandler { public: RecordFileHandler() = default; + ~RecordFileHandler(); + RC init(DiskBufferPool *buffer_pool); void close(); @@ -122,7 +128,7 @@ public: RC delete_record(const RID *rid); /** - * 插入一个新的记录到指定文件中,pData为指向新纪录内容的指针,返回该记录的标识符rid + * 插入一个新的记录到指定文件中,data为指向新纪录内容的指针,返回该记录的标识符rid */ RC insert_record(const char *data, int record_size, RID *rid); RC recover_insert_record(const char *data, int record_size, RID *rid); @@ -130,7 +136,9 @@ public: /** * 获取指定文件中标识符为rid的记录内容到rec指向的记录结构中 */ - RC get_record(const RID *rid, Record *rec); + RC get_record(RecordPageHandler &page_handler, const RID *rid, bool readonly, Record *rec); + + RC visit_record(const RID &rid, bool readonly, std::function visitor); private: RC init_free_pages(); @@ -138,18 +146,29 @@ private: private: DiskBufferPool *disk_buffer_pool_ = nullptr; std::unordered_set free_pages_; // 没有填充满的页面集合 + common::Mutex lock_; // 当编译时增加-DCONCURRENCY=ON 选项时,才会真正的支持并发 }; class RecordFileScanner { public: RecordFileScanner() = default; + ~RecordFileScanner(); /** * 打开一个文件扫描。 * 如果条件不为空,则要对每条记录进行条件比较,只有满足所有条件的记录才被返回 + * @param table 遍历的哪张表 + * @param buffer_pool 访问的文件 + * @param readonly 当前是否只读操作。访问数据时,需要对页面加锁。比如 + * 删除时也需要遍历找到数据,然后删除,这时就需要加写锁 + * @param condition_filter 做一些初步过滤操作 */ - RC open_scan(DiskBufferPool &buffer_pool, ConditionFilter *condition_filter); + RC open_scan(Table *table, + DiskBufferPool &buffer_pool, + Trx *trx, + bool readonly, + ConditionFilter *condition_filter); /** * 关闭一个文件扫描,释放相应的资源 @@ -164,11 +183,14 @@ private: RC fetch_next_record_in_page(); private: - DiskBufferPool *disk_buffer_pool_ = nullptr; - - BufferPoolIterator bp_iterator_; - ConditionFilter *condition_filter_ = nullptr; - RecordPageHandler record_page_handler_; - RecordPageIterator record_page_iterator_; - Record next_record_; + Table * table_ = nullptr; + DiskBufferPool * disk_buffer_pool_ = nullptr; + Trx * trx_ = nullptr; + bool readonly_ = false; // 遍历出来的数据,是否可能对它做修改 + + BufferPoolIterator bp_iterator_; // 遍历buffer pool的所有页面 + ConditionFilter * condition_filter_ = nullptr; // 过滤record + RecordPageHandler record_page_handler_; + RecordPageIterator record_page_iterator_; // 遍历某个页面上的所有record + Record next_record_; }; diff --git a/src/observer/storage/trx/latch_memo.cpp b/src/observer/storage/trx/latch_memo.cpp index 1342cdf..13d05ae 100644 --- a/src/observer/storage/trx/latch_memo.cpp +++ b/src/observer/storage/trx/latch_memo.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/src/observer/storage/trx/latch_memo.h b/src/observer/storage/trx/latch_memo.h index 9d378fb..7bc469b 100644 --- a/src/observer/storage/trx/latch_memo.h +++ b/src/observer/storage/trx/latch_memo.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -49,6 +49,9 @@ struct LatchMemoItem class LatchMemo final { public: + /** + * @brief 当前遇到的场景都是针对单个BufferPool的,不过从概念上讲,不一定做这个限制 + */ LatchMemo(DiskBufferPool *buffer_pool); ~LatchMemo(); @@ -65,7 +68,6 @@ public: void release(); - /// 除了最后一个锁,其它的都释放掉 void release_to(int point); int memo_point() const { return static_cast(items_.size()); } diff --git a/src/observer/storage/trx/mvcc_trx.cpp b/src/observer/storage/trx/mvcc_trx.cpp new file mode 100644 index 0000000..fa4129c --- /dev/null +++ b/src/observer/storage/trx/mvcc_trx.cpp @@ -0,0 +1,271 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/04/24. +// + +#include +#include "storage/trx/mvcc_trx.h" +#include "storage/common/field.h" + +using namespace std; + +RC MvccTrxKit::init() +{ + fields_ = vector{ + FieldMeta("__trx_xid_begin", AttrType::INTS, 0/*attr_offset*/, 4/*attr_len*/, false/*visible*/), + FieldMeta("__trx_xid_end", AttrType::INTS, 0/*attr_offset*/, 4/*attr_len*/, false/*visible*/) + }; + + LOG_INFO("init mvcc trx kit done."); + return RC::SUCCESS; +} + +const vector *MvccTrxKit::trx_fields() const +{ + return &fields_; +} + +int32_t MvccTrxKit::next_trx_id() +{ + return ++current_trx_id_; +} + +int32_t MvccTrxKit::max_trx_id() const +{ + return numeric_limits::max(); +} + +Trx *MvccTrxKit::create_trx() +{ + return new MvccTrx(*this); +} + +//////////////////////////////////////////////////////////////////////////////// + +MvccTrx::MvccTrx(MvccTrxKit &kit) : trx_kit_(kit) +{} + +RC MvccTrx::insert_record(Table *table, Record &record) +{ + Field begin_field; + Field end_field; + trx_fields(table, begin_field, end_field); + + begin_field.set_int(record, -trx_id_); + end_field.set_int(record, trx_kit_.max_trx_id()); + + RC rc = table->insert_record(record); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to insert record into table. rc=%s", strrc(rc)); + return rc; + } + + pair ret = + operations_.insert(Operation(Operation::Type::INSERT, table, record.rid())); + if (!ret.second) { + rc = RC::INTERNAL; + LOG_WARN("failed to insert operation(insertion) into operation set: duplicate"); + } + return rc; +} + +RC MvccTrx::delete_record(Table * table, Record &record) +{ + Field begin_field; + Field end_field; + trx_fields(table, begin_field, end_field); + + [[maybe_unused]] int32_t end_xid = end_field.get_int(record); + /// 在删除之前,第一次获取record时,就已经对record做了对应的检查,并且保证不会有其它的事务来访问这条数据 + ASSERT(end_xid == trx_kit_.max_trx_id(), "cannot delete an old version record. end_xid=%d", end_xid); + end_field.set_int(record, -trx_id_); + + operations_.insert(Operation(Operation::Type::DELETE, table, record.rid())); + + return RC::SUCCESS; +} + +RC MvccTrx::visit_record(Table *table, Record &record, bool readonly) +{ + Field begin_field; + Field end_field; + trx_fields(table, begin_field, end_field); + + int32_t begin_xid = begin_field.get_int(record); + int32_t end_xid = end_field.get_int(record); + + RC rc = RC::SUCCESS; + if (begin_xid > 0 && end_xid > 0) { + if (trx_id_ >= begin_xid && trx_id_ <= end_xid) { + rc = RC::SUCCESS; + } else { + rc = RC::RECORD_INVISIBLE; + } + } else if (begin_xid < 0) { + // begin xid 小于0说明是刚插入而且没有提交的数据 + rc = (-begin_xid == trx_id_) ? RC::SUCCESS : RC::RECORD_INVISIBLE; + } else if (end_xid < 0) { + // end xid 小于0 说明是正在删除但是还没有提交的数据 + if (readonly) { + // 如果 -end_xid 就是当前事务的事务号,说明是当前事务删除的 + rc = (-end_xid != trx_id_) ? RC::SUCCESS : RC::RECORD_INVISIBLE; + } else { + // 如果当前想要修改此条数据,并且不是当前事务删除的,简单的报错 + // 这是事务并发处理的一种方式,非常简单粗暴。其它的并发处理方法,可以等待,或者让客户端重试 + // 或者等事务结束后,再检测修改的数据是否有冲突 + rc = (-end_xid != trx_id_) ? RC::LOCKED_CONCURRENCY_CONFLICT : RC::RECORD_INVISIBLE; + } + } + return rc; +} + +/** + * @brief 获取指定表上的事务使用的字段 + * + * @param table 指定的表 + * @param begin_xid_field 返回处理begin_xid的字段 + * @param end_xid_field 返回处理end_xid的字段 + */ +void MvccTrx::trx_fields(Table *table, Field &begin_xid_field, Field &end_xid_field) const +{ + const TableMeta &table_meta = table->table_meta(); + const std::pair trx_fields = table_meta.trx_fields(); + ASSERT(trx_fields.second >= 2, "invalid trx fields number. %d", trx_fields.second); + + begin_xid_field.set_table(table); + begin_xid_field.set_field(&trx_fields.first[0]); + end_xid_field.set_table(table); + end_xid_field.set_field(&trx_fields.first[1]); +} + +RC MvccTrx::start_if_need() +{ + if (!started_) { + ASSERT(operations_.empty(), "try to start a new trx while operations is not empty"); + trx_id_ = trx_kit_.next_trx_id(); + started_ = true; + } + return RC::SUCCESS; +} + +RC MvccTrx::commit() +{ + // TODO 这里存在一个很大的问题,不能让其他事务一次性看到当前事务更新到的数据或同时看不到 + RC rc = RC::SUCCESS; + started_ = false; + + int32_t commit_xid = trx_kit_.next_trx_id(); + for (const Operation &operation : operations_) { + switch (operation.type()) { + case Operation::Type::INSERT: { + Record record; + RID rid(operation.page_num(), operation.slot_num()); + + Field begin_xid_field, end_xid_field; + trx_fields(operation.table(), begin_xid_field, end_xid_field); + + auto record_updater = [ this, &begin_xid_field, commit_xid](Record &record) { + (void)this; + ASSERT(begin_xid_field.get_int(record) == -this->trx_id_, + "got an invalid record while committing. begin xid=%d, this trx id=%d", + begin_xid_field.get_int(record), trx_id_); + + begin_xid_field.set_int(record, commit_xid); + }; + + rc = operation.table()->visit_record(rid, false/*readonly*/, record_updater); + ASSERT(rc == RC::SUCCESS, "failed to get record while committing. rid=%s, rc=%s", + rid.to_string().c_str(), strrc(rc)); + } break; + + case Operation::Type::DELETE: { + Record record; + RID rid(operation.page_num(), operation.slot_num()); + + Field begin_xid_field, end_xid_field; + trx_fields(operation.table(), begin_xid_field, end_xid_field); + + auto record_updater = [this, &end_xid_field, commit_xid](Record &record) { + (void)this; + ASSERT(end_xid_field.get_int(record) == -trx_id_, + "got an invalid record while committing. end xid=%d, this trx id=%d", + end_xid_field.get_int(record), trx_id_); + + end_xid_field.set_int(record, commit_xid); + }; + + rc = operation.table()->visit_record(rid, false/*readonly*/, record_updater); + ASSERT(rc == RC::SUCCESS, "failed to get record while committing. rid=%s, rc=%s", + rid.to_string().c_str(), strrc(rc)); + } break; + + default: { + ASSERT(false, "unsupported operation. type=%d", static_cast(operation.type())); + } + } + } + + operations_.clear(); + return rc; +} + +RC MvccTrx::rollback() +{ + RC rc = RC::SUCCESS; + started_ = false; + + for (const Operation &operation : operations_) { + switch (operation.type()) { + case Operation::Type::INSERT: { + RID rid(operation.page_num(), operation.slot_num()); + Record record; + Table *table = operation.table(); + // TODO 这里虽然调用get_record好像多次一举,而且看起来放在table的实现中更好,但是实际上trx应该记录下来自己曾经插入过的数据 + // 也就是不需要从table中获取这条数据,可以直接从当前内存中获取 + // 这里也可以不删除,仅仅给数据加个标识位,等垃圾回收器来收割也行 + rc = table->get_record(rid, record); + ASSERT(rc == RC::SUCCESS, "failed to get record while rollback. rid=%s, rc=%s", + rid.to_string().c_str(), strrc(rc)); + rc = table->delete_record(record); + ASSERT(rc == RC::SUCCESS, "failed to delete record while rollback. rid=%s, rc=%s", + rid.to_string().c_str(), strrc(rc)); + } break; + + case Operation::Type::DELETE: { + Record record; + RID rid(operation.page_num(), operation.slot_num()); + + ASSERT(rc == RC::SUCCESS, "failed to get record while rollback. rid=%s, rc=%s", + rid.to_string().c_str(), strrc(rc)); + Field begin_xid_field, end_xid_field; + trx_fields(operation.table(), begin_xid_field, end_xid_field); + + auto record_updater = [this, &end_xid_field](Record &record) { + ASSERT(end_xid_field.get_int(record) == -trx_id_, + "got an invalid record while rollback. end xid=%d, this trx id=%d", + end_xid_field.get_int(record), trx_id_); + + end_xid_field.set_int(record, trx_kit_.max_trx_id()); + }; + + rc = operation.table()->visit_record(rid, false/*readonly*/, record_updater); + } break; + + default: { + ASSERT(false, "unsupported operation. type=%d", static_cast(operation.type())); + } + } + } + + operations_.clear(); + return rc; +} diff --git a/src/observer/storage/trx/mvcc_trx.h b/src/observer/storage/trx/mvcc_trx.h new file mode 100644 index 0000000..0a5ef33 --- /dev/null +++ b/src/observer/storage/trx/mvcc_trx.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/04/24. +// + +#pragma once + +#include "storage/trx/trx.h" + +class MvccTrxKit : public TrxKit +{ +public: + MvccTrxKit() = default; + virtual ~MvccTrxKit() = default; + + RC init() override; + const std::vector *trx_fields() const override; + Trx *create_trx() override; + + int32_t next_trx_id(); + +public: + int32_t max_trx_id() const; + +private: + std::vector fields_; // 存储事务数据需要用到的字段元数据,所有表结构都需要带的 + + std::atomic current_trx_id_{0}; +}; + +/** + * TODO 没有垃圾回收 + * + */ +class MvccTrx : public Trx +{ +public: + MvccTrx(MvccTrxKit &trx_kit); + virtual ~MvccTrx() = default; + + RC insert_record(Table *table, Record &record) override; + RC delete_record(Table *table, Record &record) override; + + /** + * @brief 当访问到某条数据时,使用此函数来判断是否可见,或者是否有访问冲突 + * + * @param table 要访问的数据属于哪张表 + * @param record 要访问哪条数据 + * @param readonly 是否只读访问 + * @return RC - SUCCESS 成功 + * - RECORD_INVISIBLE 此数据对当前事务不可见,应该跳过 + * - LOCKED_CONCURRENCY_CONFLICT 与其它事务有冲突 + */ + RC visit_record(Table *table, Record &record, bool readonly) override; + + RC start_if_need() override; + RC commit() override; + RC rollback() override; + +private: + void trx_fields(Table *table, Field &begin_xid_field, Field &end_xid_field) const; + +private: + static const int32_t MAX_TRX_ID = std::numeric_limits::max(); + +private: + using OperationSet = std::unordered_set; + MvccTrxKit &trx_kit_; + int32_t trx_id_; + bool started_ = false; + OperationSet operations_; +}; diff --git a/src/observer/storage/trx/trx.cpp b/src/observer/storage/trx/trx.cpp index e10efb1..6a0c7fe 100644 --- a/src/observer/storage/trx/trx.cpp +++ b/src/observer/storage/trx/trx.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -19,266 +19,38 @@ See the Mulan PSL v2 for more details. */ #include "storage/record/record_manager.h" #include "storage/common/field_meta.h" #include "common/log/log.h" +#include "storage/common/field.h" +#include "storage/trx/mvcc_trx.h" +#include "storage/trx/vacuous_trx.h" -static const uint32_t DELETED_FLAG_BIT_MASK = 0x80000000; -static const uint32_t TRX_ID_BIT_MASK = 0x7FFFFFFF; -std::atomic Trx::trx_id(0); +static TrxKit *global_trxkit = nullptr; -int32_t Trx::default_trx_id() +TrxKit *TrxKit::create(const char *name) { - return 0; -} - -int32_t Trx::next_trx_id() -{ - return ++trx_id; -} - -void Trx::set_trx_id(int32_t id) -{ - trx_id = id; -} - -void Trx::next_current_id() -{ - Trx::next_trx_id(); - trx_id_ = trx_id; -} - -int32_t Trx::get_current_id() -{ - return trx_id_; -} - -const char *Trx::trx_field_name() -{ - return "__trx"; -} - -AttrType Trx::trx_field_type() -{ - return INTS; -} - -int Trx::trx_field_len() -{ - return sizeof(int32_t); -} - -Trx::Trx() -{ - start_if_not_started(); -} - -Trx::~Trx() -{} - -RC Trx::insert_record(Table *table, Record *record) -{ - RC rc = RC::SUCCESS; - // 先校验是否以前是否存在过(应该不会存在) - Operation *old_oper = find_operation(table, record->rid()); - if (old_oper != nullptr) { - if (old_oper->type() == Operation::Type::DELETE) { - delete_operation(table, record->rid()); - } else { - return RC::GENERIC_ERROR; - } - } - - // start_if_not_started(); - - // 记录到operations中 - insert_operation(table, Operation::Type::INSERT, record->rid()); - return rc; -} - -RC Trx::delete_record(Table *table, Record *record) -{ - RC rc = RC::SUCCESS; - start_if_not_started(); - Operation *old_oper = find_operation(table, record->rid()); - if (old_oper != nullptr) { - if (old_oper->type() == Operation::Type::INSERT) { - delete_operation(table, record->rid()); - return RC::SUCCESS; - } else { - return RC::GENERIC_ERROR; - } - } - set_record_trx_id(table, *record, trx_id_, true); - insert_operation(table, Operation::Type::DELETE, record->rid()); - return rc; -} - -void Trx::set_record_trx_id(Table *table, Record &record, int32_t trx_id, bool deleted) const -{ - const FieldMeta *trx_field = table->table_meta().trx_field(); - int32_t *ptrx_id = (int32_t *)(record.data() + trx_field->offset()); - if (deleted) { - trx_id |= DELETED_FLAG_BIT_MASK; - } - *ptrx_id = trx_id; -} - -void Trx::get_record_trx_id(Table *table, const Record &record, int32_t &trx_id, bool &deleted) -{ - const FieldMeta *trx_field = table->table_meta().trx_field(); - int32_t trx = *(int32_t *)(record.data() + trx_field->offset()); - trx_id = trx & TRX_ID_BIT_MASK; - deleted = (trx & DELETED_FLAG_BIT_MASK) != 0; -} - -Operation *Trx::find_operation(Table *table, const RID &rid) -{ - std::unordered_map
::iterator table_operations_iter = operations_.find(table); - if (table_operations_iter == operations_.end()) { - return nullptr; + if (0 == strcasecmp(name, "mvcc")) { + return new MvccTrxKit(); } - - OperationSet &table_operations = table_operations_iter->second; - Operation tmp(Operation::Type::UNDEFINED, rid); - OperationSet::iterator operation_iter = table_operations.find(tmp); - if (operation_iter == table_operations.end()) { - return nullptr; - } - return const_cast(&(*operation_iter)); + + return new VacuousTrxKit(); } -void Trx::insert_operation(Table *table, Operation::Type type, const RID &rid) +RC TrxKit::init_global(const char *name) { - OperationSet &table_operations = operations_[table]; - table_operations.emplace(type, rid); -} - -void Trx::delete_operation(Table *table, const RID &rid) -{ - - std::unordered_map
::iterator table_operations_iter = operations_.find(table); - if (table_operations_iter == operations_.end()) { - return; + ASSERT(global_trxkit == nullptr, "init global trx kit twice"); + TrxKit *trx_kit = create(name); + if (nullptr == trx_kit) { + LOG_ERROR("failed to create trx kit by name. name=%s", name); + return RC::INTERNAL; } - Operation tmp(Operation::Type::UNDEFINED, rid); - table_operations_iter->second.erase(tmp); -} - -RC Trx::commit() -{ - RC rc = RC::SUCCESS; - for (const auto &table_operations : operations_) { - Table *table = table_operations.first; - const OperationSet &operation_set = table_operations.second; - for (const Operation &operation : operation_set) { - - RID rid; - rid.page_num = operation.page_num(); - rid.slot_num = operation.slot_num(); - - switch (operation.type()) { - case Operation::Type::INSERT: { - rc = table->commit_insert(this, rid); - if (rc != RC::SUCCESS) { - // handle rc - LOG_ERROR( - "Failed to commit insert operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc)); - } - } break; - case Operation::Type::DELETE: { - rc = table->commit_delete(this, rid); - if (rc != RC::SUCCESS) { - // handle rc - LOG_ERROR( - "Failed to commit delete operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc)); - } - } break; - default: { - LOG_PANIC("Unknown operation. type=%d", (int)operation.type()); - } break; - } - } - } - - operations_.clear(); - trx_id_ = 0; - return rc; -} - -RC Trx::rollback() -{ - RC rc = RC::SUCCESS; - for (const auto &table_operations : operations_) { - Table *table = table_operations.first; - const OperationSet &operation_set = table_operations.second; - for (const Operation &operation : operation_set) { - - RID rid; - rid.page_num = operation.page_num(); - rid.slot_num = operation.slot_num(); - - switch (operation.type()) { - case Operation::Type::INSERT: { - rc = table->rollback_insert(this, rid); - if (rc != RC::SUCCESS) { - // handle rc - LOG_ERROR( - "Failed to rollback insert operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc)); - } - } break; - case Operation::Type::DELETE: { - rc = table->rollback_delete(this, rid); - if (rc != RC::SUCCESS) { - // handle rc - LOG_ERROR( - "Failed to rollback delete operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc)); - } - } break; - default: { - LOG_PANIC("Unknown operation. type=%d", (int)operation.type()); - } break; - } - } + RC rc = trx_kit->init(); + if (rc == RC::SUCCESS) { + global_trxkit = trx_kit; } - - operations_.clear(); - trx_id_ = 0; return rc; } -RC Trx::commit_insert(Table *table, Record &record) +TrxKit *TrxKit::instance() { - set_record_trx_id(table, record, 0, false); - return RC::SUCCESS; -} - -RC Trx::rollback_delete(Table *table, Record &record) -{ - set_record_trx_id(table, record, 0, false); - return RC::SUCCESS; -} - -bool Trx::is_visible(Table *table, const Record *record) -{ - int32_t record_trx_id; - bool record_deleted; - get_record_trx_id(table, *record, record_trx_id, record_deleted); - - // 0 表示这条数据已经提交 - if (0 == record_trx_id || record_trx_id == trx_id_) { - return !record_deleted; - } - - return record_deleted; // 当前记录上面有事务号,说明是未提交数据,那么如果有删除标记的话,就表示是未提交的删除 -} - -void Trx::init_trx_info(Table *table, Record &record) -{ - set_record_trx_id(table, record, trx_id_, false); -} - -void Trx::start_if_not_started() -{ - if (trx_id_ == 0) { - trx_id_ = next_trx_id(); - } -} + return global_trxkit; +} \ No newline at end of file diff --git a/src/observer/storage/trx/trx.h b/src/observer/storage/trx/trx.h index c9e6403..5023945 100644 --- a/src/observer/storage/trx/trx.h +++ b/src/observer/storage/trx/trx.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -15,20 +15,21 @@ See the Mulan PSL v2 for more details. */ #pragma once #include -#include #include #include +#include #include "sql/parser/parse.h" #include "storage/record/record_manager.h" +#include "storage/common/field_meta.h" +#include "storage/common/table.h" #include "rc.h" -class Table; - class Operation { public: - enum class Type : int { + enum class Type : int + { INSERT, UPDATE, DELETE, @@ -36,25 +37,23 @@ public: }; public: - Operation(Type type, const RID &rid) : type_(type), page_num_(rid.page_num), slot_num_(rid.slot_num) + Operation(Type type, Table *table, const RID &rid) + : type_(type), + table_(table), + page_num_(rid.page_num), + slot_num_(rid.slot_num) {} - Type type() const - { - return type_; - } - PageNum page_num() const - { - return page_num_; - } - SlotNum slot_num() const - { - return slot_num_; - } + Type type() const { return type_; } + int32_t table_id() const { return table_->table_id(); } + Table * table() const { return table_; } + PageNum page_num() const { return page_num_; } + SlotNum slot_num() const { return slot_num_; } private: Type type_; - PageNum page_num_; + Table * table_ = nullptr; + PageNum page_num_; // TODO use RID instead of page num and slot num SlotNum slot_num_; }; @@ -72,64 +71,45 @@ class OperationEqualer public: bool operator()(const Operation &op1, const Operation &op2) const { - return op1.page_num() == op2.page_num() && op1.slot_num() == op2.slot_num(); + return op1.table_id() == op2.table_id() && + op1.page_num() == op2.page_num() && op1.slot_num() == op2.slot_num(); } }; -/** - * 这里是一个简单的事务实现,可以支持提交/回滚。但是没有对并发访问做控制 - * 可以在这个基础上做备份恢复,当然也可以重写 - */ -class Trx +class TrxKit { public: - static std::atomic trx_id; + enum Type + { + VACUOUS, + MVCC, + }; - static int32_t default_trx_id(); - static int32_t next_trx_id(); - static void set_trx_id(int32_t id); +public: + TrxKit() = default; + virtual ~TrxKit() = default; - static const char *trx_field_name(); - static AttrType trx_field_type(); - static int trx_field_len(); + virtual RC init() = 0; + virtual const std::vector *trx_fields() const = 0; + virtual Trx *create_trx() = 0; public: - Trx(); - ~Trx(); + static TrxKit *create(const char *name); + static RC init_global(const char *name); + static TrxKit *instance(); +}; +class Trx +{ public: - RC insert_record(Table *table, Record *record); - RC delete_record(Table *table, Record *record); + Trx() = default; + virtual ~Trx() = default; - RC commit(); - RC rollback(); + virtual RC insert_record(Table *table, Record &record) = 0; + virtual RC delete_record(Table *table, Record &record) = 0; + virtual RC visit_record(Table *table, Record &record, bool readonly) = 0; - RC commit_insert(Table *table, Record &record); - RC rollback_delete(Table *table, Record &record); - - bool is_visible(Table *table, const Record *record); - - void init_trx_info(Table *table, Record &record); - - void next_current_id(); - - int32_t get_current_id(); - -private: - void set_record_trx_id(Table *table, Record &record, int32_t trx_id, bool deleted) const; - static void get_record_trx_id(Table *table, const Record &record, int32_t &trx_id, bool &deleted); - -private: - using OperationSet = std::unordered_set; - - Operation *find_operation(Table *table, const RID &rid); - void insert_operation(Table *table, Operation::Type type, const RID &rid); - void delete_operation(Table *table, const RID &rid); - -private: - void start_if_not_started(); - -private: - int32_t trx_id_ = 0; - std::unordered_map
operations_; + virtual RC start_if_need() = 0; + virtual RC commit() = 0; + virtual RC rollback() = 0; }; diff --git a/src/observer/storage/trx/vacuous_trx.cpp b/src/observer/storage/trx/vacuous_trx.cpp new file mode 100644 index 0000000..73ad838 --- /dev/null +++ b/src/observer/storage/trx/vacuous_trx.cpp @@ -0,0 +1,64 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/24. +// + +#include "storage/trx/vacuous_trx.h" + +using namespace std; + +RC VacuousTrxKit::init() +{ + return RC::SUCCESS; +} + +const vector *VacuousTrxKit::trx_fields() const +{ + return nullptr; +} + +Trx *VacuousTrxKit::create_trx() +{ + return new VacuousTrx; +} + +//////////////////////////////////////////////////////////////////////////////// + +RC VacuousTrx::insert_record(Table *table, Record &record) +{ + return table->insert_record(record); +} + +RC VacuousTrx::delete_record(Table *table, Record &record) +{ + return table->delete_record(record); +} + +RC VacuousTrx::visit_record(Table *table, Record &record, bool readonly) +{ + return RC::SUCCESS; +} + +RC VacuousTrx::start_if_need() +{ + return RC::SUCCESS; +} + +RC VacuousTrx::commit() +{ + return RC::SUCCESS; +} + +RC VacuousTrx::rollback() +{ + return RC::SUCCESS; +} diff --git a/src/observer/storage/trx/vacuous_trx.h b/src/observer/storage/trx/vacuous_trx.h new file mode 100644 index 0000000..aebfe01 --- /dev/null +++ b/src/observer/storage/trx/vacuous_trx.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/4/24. +// + +#pragma once + +#include "storage/trx/trx.h" + +/** + * @brief Vacuous(真空的),顾名思义就是没有实现事务功能 + */ +class VacuousTrxKit : public TrxKit +{ +public: + VacuousTrxKit() = default; + virtual ~VacuousTrxKit() = default; + + RC init() override; + const std::vector *trx_fields() const override; + Trx *create_trx() override; +}; + +class VacuousTrx : public Trx +{ +public: + VacuousTrx() = default; + virtual ~VacuousTrx() = default; + + RC insert_record(Table *table, Record &record) override; + RC delete_record(Table *table, Record &record) override; + RC visit_record(Table *table, Record &record, bool readonly) override; + RC start_if_need() override; + RC commit() override; + RC rollback() override; +}; diff --git a/test/perf/client_performance_test.cpp b/test/perf/client_performance_test.cpp index f31d89e..1a1d009 100644 --- a/test/perf/client_performance_test.cpp +++ b/test/perf/client_performance_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/bitmap_test.cpp b/unittest/bitmap_test.cpp index 206c9ab..950910a 100644 --- a/unittest/bitmap_test.cpp +++ b/unittest/bitmap_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/bp_manager_test.cpp b/unittest/bp_manager_test.cpp index f9b8724..2f3a002 100644 --- a/unittest/bp_manager_test.cpp +++ b/unittest/bp_manager_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/bplus_tree_test.cpp b/unittest/bplus_tree_test.cpp index 8e5dfbb..4e8b2d0 100644 --- a/unittest/bplus_tree_test.cpp +++ b/unittest/bplus_tree_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/clog_test.cpp b/unittest/clog_test.cpp index e936939..7b287ba 100644 --- a/unittest/clog_test.cpp +++ b/unittest/clog_test.cpp @@ -1,6 +1,4 @@ -/* Copyright (c) 2021-2022 Xie Meiyi(xiemeiyi@hust.edu.cn), -Huazhong University of Science and Technology -and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021-2022 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/log_test.cpp b/unittest/log_test.cpp index cf47110..812b166 100644 --- a/unittest/log_test.cpp +++ b/unittest/log_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/log_test.h b/unittest/log_test.h index 557e31e..ff63268 100644 --- a/unittest/log_test.h +++ b/unittest/log_test.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/lower_bound_test.cpp b/unittest/lower_bound_test.cpp index 3f5b118..f701f48 100644 --- a/unittest/lower_bound_test.cpp +++ b/unittest/lower_bound_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/md5_test.cpp b/unittest/md5_test.cpp index 92ea2f5..7f20c5a 100644 --- a/unittest/md5_test.cpp +++ b/unittest/md5_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/md5_test.h b/unittest/md5_test.h index ea210c0..77b2ea5 100644 --- a/unittest/md5_test.h +++ b/unittest/md5_test.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/mem_pool_test.cpp b/unittest/mem_pool_test.cpp index 947cd87..db65ed5 100644 --- a/unittest/mem_pool_test.cpp +++ b/unittest/mem_pool_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/path_test.cpp b/unittest/path_test.cpp index d2d6b3d..7a5ec06 100644 --- a/unittest/path_test.cpp +++ b/unittest/path_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/persist_test.cpp b/unittest/persist_test.cpp index 131a5de..3bef4a1 100644 --- a/unittest/persist_test.cpp +++ b/unittest/persist_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/pidfile_test.cpp b/unittest/pidfile_test.cpp index 5acce09..751603b 100644 --- a/unittest/pidfile_test.cpp +++ b/unittest/pidfile_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: diff --git a/unittest/rc_test.cpp b/unittest/rc_test.cpp index e992d94..50e8387 100644 --- a/unittest/rc_test.cpp +++ b/unittest/rc_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -17,5 +17,4 @@ See the Mulan PSL v2 for more details. */ int main(int argc, char **argv) { - std::cout << rc2SimpleStr(status) << std::endl; } \ No newline at end of file diff --git a/unittest/record_manager_test.cpp b/unittest/record_manager_test.cpp index 06c77e5..87fcb47 100644 --- a/unittest/record_manager_test.cpp +++ b/unittest/record_manager_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -18,6 +18,7 @@ See the Mulan PSL v2 for more details. */ #include "gtest/gtest.h" #include "storage/default/disk_buffer_pool.h" #include "storage/record/record_manager.h" +#include "storage/trx/vacuous_trx.h" using namespace common; @@ -123,8 +124,9 @@ TEST(test_record_page_handler, test_record_file_iterator) rc = file_handler.init(bp); ASSERT_EQ(rc, RC::SUCCESS); + VacuousTrx trx; RecordFileScanner file_scanner; - rc = file_scanner.open_scan(*bp, nullptr); + rc = file_scanner.open_scan(nullptr/*table*/, *bp, &trx, true/*readonly*/, nullptr/*condition_filter*/); ASSERT_EQ(rc, RC::SUCCESS); int count = 0; @@ -147,7 +149,7 @@ TEST(test_record_page_handler, test_record_file_iterator) rids.push_back(rid); } - rc = file_scanner.open_scan(*bp, nullptr); + rc = file_scanner.open_scan(nullptr/*table*/, *bp, &trx, true/*readonly*/, nullptr/*condition_filter*/); ASSERT_EQ(rc, RC::SUCCESS); count = 0; @@ -164,7 +166,7 @@ TEST(test_record_page_handler, test_record_file_iterator) ASSERT_EQ(rc, RC::SUCCESS); } - rc = file_scanner.open_scan(*bp, nullptr); + rc = file_scanner.open_scan(nullptr/*table*/, *bp, &trx, true/*readonly*/, nullptr/*condition_filter*/); ASSERT_EQ(rc, RC::SUCCESS); count = 0; diff --git a/unittest/thread_test.h b/unittest/thread_test.h index 81f42a2..1b7c5cc 100644 --- a/unittest/thread_test.h +++ b/unittest/thread_test.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved. +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: @@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ // Created by Longda on 2021 // -#ifndef CTESTTHREAD_H_ -#define CTESTTHREAD_H_ +#pragma once #include "common/lang/mutex.h" -- GitLab