[OBCDC] various bug fix
This commit is contained in:
@ -88,6 +88,7 @@ void ObCdcService::run1()
|
|||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int64_t tenant_id = MTL_ID();
|
int64_t tenant_id = MTL_ID();
|
||||||
|
lib::set_thread_name("CdcSrv");
|
||||||
if (IS_NOT_INIT) {
|
if (IS_NOT_INIT) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
EXTLOG_LOG(ERROR, "ObCdcService is not initialized", KR(ret));
|
EXTLOG_LOG(ERROR, "ObCdcService is not initialized", KR(ret));
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
* OBCDC Instance
|
* OBCDC Instance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lib/ob_errno.h"
|
|
||||||
#define USING_LOG_PREFIX OBLOG
|
#define USING_LOG_PREFIX OBLOG
|
||||||
|
|
||||||
#include "ob_log_instance.h"
|
#include "ob_log_instance.h"
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
#include "ob_log_callback.h" // ObILogCallback
|
#include "ob_log_callback.h" // ObILogCallback
|
||||||
#include "ob_cdc_lob_ctx.h" // ObLobDataOutRowCtxList
|
#include "ob_cdc_lob_ctx.h" // ObLobDataOutRowCtxList
|
||||||
#include "ob_cdc_lob_aux_table_schema_info.h" // ObCDCLobAuxTableSchemaInfo
|
#include "ob_cdc_lob_aux_table_schema_info.h" // ObCDCLobAuxTableSchemaInfo
|
||||||
|
#include "ob_log_safe_arena.h"
|
||||||
|
|
||||||
namespace oceanbase
|
namespace oceanbase
|
||||||
{
|
{
|
||||||
@ -715,9 +716,9 @@ private:
|
|||||||
int64_t formatted_stmt_num_; // Number of statements that formatted
|
int64_t formatted_stmt_num_; // Number of statements that formatted
|
||||||
int64_t row_ref_cnt_; // reference count
|
int64_t row_ref_cnt_; // reference count
|
||||||
|
|
||||||
// Non-thread safe allocator
|
// thread safe allocator
|
||||||
// used for Parser/Formatter
|
// used for Parser/Formatter/LobDataMerger
|
||||||
common::ObArenaAllocator arena_allocator_; // allocator
|
ObCdcSafeArena arena_allocator_; // allocator
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(ObLogEntryTask);
|
DISALLOW_COPY_AND_ASSIGN(ObLogEntryTask);
|
||||||
|
|||||||
93
src/logservice/libobcdc/src/ob_log_safe_arena.h
Normal file
93
src/logservice/libobcdc/src/ob_log_safe_arena.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A Smaller Thread-Safe Arena Allocator for libobcdc
|
||||||
|
|
||||||
|
#ifndef OCEANBASE_LIBOBCDC_OB_LOG_SAFE_ARENA_
|
||||||
|
#define OCEANBASE_LIBOBCDC_OB_LOG_SAFE_ARENA_
|
||||||
|
|
||||||
|
#include "lib/allocator/ob_allocator.h"
|
||||||
|
#include "lib/allocator/page_arena.h"
|
||||||
|
#include "lib/lock/ob_small_spin_lock.h"
|
||||||
|
|
||||||
|
namespace oceanbase
|
||||||
|
{
|
||||||
|
namespace libobcdc
|
||||||
|
{
|
||||||
|
|
||||||
|
class ObCdcSafeArena: public common::ObIAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ObCdcSafeArena(const lib::ObLabel &label = ObModIds::OB_MODULE_PAGE_ALLOCATOR,
|
||||||
|
const int64_t page_size = OB_MALLOC_NORMAL_BLOCK_SIZE,
|
||||||
|
int64_t tenant_id = OB_SERVER_TENANT_ID,
|
||||||
|
int64_t ctx_id = 0) :
|
||||||
|
arena_(label, page_size, tenant_id, ctx_id),
|
||||||
|
lock_() {}
|
||||||
|
virtual ~ObCdcSafeArena() {}
|
||||||
|
virtual void *alloc(const int64_t size) override
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
return arena_.alloc(size);
|
||||||
|
}
|
||||||
|
virtual void* alloc(const int64_t size, const ObMemAttr &attr)
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
return arena_.alloc(size, attr);
|
||||||
|
}
|
||||||
|
virtual void free(void *ptr) override
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
arena_.free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void clear()
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
arena_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int64_t total() const override
|
||||||
|
{
|
||||||
|
return arena_.total();
|
||||||
|
}
|
||||||
|
virtual int64_t used() const override
|
||||||
|
{
|
||||||
|
return arena_.used();
|
||||||
|
}
|
||||||
|
virtual void reset() override
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
arena_.reset();
|
||||||
|
}
|
||||||
|
virtual void reuse() override
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
arena_.reuse();
|
||||||
|
}
|
||||||
|
virtual void set_attr(const ObMemAttr &attr) override
|
||||||
|
{
|
||||||
|
ObByteLockGuard guard(lock_);
|
||||||
|
arena_.set_attr(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ObArenaAllocator arena_;
|
||||||
|
ObByteLock lock_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -322,6 +322,7 @@ int ObLogSequencer::handle_to_be_sequenced_trans_(TrxSortElem &trx_sort_elem,
|
|||||||
uint64_t tenant_id = OB_INVALID_TENANT_ID;
|
uint64_t tenant_id = OB_INVALID_TENANT_ID;
|
||||||
ObLogTenantGuard guard;
|
ObLogTenantGuard guard;
|
||||||
ObLogTenant *tenant = NULL;
|
ObLogTenant *tenant = NULL;
|
||||||
|
const ObTransID trans_id = trans_ctx->get_trans_id();
|
||||||
|
|
||||||
if (OB_FAIL(trans_ctx->get_tenant_id(tenant_id))) {
|
if (OB_FAIL(trans_ctx->get_tenant_id(tenant_id))) {
|
||||||
LOG_ERROR("trans_ctx get_tenant_id fail", KR(ret), K(tenant_id));
|
LOG_ERROR("trans_ctx get_tenant_id fail", KR(ret), K(tenant_id));
|
||||||
@ -360,6 +361,7 @@ int ObLogSequencer::handle_to_be_sequenced_trans_(TrxSortElem &trx_sort_elem,
|
|||||||
monitor.mark_and_get_cost("dml-done", true);
|
monitor.mark_and_get_cost("dml-done", true);
|
||||||
} // while
|
} // while
|
||||||
} else if (is_ddl_trans){
|
} else if (is_ddl_trans){
|
||||||
|
trans_ctx->set_trans_redo_dispatched();
|
||||||
// need sort_participants = on, which make sure the first PartTransTask of
|
// need sort_participants = on, which make sure the first PartTransTask of
|
||||||
// participant_list is DDL_TRANS.
|
// participant_list is DDL_TRANS.
|
||||||
// TODO: consider more idea to handle this.
|
// TODO: consider more idea to handle this.
|
||||||
@ -378,7 +380,7 @@ int ObLogSequencer::handle_to_be_sequenced_trans_(TrxSortElem &trx_sort_elem,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("handle_to_be_sequenced_trans_ end", KR(ret), KPC(trans_ctx));
|
LOG_DEBUG("handle_to_be_sequenced_trans_ end", KR(ret), K(trans_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@ -564,10 +564,9 @@ int ObBinlogRecordPrinter::output_data_file_column_data(IBinlogRecord *br,
|
|||||||
ROW_PRINTF(ptr, size, pos, ri, "[C%ld] column_extend_info:%s", column_index, enum_set_values_str.c_str());
|
ROW_PRINTF(ptr, size, pos, ri, "[C%ld] column_extend_info:%s", column_index, enum_set_values_str.c_str());
|
||||||
}
|
}
|
||||||
// print precision & scale only in print detail mode, becacuse INT in oracle mode is also a kind of NUMBER(DECIMAL)
|
// print precision & scale only in print detail mode, becacuse INT in oracle mode is also a kind of NUMBER(DECIMAL)
|
||||||
// whose precision is 38 and scale is 0, more importantly, the default precision(-1, PRECISION_UNKNOWN_YET)
|
// whose precision is 38 and scale is 0
|
||||||
// and scale(-85, ORA_NUMBER_SCALE_UNKNOWN_YET) of NUMBER in oracle mode is confusing, so we decide not to
|
// the default value of precision is -1(PRECISION_UNKNOWN_YET) and the default value of scale is -85
|
||||||
// modify test results for oracle mode temporarily for convenience and efficiency.
|
// (ORA_NUMBER_SCALE_UNKNOWN_YET), when using default precision & scale, the number type would behave adaptively
|
||||||
// TODO
|
|
||||||
else if ((oceanbase::obmysql::MYSQL_TYPE_DECIMAL == ctype) || (oceanbase::obmysql::MYSQL_TYPE_NEWDECIMAL == ctype)) {
|
else if ((oceanbase::obmysql::MYSQL_TYPE_DECIMAL == ctype) || (oceanbase::obmysql::MYSQL_TYPE_NEWDECIMAL == ctype)) {
|
||||||
// Not sure if MYSQL_TYPE_DECIMAL is deprecated, DECIMAL in mysql & oracle mode should be MYSQL_TYPE_NEWDECIMAL
|
// Not sure if MYSQL_TYPE_DECIMAL is deprecated, DECIMAL in mysql & oracle mode should be MYSQL_TYPE_NEWDECIMAL
|
||||||
ROW_PRINTF(ptr, size, pos , ri, "[C%ld] column_precision:%ld", column_index, precision);
|
ROW_PRINTF(ptr, size, pos , ri, "[C%ld] column_precision:%ld", column_index, precision);
|
||||||
|
|||||||
@ -29,3 +29,4 @@ libobcdc_unittest(test_ob_seq_thread)
|
|||||||
libobcdc_unittest(test_ob_cdc_part_trans_resolver)
|
libobcdc_unittest(test_ob_cdc_part_trans_resolver)
|
||||||
libobcdc_unittest(test_log_svr_blacklist)
|
libobcdc_unittest(test_log_svr_blacklist)
|
||||||
libobcdc_unittest(test_ob_cdc_sorted_list)
|
libobcdc_unittest(test_ob_cdc_sorted_list)
|
||||||
|
libobcdc_unittest(test_ob_log_safe_arena)
|
||||||
|
|||||||
70
unittest/libobcdc/test_ob_log_safe_arena.cpp
Normal file
70
unittest/libobcdc/test_ob_log_safe_arena.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib/oblog/ob_log.h"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "ob_log_safe_arena.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace oceanbase
|
||||||
|
{
|
||||||
|
namespace libobcdc
|
||||||
|
{
|
||||||
|
|
||||||
|
bool check_memset(const void *ptr, const char c, const int64_t size) {
|
||||||
|
bool bret = true;
|
||||||
|
const char *cptr = static_cast<const char*>(ptr);
|
||||||
|
for (int i = 0; bret && i < size; i++) {
|
||||||
|
if (cptr[i] != c) {
|
||||||
|
bret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bret;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ObLogSafeArena, test_ob_log_safe_arena)
|
||||||
|
{
|
||||||
|
ObCdcSafeArena safe_arena;
|
||||||
|
const int64_t THREAD_NUM = 32;
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
auto alloc_test_func = [&](int idx) {
|
||||||
|
constexpr int64_t ALLOC_CNT = 1024;
|
||||||
|
constexpr int64_t ALLOC_SIZE = 1024;
|
||||||
|
ObRandom rand;
|
||||||
|
char c = static_cast<char>(idx & 0xFF);
|
||||||
|
for (int i = 0; i < ALLOC_CNT; i++) {
|
||||||
|
int64_t alloc_size = rand.get(1, ALLOC_SIZE);
|
||||||
|
void *ptr = safe_arena.alloc(alloc_size);
|
||||||
|
EXPECT_TRUE(NULL != ptr);
|
||||||
|
MEMSET(ptr, c, alloc_size);
|
||||||
|
EXPECT_TRUE(check_memset(ptr, c, alloc_size));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (int i = 0; i < THREAD_NUM; i++) {
|
||||||
|
threads.emplace_back(std::thread(alloc_test_func, i));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < THREAD_NUM; i++) {
|
||||||
|
threads[i].join();
|
||||||
|
}
|
||||||
|
safe_arena.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace libobcdc
|
||||||
|
} // ns oceanbase
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
oceanbase::common::ObLogger::get_logger().set_log_level("DEBUG");
|
||||||
|
OB_LOGGER.set_log_level("DEBUG");
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user