diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 29d97a23e36791fcd8275338b7733290be58300a..fe5dc73f5fcf7497cc71595a0bda42cba2d8d4d8 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -22,11 +22,6 @@ "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 518961adbe50e4ba72ffb2dfd263eb0f7519d46b..8ee55a8818d4a6c2242f30501321f910d7eadb88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir " ${PROJECT_BINARY_DIR}) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) #SET(LIBRARY_OUTPUT_PATH <路径>) -OPTION(ENABLE_ASAN "Enable build with address sanitizer" OFF) +OPTION(ENABLE_ASAN "Enable build with address sanitizer" ON) OPTION(WITH_UNIT_TESTS "Compile miniob with unit tests" ON) OPTION(CONCURRENCY "Support concurrency operations" OFF) @@ -40,7 +40,7 @@ ELSE() ENDIF(WIN32) # This is for clangd plugin for vscode -SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -DCMAKE_EXPORT_COMPILE_COMMANDS=1") +SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -Werror") IF(DEBUG) MESSAGE("DEBUG has been set as TRUE ${DEBUG}") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O0 -g -DDEBUG ") diff --git a/build.sh b/build.sh index 4aba907392f50b5fbebc9a2332f1a7bcb1303799..8d6d735d0d44ed10e136b7f7956c60b4bc00dd95 100755 --- a/build.sh +++ b/build.sh @@ -11,7 +11,6 @@ ALL_ARGS=("$@") BUILD_ARGS=() MAKE_ARGS=(-j $CPU_CORES) MAKE=make -ASAN_OPTION=ON echo "$0 ${ALL_ARGS[@]}" @@ -24,7 +23,7 @@ function usage echo "./build.sh [BuildType] [--make [MakeOptions]]" echo "" echo "OPTIONS:" - echo "BuildType => debug(default), release, debug_asan, release_asan" + echo "BuildType => debug(default), release" echo "MakeOptions => Options to make command, default: -j N" echo "" @@ -137,15 +136,9 @@ function build xrelease) do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEBUG=OFF ;; - xrelease_asan) - do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEBUG=OFF -DENABLE_ASAN=$ASAN_OPTION - ;; xdebug) do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DDEBUG=ON ;; - xdebug_asan) - do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DDEBUG=ON -DENABLE_ASAN=$ASAN_OPTION - ;; *) BUILD_ARGS=(debug "${BUILD_ARGS[@]}") build diff --git a/deps/common/lang/bitmap.cpp b/deps/common/lang/bitmap.cpp index b3f493c0d6fbe423f1713bf90e2581157a3a8f96..097167eab321707b2cc700f8b22f915a446e441e 100644 --- a/deps/common/lang/bitmap.cpp +++ b/deps/common/lang/bitmap.cpp @@ -36,6 +36,11 @@ int find_first_setted(char byte, int start) return -1; } +int bytes(int size) +{ + return size % 8 == 0 ? size / 8 : size / 8 + 1; +} + Bitmap::Bitmap() : bitmap_(nullptr), size_(0) {} Bitmap::Bitmap(char *bitmap, int size) : bitmap_(bitmap), size_(size) @@ -69,7 +74,7 @@ int Bitmap::next_unsetted_bit(int start) { int ret = -1; int start_in_byte = start % 8; - for (int iter = start / 8, end = (size_ % 8 == 0 ? size_ / 8 : size_ / 8 + 1); iter <= end; iter++) { + for (int iter = start / 8, end = bytes(size_); iter < end; iter++) { char byte = bitmap_[iter]; if (byte != -1) { int index_in_byte = find_first_zero(byte, start_in_byte); @@ -92,7 +97,7 @@ int Bitmap::next_setted_bit(int start) { int ret = -1; int start_in_byte = start % 8; - for (int iter = start / 8, end = (size_ % 8 == 0 ? size_ / 8 : size_ / 8 + 1); iter <= end; iter++) { + for (int iter = start / 8, end = bytes(size_); iter < end; iter++) { char byte = bitmap_[iter]; if (byte != 0x00) { int index_in_byte = find_first_setted(byte, start_in_byte); diff --git a/deps/common/lang/lower_bound.h b/deps/common/lang/lower_bound.h index 8eb63240513473baf327e25f0eca2319757b1c2a..f204977abc89c3ae449bc96112031a06db20f6c4 100644 --- a/deps/common/lang/lower_bound.h +++ b/deps/common/lang/lower_bound.h @@ -82,9 +82,20 @@ ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T return lower_bound>(first, last, val, Comparator(), _found); } +// std::iterator is deprecated +// refer to https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/#:~:text=std%3A%3Aiterator%20is%20deprecated%2C%20so%20we%20should%20stop%20using,the%205%20aliases%20inside%20of%20your%20custom%20iterators. +// a sample code: +// https://github.com/google/googletest/commit/25208a60a27c2e634f46327595b281cb67355700 template -class BinaryIterator : public std::iterator +class BinaryIterator { +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = Distance; + using pointer = value_type *; + using reference = value_type &; + public: BinaryIterator() = default; BinaryIterator(size_t item_num, T *data) : item_num_(item_num), data_(data) diff --git a/deps/common/log/log.h b/deps/common/log/log.h index 35c56e7f9ee015157eee29de7a3bf230143419c4..7285173f1efd554f985c3a6936b4fae014e02e56 100644 --- a/deps/common/log/log.h +++ b/deps/common/log/log.h @@ -182,7 +182,7 @@ extern Log *g_log; } \ snprintf(prefix, \ sizeof(prefix), \ - "[%s %s %s:%u %s]>>", \ + "[%s %s %s:%u %s] >> ", \ sz_head, \ (common::g_log)->prefix_msg(level), \ __FILE_NAME__, \ diff --git a/deps/common/os/path.cpp b/deps/common/os/path.cpp index 6735165ae677d5c33615f5c77adda9875e340f4f..441780a259ecf2fda7c3941ac742d101a97ae844 100644 --- a/deps/common/os/path.cpp +++ b/deps/common/os/path.cpp @@ -189,19 +189,21 @@ int list_file(const char *path, const char *filter_pattern, std::vectord_name[0]) // 跳过./..文件和隐藏文件 continue; - snprintf(tmp_path, sizeof(tmp_path), "%s/%s", path, entry.d_name); + snprintf(tmp_path, sizeof(tmp_path), "%s/%s", path, pentry->d_name); if (is_directory(tmp_path)) continue; - if (!filter_pattern || 0 == regexec(®, entry.d_name, 0, NULL, 0)) - files.push_back(entry.d_name); + if (!filter_pattern || 0 == regexec(®, pentry->d_name, 0, NULL, 0)) + files.push_back(pentry->d_name); } if (filter_pattern) @@ -211,4 +213,4 @@ int list_file(const char *path, const char *filter_pattern, std::vectorwrite(log_block->log_block_hdr_.log_block_no, CLOG_BUFFER_SIZE, buffer_); + RC rc = log_file->write(log_block->log_block_hdr_.log_block_no, CLOG_BUFFER_SIZE, buffer_); + ASSERT(rc == RC::SUCCESS, "failed to write buffer block to file. error=%s", strerror(errno)); write_block_offset_ = 0; write_offset_ = 0; memset(buffer_, 0, CLOG_BUFFER_SIZE); } else { CLogBlock *log_block = (CLogBlock *)buffer_; - log_file->write(log_block->log_block_hdr_.log_block_no, write_block_offset_ + CLOG_BLOCK_SIZE, buffer_); + RC rc = log_file->write(log_block->log_block_hdr_.log_block_no, write_block_offset_ + CLOG_BLOCK_SIZE, buffer_); + ASSERT(rc == RC::SUCCESS, "failed to write buffer block to file. error=%s", strerror(errno)); log_block = (CLogBlock *)&buffer_[write_block_offset_]; if (log_block->log_block_hdr_.log_data_len_ == CLOG_BLOCK_DATA_SIZE) { // 最后一个block已写满 write_block_offset_ = 0; @@ -397,6 +399,14 @@ void CLogMTRManager::log_record_manage(CLogRecord *log_rec) } } +CLogMTRManager::~CLogMTRManager() +{ + for (auto log_rec: log_redo_list) { + delete log_rec; + } + log_redo_list.clear(); +} + //////////////////// std::atomic CLogManager::gloabl_lsn_(0); CLogManager::CLogManager(const char *path) @@ -410,6 +420,17 @@ CLogManager::~CLogManager() { if (log_buffer_) { delete log_buffer_; + log_buffer_ = nullptr; + } + + if (log_file_ != nullptr) { + delete log_file_; + log_file_ = nullptr; + } + + if (log_mtr_mgr_ != nullptr) { + delete log_mtr_mgr_; + log_mtr_mgr_ = nullptr; } } diff --git a/src/observer/storage/clog/clog.h b/src/observer/storage/clog/clog.h index 4ba87942afbfb6aac995ca2e55ba9a078ddb6668..222992f0d677871ebfdf31943f7934762a387bd4 100644 --- a/src/observer/storage/clog/clog.h +++ b/src/observer/storage/clog/clog.h @@ -227,6 +227,8 @@ struct CLogMTRManager { std::unordered_map trx_commited; // void log_record_manage(CLogRecord *log_rec); + + ~CLogMTRManager(); }; // diff --git a/src/observer/storage/persist/persist.cpp b/src/observer/storage/persist/persist.cpp index 18450ffff1e072e74afbf290e90ab3fae025794a..fe4fbfb1511710eba49bb2ec1bad9be16de3d173 100644 --- a/src/observer/storage/persist/persist.cpp +++ b/src/observer/storage/persist/persist.cpp @@ -269,12 +269,14 @@ RC PersistHandler::read_at(uint64_t offset, int size, char *data, int64_t *out_s strerror(errno)); return RC::FILE_SEEK; } else { - int64_t read_size = 0; - if ((read_size = read(file_desc_, data, size)) != size) { - LOG_WARN("Failed to read %lld of %d:%s due to %s.", offset, file_desc_, file_name_.c_str(), strerror(errno)); + ssize_t read_size = read(file_desc_, data, size); + if (read_size == 0) { + LOG_TRACE("read file touch the end. file name=%s", file_name_.c_str()); + } else if (read_size < 0) { + LOG_WARN("failed to read file. file name=%s, offset=%lld, size=%d, error=%s", file_name_.c_str(), offset, size, + strerror(errno)); rc = RC::FILE_READ; - } - if (out_size != nullptr) { + } else if (out_size != nullptr) { *out_size = read_size; } } diff --git a/unittest/clog_test.cpp b/unittest/clog_test.cpp index 158b7a65e499f8c7d06d35bec9d3eee46df1a73a..1de4a31befe7aa9a13b77c49df9770123b79d228 100644 --- a/unittest/clog_test.cpp +++ b/unittest/clog_test.cpp @@ -39,6 +39,9 @@ Record *gen_del_record(int32_t page_num, int32_t slot_num) TEST(test_clog, test_clog) { + const char *clog_file = "./clog"; + remove(clog_file); + CLogManager *log_mgr = new CLogManager("./"); CLogRecord *log_rec[6]; @@ -116,6 +119,7 @@ TEST(test_clog, test_clog) i++; } */ + delete log_mgr; } int main(int argc, char **argv) @@ -123,7 +127,7 @@ int main(int argc, char **argv) // 分析gtest程序的命令行参数 testing::InitGoogleTest(&argc, argv); - LoggerFactory::init_default("test.log", LOG_LEVEL_TRACE); + LoggerFactory::init_default("clog_test.log", LOG_LEVEL_TRACE); // 调用RUN_ALL_TESTS()运行所有测试用例 // main函数返回RUN_ALL_TESTS()的运行结果 diff --git a/unittest/path_test.cpp b/unittest/path_test.cpp deleted file mode 100644 index 7a5ec06c2ff3b1d1f484024c283ae44c1333de4e..0000000000000000000000000000000000000000 --- a/unittest/path_test.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. -miniob is licensed under Mulan PSL v2. -You can 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 Longda on 2021 -// - -int main(int argc, char **argv) -{ - return 0; -} \ No newline at end of file diff --git a/unittest/record_manager_test.cpp b/unittest/record_manager_test.cpp index 87fcb47bf67e217b9ebfb38c9023bfb8e1ab8c31..01da85ed163a09e1b643035d44a4ba94a6eaa0bf 100644 --- a/unittest/record_manager_test.cpp +++ b/unittest/record_manager_test.cpp @@ -104,7 +104,9 @@ TEST(test_record_page_handler, test_record_page_handler) } ASSERT_EQ(count, 6); + record_page_handle.cleanup(); bpm->close_file(record_manager_file); + delete bpm; } TEST(test_record_page_handler, test_record_file_iterator) @@ -179,6 +181,7 @@ TEST(test_record_page_handler, test_record_file_iterator) ASSERT_EQ(count, rids.size() / 2); bpm->close_file(record_manager_file); + delete bpm; } int main(int argc, char **argv) diff --git a/unittest/thread_test.h b/unittest/thread_test.h deleted file mode 100644 index 1b7c5cc840b5cd27dbf9c916f7eaedced7e82b12..0000000000000000000000000000000000000000 --- a/unittest/thread_test.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. -miniob is licensed under Mulan PSL v2. -You can 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 Longda on 2021 -// - -#pragma once - -#include "common/lang/mutex.h" - -/* - * - */ -class ThreadTest { -public: - ThreadTest(); - virtual ~ThreadTest(); - - int create(); - - int startTestCond(); - int startTestDeadLock(); - - static void *testCond(void *param); - static void *testDeadLock(void *param); - -private: - int param[10]; - - pthread_mutex_t mutex; - pthread_cond_t cond; - - pthread_mutex_t dead_mutex1; - pthread_mutex_t dead_mutex2; -}; - -#endif /* CTESTTHREAD_H_ */