511 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2021 OceanBase
 | |
|  * OceanBase CE is licensed under Mulan PubL v2.
 | |
|  * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | |
|  * You may obtain a copy of Mulan PubL v2 at:
 | |
|  *          http://license.coscl.org.cn/MulanPubL-2.0
 | |
|  * 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 PubL v2 for more details.
 | |
|  */
 | |
| 
 | |
| #define USING_LOG_PREFIX SQL
 | |
| 
 | |
| #include <gtest/gtest.h>
 | |
| #include "lib/alloc/ob_malloc_allocator.h"
 | |
| #include "lib/allocator/ob_malloc.h"
 | |
| #include "storage/blocksstable/ob_data_file_prepare.h"
 | |
| #include "storage/blocksstable/ob_macro_file.h"
 | |
| #include "sql/engine/basic/ob_ra_row_store.h"
 | |
| #include "share/config/ob_server_config.h"
 | |
| 
 | |
| namespace oceanbase
 | |
| {
 | |
| namespace sql
 | |
| {
 | |
| using namespace common;
 | |
| 
 | |
| class TestEnv : public ::testing::Environment
 | |
| {
 | |
| public:
 | |
|   virtual void SetUp() override
 | |
|   {
 | |
|     GCONF.enable_sql_operator_dump.set_value("True");
 | |
|     lib::AChunkMgr::instance().set_max_chunk_cache_size(0);
 | |
|     int ret = OB_SUCCESS;
 | |
|     lib::ObMallocAllocator *malloc_allocator = lib::ObMallocAllocator::get_instance();
 | |
|     ret = malloc_allocator->create_and_add_tenant_allocator(OB_SYS_TENANT_ID);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     int s = (int)time(NULL);
 | |
|     LOG_INFO("initial setup random seed", K(s));
 | |
|     srandom(s);
 | |
|   }
 | |
| 
 | |
|   virtual void TearDown() override
 | |
|   {
 | |
|   }
 | |
| };
 | |
| 
 | |
| #define CALL(func, ...) func(__VA_ARGS__); ASSERT_FALSE(HasFatalFailure());
 | |
| 
 | |
| class TestRARowStore : public blocksstable::TestDataFilePrepare
 | |
| {
 | |
| public:
 | |
|   TestRARowStore() : blocksstable::TestDataFilePrepare("TestDiskIR", 2<<20, 1000)
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   virtual void SetUp() override
 | |
|   {
 | |
|     int ret = OB_SUCCESS;
 | |
|     blocksstable::TestDataFilePrepare::SetUp();
 | |
| 		ret = blocksstable::ObMacroFileManager::get_instance().init();
 | |
| 		ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|     row_.count_ = COLS;
 | |
|     row_.cells_ = cells_;
 | |
|     cells_[1].set_null();
 | |
| 
 | |
|     ret = rs_.init(0, tenant_id_, ctx_id_, label_);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|     memset(str_buf_, 'a', BUF_SIZE);
 | |
|   }
 | |
| 
 | |
|   virtual void TearDown() override
 | |
|   {
 | |
|     rs_.reset();
 | |
| 
 | |
|     blocksstable::ObMacroFileManager::get_instance().destroy();
 | |
|     blocksstable::TestDataFilePrepare::TearDown();
 | |
|     common::ObModItem mod;
 | |
|   }
 | |
| 
 | |
|   ObNewRow &gen_row(int64_t row_id)
 | |
|   {
 | |
|     cells_[0].set_int(row_id);
 | |
|     int64_t max_size = 512;
 | |
|     if (enable_big_row_ && row_id > 0 && random() % 100000 < 5) {
 | |
|       max_size = 1 << 20;
 | |
|     }
 | |
|     int64_t size = 10 + random() % max_size;
 | |
|     cells_[2].set_varchar(str_buf_, (int)size);
 | |
|     return row_;
 | |
|   }
 | |
| 
 | |
|   template <typename T>
 | |
|   void verify_row(T &reader, int64_t id, bool verify_all = false)
 | |
|   {
 | |
|     const ObNewRow *r = NULL;
 | |
|     int ret = reader.get_row(id, r);
 | |
|     ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|     int64_t v;
 | |
|     r->get_cell(0).get_int(v);
 | |
|     if (verify_all) {
 | |
|       r->get_cell(1).is_null();
 | |
|       ObString s = r->get_cell(2).get_varchar();
 | |
|       ASSERT_EQ(0, strncmp(str_buf_, s.ptr(), s.length()));
 | |
|     }
 | |
|     ASSERT_EQ(id, v);
 | |
|   }
 | |
| 
 | |
|   void verify_row(int64_t id, bool verify_all = false)
 | |
|   {
 | |
|     return verify_row(rs_, id, verify_all);
 | |
|   }
 | |
| 
 | |
|   void verify_rows(int64_t begin, int64_t end,
 | |
|       const char *mode =  "scan", int64_t cnt = 0, bool verify_all = false)
 | |
|   {
 | |
|     if (strcmp(mode, "scan") == 0) {
 | |
|       for (int64_t i = begin; i < end; i++) {
 | |
|         CALL(verify_row, i, verify_all);
 | |
|       }
 | |
|     } else if (strcmp(mode, "rscan") == 0) {
 | |
|       for (int64_t i = begin; i < end; i++) {
 | |
|         CALL(verify_row, end + begin - i - 1, verify_all);
 | |
|       }
 | |
|     } else if (strcmp(mode, "get") == 0) {
 | |
|       for (int64_t i = 0; i < cnt; i++) {
 | |
|         CALL(verify_row, random() % (end - begin) + begin, verify_all);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void append_rows(int64_t cnt)
 | |
|   {
 | |
|     int64_t ret = OB_SUCCESS;
 | |
|     int64_t base = rs_.get_row_cnt();
 | |
|     for (int64_t i = 0; i < cnt; i++) {
 | |
|       ret = rs_.add_row(gen_row(base + i));
 | |
|       ASSERT_EQ(OB_SUCCESS, ret);
 | |
|     }
 | |
|     ASSERT_EQ(base + cnt, rs_.get_row_cnt());
 | |
|   }
 | |
| 
 | |
| protected:
 | |
| 
 | |
|   const static int64_t COLS = 3;
 | |
|   bool enable_big_row_ = false;
 | |
|   ObObj cells_[COLS];
 | |
|   ObNewRow row_;
 | |
|   ObRARowStore rs_;
 | |
| 
 | |
|   int64_t tenant_id_ = OB_SYS_TENANT_ID;
 | |
|   int64_t ctx_id_ = ObCtxIds::WORK_AREA;
 | |
|   const char *label_ = ObModIds::OB_SQL_ROW_STORE;
 | |
| 
 | |
|   const static int64_t BUF_SIZE = 2 << 20;
 | |
|   char str_buf_[BUF_SIZE];
 | |
| };
 | |
| 
 | |
| TEST_F(TestRARowStore, basic)
 | |
| {
 | |
|   CALL(append_rows, 3000); // approximate 1MB, index block not needed
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "scan", 0, true);
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "rscan", 0, true);
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "get", rs_.get_row_cnt(), true);
 | |
| 
 | |
|   CALL(append_rows, 10000);
 | |
|   LOG_INFO("mem", K(rs_.get_mem_hold()));
 | |
|   ASSERT_EQ(13000, rs_.get_row_cnt());
 | |
|   for (int64_t i = 0; i < rs_.get_row_cnt(); i++) {
 | |
|     CALL(verify_row, i, true);
 | |
|   }
 | |
| 
 | |
|   int ret = OB_SUCCESS;
 | |
|   const ObNewRow *row = NULL;
 | |
|   ret = rs_.get_row(-1, row);
 | |
|   ASSERT_NE(OB_SUCCESS, ret);
 | |
|   ret = rs_.get_row(rs_.get_row_cnt(), row);
 | |
|   ASSERT_NE(OB_SUCCESS, ret);
 | |
| 
 | |
|   enable_big_row_ = true;
 | |
|   CALL(append_rows, 20000);
 | |
|   LOG_INFO("mem", K(rs_.get_mem_hold()));
 | |
|   ASSERT_EQ(33000, rs_.get_row_cnt());
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "get", 1000, true);
 | |
| 
 | |
|   rs_.reset();
 | |
|   ret = rs_.init(5L << 20, tenant_id_, ctx_id_, label_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   CALL(append_rows, 100000);
 | |
|   ASSERT_GT(rs_.get_mem_hold(), 0);
 | |
|   ASSERT_GT(rs_.get_file_size(), 0);
 | |
|   LOG_WARN("mem and disk", K(rs_.get_mem_hold()), K(rs_.get_file_size()));
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "scan", 0, true);
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "rscan", 0, true);
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "get", 500, true);
 | |
| }
 | |
| 
 | |
| TEST_F(TestRARowStore, mem_perf)
 | |
| {
 | |
|   int64_t rows = 2000000;
 | |
|   int64_t begin = ObTimeUtil::current_time();
 | |
|   CALL(append_rows, rows);
 | |
|   LOG_WARN("write time:", K(rows), K(ObTimeUtil::current_time() - begin));
 | |
|   for (int64_t i = 0; i < 10000; i++) {
 | |
|     CALL(verify_row, random() % rs_.get_row_cnt(), true);
 | |
|   }
 | |
|   LOG_INFO("mem", K(rs_.get_mem_hold()));
 | |
| 
 | |
|   begin = ObTimeUtil::current_time();
 | |
|   CALL(verify_rows, 0, rows, "scan");
 | |
|   LOG_WARN("scan time:", K(rows), K(ObTimeUtil::current_time() - begin));
 | |
| 
 | |
|   begin = common::ObTimeUtil::current_time();
 | |
|   CALL(verify_rows, 0, rows, "rscan");
 | |
|   LOG_WARN("reverse scan time:", K(rows), K(ObTimeUtil::current_time() - begin));
 | |
| 
 | |
|   begin = common::ObTimeUtil::current_time();
 | |
|   CALL(verify_rows, 0, rows, "get", rows);
 | |
|   LOG_WARN("random access time:", K(rows), K(ObTimeUtil::current_time() - begin));
 | |
| }
 | |
| 
 | |
| TEST_F(TestRARowStore, disk)
 | |
| {
 | |
|   int64_t begin = 0;
 | |
|   int64_t write_time = 0;
 | |
|   int64_t round = 500;
 | |
|   rs_.set_mem_limit(100L << 20);
 | |
|   for (int64_t i = 0; i < round; i++) {
 | |
|     if (i == round / 2) {
 | |
|       enable_big_row_ = true;
 | |
|     }
 | |
|     begin = common::ObTimeUtil::current_time();
 | |
|     CALL(append_rows, 10000);
 | |
|     write_time += common::ObTimeUtil::current_time() - begin;
 | |
|     CALL(verify_rows, 0, rs_.get_row_cnt(), "get", 10);
 | |
|   }
 | |
|   int64_t rows = round * 10000;
 | |
|   LOG_WARN("mem and disk", K(rows), K(rs_.get_mem_hold()), K(rs_.get_file_size()));
 | |
|   LOG_INFO("disk write:", K(rows), K(write_time));
 | |
| 
 | |
|   begin = ObTimeUtil::current_time();
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "rscan");
 | |
|   LOG_WARN("disk rscan time:", K(rows), K(ObTimeUtil::current_time() - begin));
 | |
| }
 | |
| 
 | |
| TEST_F(TestRARowStore, finish_add_row)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
| 
 | |
|   rs_.set_mem_limit(100L << 20);
 | |
|   CALL(append_rows, 10000);
 | |
|   int64_t before_mem = rs_.get_mem_hold();
 | |
|   ASSERT_EQ(OB_SUCCESS, rs_.finish_add_row());
 | |
|   int64_t after_mem = rs_.get_mem_hold();
 | |
|   ASSERT_EQ(before_mem, after_mem);
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "scan");
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "get", 1000);
 | |
| 
 | |
| 
 | |
|   rs_.reset();
 | |
|   ret = rs_.init(0, tenant_id_, ctx_id_, label_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   rs_.set_mem_limit(50L << 20);
 | |
|   enable_big_row_ = true;
 | |
| 
 | |
|   for (int64_t i = 0; i < 1000; i++) {
 | |
|     CALL(append_rows, 1000);
 | |
|     if (rs_.get_file_size() > 0) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   before_mem = rs_.get_mem_hold();
 | |
|   ASSERT_EQ(OB_SUCCESS, rs_.finish_add_row());
 | |
|   after_mem = rs_.get_mem_hold();
 | |
|   ASSERT_GT(before_mem, after_mem);
 | |
| 
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "rscan");
 | |
|   CALL(verify_rows, 0, rs_.get_row_cnt(), "get", 1000);
 | |
| }
 | |
| 
 | |
| TEST_F(TestRARowStore, multi_reader)
 | |
| {
 | |
|   rs_.set_mem_limit(50L << 20);
 | |
|   CALL(append_rows, 10000);
 | |
| 
 | |
|   ObRARowStore::Reader reader0(rs_);
 | |
|   ObRARowStore::Reader reader1(rs_);
 | |
|   ObRARowStore::Reader reader2(rs_);
 | |
| 
 | |
|   ObRARowStore::Reader *readers[] = { &reader0, &reader1, &reader2 };
 | |
|   for (int64_t i = 0; i < 10000; ++i) {
 | |
|     int64_t row_id = random() % rs_.get_row_cnt();
 | |
|     CALL(verify_row, rs_, row_id);
 | |
|     for (int64_t j = 0; j < sizeof(readers) / sizeof(readers[0]); ++j) {
 | |
|       row_id = random() % rs_.get_row_cnt();
 | |
|       CALL(verify_row, *readers[j], row_id);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   int round = 1;
 | |
|   while (round > 0) {
 | |
|     append_rows(10000);
 | |
|     if (rs_.get_file_size() <= 0) {
 | |
|       round++;
 | |
|     } else {
 | |
|       round--;
 | |
|     }
 | |
|     if (round > 1000) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   ASSERT_GT(rs_.get_file_size(), 0);
 | |
| 
 | |
|   for (int64_t i = 0; i < 1000; ++i) {
 | |
|     int64_t row_id = random() % rs_.get_row_cnt();
 | |
|     CALL(verify_row, rs_, row_id);
 | |
|     for (int64_t j = 0; j < sizeof(readers) / sizeof(readers[0]); ++j) {
 | |
|       row_id = random() % rs_.get_row_cnt();
 | |
|       CALL(verify_row, *readers[j], row_id);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (int64_t i = 0; i < rs_.get_row_cnt(); ++i) {
 | |
|     CALL(verify_row, *readers[0], i);
 | |
|     CALL(verify_row, *readers[1], rs_.get_row_cnt() - 1 - i);
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(TestRARowStore, reuse)
 | |
| {
 | |
|   rs_.set_mem_limit(50L << 20);
 | |
|   rs_.reuse();
 | |
|   CALL(append_rows, 10000);
 | |
| 
 | |
|   ObRARowStore::Reader reader(rs_);
 | |
| 
 | |
|   for (int64_t i = 0; i < 10000; ++i) {
 | |
|     int64_t row_id = random() % rs_.get_row_cnt();
 | |
|     CALL(verify_row, rs_, row_id);
 | |
|     row_id = random() % rs_.get_row_cnt();
 | |
|     if (random() & 1) {
 | |
|       CALL(verify_row, reader, row_id);
 | |
|     } else {
 | |
|       CALL(verify_row, rs_, row_id);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   rs_.reuse();
 | |
|   reader.reuse();
 | |
|   ASSERT_EQ(0, rs_.get_row_cnt());
 | |
|   ASSERT_LT(16 << 10, rs_.get_mem_hold());
 | |
|   CALL(append_rows, 10000);
 | |
|   for (int64_t i = 0; i < 10000; ++i) {
 | |
|     int64_t row_id = random() % rs_.get_row_cnt();
 | |
|     CALL(verify_row, rs_, row_id);
 | |
|     row_id = random() % rs_.get_row_cnt();
 | |
|     if (random() & 1) {
 | |
|       CALL(verify_row, reader, row_id);
 | |
|     } else {
 | |
|       CALL(verify_row, rs_, row_id);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   int round = 1;
 | |
|   while (round > 0) {
 | |
|     append_rows(10000);
 | |
|     if (rs_.get_file_size() <= 0) {
 | |
|       round++;
 | |
|     } else {
 | |
|       round--;
 | |
|     }
 | |
|     if (round > 1000) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (int64_t i = 0; i < 1000; ++i) {
 | |
|     int64_t row_id = random() % rs_.get_row_cnt();
 | |
|     CALL(verify_row, rs_, row_id);
 | |
|     row_id = random() % rs_.get_row_cnt();
 | |
|     if (random() & 1) {
 | |
|       CALL(verify_row, reader, row_id);
 | |
|     } else {
 | |
|       CALL(verify_row, rs_, row_id);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   rs_.reuse();
 | |
|   reader.reuse();
 | |
|   ASSERT_EQ(0, rs_.get_file_size());
 | |
|   ASSERT_EQ(0, rs_.get_row_cnt());
 | |
| 
 | |
|   CALL(append_rows, 10000);
 | |
| 
 | |
|   for (int64_t i = 0; i < 1000; ++i) {
 | |
|     int64_t row_id = random() % rs_.get_row_cnt();
 | |
|     CALL(verify_row, rs_, row_id);
 | |
|     row_id = random() % rs_.get_row_cnt();
 | |
|     if (random() & 1) {
 | |
|       CALL(verify_row, reader, row_id);
 | |
|     } else {
 | |
|       CALL(verify_row, rs_, row_id);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(TestRARowStore, start_dump_by_total_mem_used)
 | |
| {
 | |
|   int ret = OB_SUCCESS;
 | |
|   append_rows(500000);
 | |
|   int64_t avg_row_size = rs_.get_mem_hold() / rs_.get_row_cnt();
 | |
|   LOG_INFO("average row size", K(avg_row_size));
 | |
| 
 | |
|   lib::ObMallocAllocator *malloc_allocator = lib::ObMallocAllocator::get_instance();
 | |
|   malloc_allocator->set_tenant_limit(OB_SYS_TENANT_ID, 1L << 30);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
|   // 50MB for work area
 | |
|   ret = lib::set_wa_limit(OB_SYS_TENANT_ID, 5);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   rs_.reset();
 | |
|   ret = rs_.init(0, tenant_id_, ctx_id_, label_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
| 
 | |
|   // case1: trigger dump by memory mod usage (60% of limit, 30MB)
 | |
|   // write 28MB, all in memory
 | |
|   CALL(append_rows, (28L << 20) / avg_row_size);
 | |
|   ASSERT_EQ(rs_.get_file_size(), 0);
 | |
| 
 | |
|   // append 10MB, need dump
 | |
|   CALL(append_rows, (10L << 20) / avg_row_size);
 | |
|   ASSERT_GT(rs_.get_file_size(), 0);
 | |
| 
 | |
|   rs_.reset();
 | |
|   ret = rs_.init(0, tenant_id_, ctx_id_, label_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   // case2: trigger dump by memory ctx usage (80% of limit, 40MB)
 | |
|   ObMemAttr attr = default_memattr;
 | |
|   attr.tenant_id_ = tenant_id_;
 | |
|   attr.ctx_id_ = ctx_id_;
 | |
|   // memory ctx hold 20MB
 | |
|   void *mem = ob_malloc(20L << 20, attr);
 | |
| 
 | |
|   // write 15MB, in memory
 | |
|   CALL(append_rows, (15L << 20) / avg_row_size);
 | |
|   ASSERT_EQ(rs_.get_file_size(), 0);
 | |
| 
 | |
|   // append 10MB, need dump
 | |
|   CALL(append_rows, (10L << 20) / avg_row_size);
 | |
|   ASSERT_GT(rs_.get_file_size(), 0);
 | |
| 
 | |
|   ob_free(mem);
 | |
| 
 | |
|   // case3: write to disk disabled
 | |
|   // write 40MB, all in memmory
 | |
|   GCONF.enable_sql_operator_dump.set_value("False");
 | |
|   rs_.reset();
 | |
|   ret = rs_.init(0, tenant_id_, ctx_id_, label_);
 | |
|   ASSERT_EQ(OB_SUCCESS, ret);
 | |
| 
 | |
|   CALL(append_rows, (40L << 20) / avg_row_size);
 | |
|   ASSERT_EQ(rs_.get_file_size(), 0);
 | |
| 
 | |
|   // append 20MB, exceed work area
 | |
|   int64_t rows = (100L << 20) / avg_row_size;
 | |
|   int64_t idx = 0;
 | |
|   int64_t base = rs_.get_row_cnt();
 | |
|   for (; idx < rows; idx++) {
 | |
|     if (OB_SUCCESS != rs_.add_row(gen_row(base + idx))) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   ASSERT_LT(idx, rows);
 | |
| 
 | |
|   lib::ObMallocAllocator::get_instance()->print_tenant_ctx_memory_usage(tenant_id_);
 | |
|   lib::ObMallocAllocator::get_instance()->print_tenant_memory_usage(tenant_id_);
 | |
| 
 | |
|   ASSERT_EQ(rs_.get_file_size(), 0);
 | |
| }
 | |
| 
 | |
| } // end namespace sql
 | |
| } // end namespace oceanbase
 | |
| 
 | |
| 
 | |
| void ignore_sig(int sig)
 | |
| {
 | |
|   UNUSED(sig);
 | |
| }
 | |
| 
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
|   signal(49, ignore_sig);
 | |
|   oceanbase::common::ObLogger::get_logger().set_log_level("TRACE");
 | |
|   testing::InitGoogleTest(&argc, argv);
 | |
|   auto *env = new (oceanbase::sql::TestEnv);
 | |
|   testing::AddGlobalTestEnvironment(env);
 | |
|   int ret = RUN_ALL_TESTS();
 | |
|   OB_LOGGER.disable();
 | |
|   return ret;
 | |
| }
 | 
