diff --git a/src/storage/tx/ob_dup_table_base.cpp b/src/storage/tx/ob_dup_table_base.cpp index cd1dd3eef..a253981f2 100644 --- a/src/storage/tx/ob_dup_table_base.cpp +++ b/src/storage/tx/ob_dup_table_base.cpp @@ -38,6 +38,11 @@ const int64_t DupTableDiagStd::DUP_DIAG_PRINT_INTERVAL[DupTableDiagStd::TypeInde 3 * 60 * 1000 * 1000 // 3min , ts_sync_print_interval }; + +const int64_t ObDupTableLogOperator::MAX_LOG_BLOCK_SIZE=common::OB_MAX_LOG_ALLOWED_SIZE; +const int64_t ObDupTableLogOperator::RESERVED_LOG_HEADER_SIZE = 100; + + /******************************************************* * Dup_Table LS Role State *******************************************************/ @@ -736,6 +741,7 @@ int ObDupTableLogOperator::prepare_serialize_log_entry_(int64_t &max_ser_size, ret = OB_INVALID_ARGUMENT; DUP_TABLE_LOG(WARN, "invalid block buf", K(ret), K(big_segment_buf_)); } else { + if (OB_SUCC(ret)) { origin_max_ser_size = max_ser_size; if (OB_FAIL(lease_mgr_ptr_->prepare_serialize(max_ser_size, logging_lease_addrs_))) { @@ -745,9 +751,10 @@ int ObDupTableLogOperator::prepare_serialize_log_entry_(int64_t &max_ser_size, DUP_TABLE_LOG(WARN, "push back log entry type failed", K(ret)); } } + if (OB_SUCC(ret)) { origin_max_ser_size = max_ser_size; - int64_t max_log_buf_size = MAX_LOG_BLOCK_SIZE - max_stat_log.get_serialize_size(); + int64_t max_log_buf_size = MAX_LOG_BLOCK_SIZE - RESERVED_LOG_HEADER_SIZE - max_stat_log.get_serialize_size(); if (OB_FAIL(tablet_mgr_ptr_->prepare_serialize(max_ser_size, logging_tablet_set_ids_, max_log_buf_size))) { DUP_TABLE_LOG(WARN, "prepare serialize tablets_mgr failed", K(ret)); @@ -785,10 +792,10 @@ int ObDupTableLogOperator::serialize_log_entry_(const int64_t max_ser_size, { int ret = OB_SUCCESS; - if (max_ser_size > MAX_LOG_BLOCK_SIZE) { + if (max_ser_size > MAX_LOG_BLOCK_SIZE - RESERVED_LOG_HEADER_SIZE) { ret = OB_LOG_TOO_LARGE; DUP_TABLE_LOG(WARN, "serialize buf is not enough for a big log", K(ls_id_), K(max_ser_size), - K(type_array)); + K(type_array), K(MAX_LOG_BLOCK_SIZE),K(RESERVED_LOG_HEADER_SIZE)); } else if (OB_FAIL(big_segment_buf_.init_for_serialize(max_ser_size))) { DUP_TABLE_LOG(WARN, "init big_segment_buf_ failed", K(ret), K(max_ser_size), K(big_segment_buf_)); @@ -932,7 +939,7 @@ int ObDupTableLogOperator::deserialize_log_entry_() } if (OB_SUCC(ret) && data_pos < after_header_pos + log_entry_size) { - DUP_TABLE_LOG(INFO, "try to deserialize a new version log", K(ret), K(data_pos), + DUP_TABLE_LOG(INFO, "try to deserialize a new version dup_table log in older observer", K(ret), K(data_pos), K(after_header_pos), K(log_entry_size), K(entry_header)); data_pos = after_header_pos + log_entry_size; } @@ -982,6 +989,10 @@ int ObDupTableLogOperator::retry_submit_log_block_() block_buf_pos, unused))) { DUP_TABLE_LOG(WARN, "split one part of segment failed", K(ret), K(big_segment_buf_), K(block_buf_pos)); + } else if (OB_FAIL(!big_segment_buf_.is_completed())) { + ret = OB_LOG_TOO_LARGE; + DUP_TABLE_LOG(WARN, "Too large dup table log. We can not submit it", K(ret), + K(big_segment_buf_.is_completed()), KPC(this)); } else if (OB_FAIL(log_handler_->append(block_buf_, block_buf_pos, share::SCN::min_scn(), false, this, logging_lsn_, logging_scn_))) { DUP_TABLE_LOG(WARN, "append block failed", K(ret), K(ls_id_)); diff --git a/src/storage/tx/ob_dup_table_base.h b/src/storage/tx/ob_dup_table_base.h index 8c0632c48..38544cc81 100644 --- a/src/storage/tx/ob_dup_table_base.h +++ b/src/storage/tx/ob_dup_table_base.h @@ -969,7 +969,8 @@ public: K(logging_lsn_)); private: - static const int64_t MAX_LOG_BLOCK_SIZE = common::OB_MAX_LOG_ALLOWED_SIZE; + static const int64_t MAX_LOG_BLOCK_SIZE ; + static const int64_t RESERVED_LOG_HEADER_SIZE ; //100 Byte int prepare_serialize_log_entry_(int64_t &max_ser_size, DupLogTypeArray &type_array); int serialize_log_entry_(const int64_t max_ser_size, const DupLogTypeArray &type_array); int deserialize_log_entry_(); diff --git a/src/storage/tx/ob_dup_table_tablets.cpp b/src/storage/tx/ob_dup_table_tablets.cpp index 0a05b4bf5..02de8ae0f 100644 --- a/src/storage/tx/ob_dup_table_tablets.cpp +++ b/src/storage/tx/ob_dup_table_tablets.cpp @@ -757,22 +757,6 @@ int ObLSDupTabletsMgr::prepare_serialize(int64_t &max_ser_size, // max_ser_size = 0; unique_id_array.reuse(); - if (OB_SUCC(ret)) { - if (OB_ISNULL(changing_new_set_)) { - // do nothing - } else if (changing_new_set_->empty()) { - // empty change map not need add to need confirm and ser - DUP_TABLE_LOG(DEBUG, "changing_new_set_ is empty", K(ret), K(changing_new_set_->empty())); - } else if (OB_FAIL(changing_new_set_->get_change_status()->prepare_serialize())) { - DUP_TABLE_LOG(WARN, "changing new set prepare serialize failed", K(ret)); - } else if (false == need_confirm_new_queue_.add_last(changing_new_set_)) { - ret = OB_ERR_UNEXPECTED; - DUP_TABLE_LOG(WARN, "push back change_new_set_ failed", K(ret)); - } else if (OB_FALSE_IT(changing_new_set_ = nullptr)) { - // do nothing - } - } - if (OB_SUCC(ret)) { bool can_be_confirmed = true; DLIST_FOREACH(cur_map, need_confirm_new_queue_) @@ -782,10 +766,11 @@ int ObLSDupTabletsMgr::prepare_serialize(int64_t &max_ser_size, DUP_TABLE_LOG(ERROR, "unexpected tablet set type", K(ret), KPC(cur_map)); } else if (!cur_map->get_change_status()->need_log()) { DUP_TABLE_LOG(INFO, "no need serialize need_confirm_set in log", K(ret), KPC(cur_map)); + } else if (OB_FAIL(cal_single_set_max_ser_size_(cur_map, max_ser_size, max_log_buf_len, + unique_id_array))) { + DUP_TABLE_LOG(WARN, "cal new set max ser_size failed", K(ret)); } else if (OB_FALSE_IT(cur_map->set_logging())) { // do nothing - } else if (OB_FAIL(cal_single_set_max_ser_size_(cur_map, max_ser_size, unique_id_array))) { - DUP_TABLE_LOG(WARN, "cal new set max ser_size failed", K(ret)); } else { int64_t tmp_ret = OB_SUCCESS; if (OB_TMP_FAIL(cur_map->get_change_status()->try_set_confirmed(can_be_confirmed))) { @@ -800,6 +785,31 @@ int ObLSDupTabletsMgr::prepare_serialize(int64_t &max_ser_size, } } + if (OB_SUCC(ret)) { + if (OB_ISNULL(changing_new_set_)) { + // do nothing + } else if (changing_new_set_->empty()) { + // empty change map not need add to need confirm and ser + DUP_TABLE_LOG(DEBUG, "changing_new_set_ is empty", K(ret), K(changing_new_set_->empty())); + } else if (OB_FAIL(cal_single_set_max_ser_size_(changing_new_set_, max_ser_size, + max_log_buf_len, unique_id_array))) { + DUP_TABLE_LOG(WARN, "cal new set max ser_size failed", K(ret)); + if (OB_SIZE_OVERFLOW == ret) { + ret = OB_LOG_TOO_LARGE; + } + } else if (OB_FALSE_IT(changing_new_set_->set_logging())) { + // do nothing + + } else if (OB_FAIL(changing_new_set_->get_change_status()->prepare_serialize())) { + DUP_TABLE_LOG(WARN, "changing new set prepare serialize failed", K(ret)); + } else if (false == need_confirm_new_queue_.add_last(changing_new_set_)) { + ret = OB_ERR_UNEXPECTED; + DUP_TABLE_LOG(WARN, "push back change_new_set_ failed", K(ret)); + } else if (OB_FALSE_IT(changing_new_set_ = nullptr)) { + // do nothing + } + } + if (OB_SUCC(ret)) { if (max_ser_size > max_log_buf_len) { ret = OB_LOG_TOO_LARGE; @@ -820,11 +830,14 @@ int ObLSDupTabletsMgr::prepare_serialize(int64_t &max_ser_size, // do nothing } else if (!old_tablet_set->get_change_status()->need_log()) { DUP_TABLE_LOG(INFO, "no need serialize old tablets in log", K(ret), KPC(old_tablet_set)); - } else if (OB_FALSE_IT(old_tablet_set->set_logging())) { - // do nothing - } else if (OB_FAIL( - cal_single_set_max_ser_size_(old_tablet_set, max_ser_size, unique_id_array))) { + } else if (OB_FAIL(cal_single_set_max_ser_size_(old_tablet_set, max_ser_size, max_log_buf_len, + unique_id_array))) { DUP_TABLE_LOG(WARN, "cal old set max ser_size failed", K(ret)); + if (OB_SIZE_OVERFLOW == ret) { + ret = OB_LOG_TOO_LARGE; + } + } else if (OB_FALSE_IT(old_tablet_set->set_logging())) { + // do nothing } else if (OB_FAIL(old_tablet_set->get_change_status()->prepare_serialize())) { DUP_TABLE_LOG(WARN, "old set prepare serialize failed", K(ret)); } else { @@ -843,14 +856,21 @@ int ObLSDupTabletsMgr::prepare_serialize(int64_t &max_ser_size, if (OB_SUCC(ret)) { DLIST_FOREACH(readable_ptr, readable_tablets_list_) { - readable_ptr->set_logging(); - if (OB_FAIL(cal_single_set_max_ser_size_(readable_ptr, max_ser_size, unique_id_array))) { + if (OB_FAIL(cal_single_set_max_ser_size_(readable_ptr, max_ser_size, max_log_buf_len, + unique_id_array))) { DUP_TABLE_LOG(WARN, "cal readable set max ser_size failed", K(ret)); + if (OB_SIZE_OVERFLOW == ret) { + ret = OB_LOG_TOO_LARGE; + } + } else { + readable_ptr->set_logging(); } } } if (OB_LOG_TOO_LARGE == ret) { + DUP_TABLE_LOG(INFO, "Too many dup tablets, we can not submit all", K(ret), K(max_ser_size), + K(max_log_buf_len), K(unique_id_array)); ret = OB_SUCCESS; } DUP_TABLE_LOG(DEBUG, "finish prepare ser", K(ret), K(max_ser_size), K(unique_id_array)); @@ -1137,6 +1157,7 @@ int ObLSDupTabletsMgr::tablet_log_synced(const bool sync_result, int ObLSDupTabletsMgr::cal_single_set_max_ser_size_(DupTabletChangeMap *hash_map, int64_t &max_ser_size, + const int64_t ser_size_limit, DupTabletSetIDArray &unique_id_array) { int ret = OB_SUCCESS; @@ -1150,6 +1171,10 @@ int ObLSDupTabletsMgr::cal_single_set_max_ser_size_(DupTabletChangeMap *hash_map if (OB_FAIL(ret)) { // do nothing + } else if (max_ser_size + tmp_ser_size > ser_size_limit) { + ret = OB_SIZE_OVERFLOW; + DUP_TABLE_LOG(WARN, "the serialize size of tablet sets is too large", K(ret), K(max_ser_size), + K(tmp_ser_size), K(ser_size_limit), K(unique_id_array), KPC(hash_map)); } else if (OB_FAIL(unique_id_array.push_back(hash_map->get_common_header()))) { DUP_TABLE_LOG(WARN, "push back unique_id array failed", K(ret)); } else { @@ -1724,9 +1749,15 @@ int ObLSDupTabletsMgr::discover_dup_tablet_(const common::ObTabletID &tablet_id, INFO, "Too large confirming tablet set. We will not insert new tablet into changing_new_set_.", K(ret), K(ls_id_), K(changing_new_set_->size()), K(confirming_tablet_cnt), - K(MAX_CONFIRMING_TABLET_COUNT), K(contain_confirming_special_op)); + K(MAX_CONFIRMING_TABLET_COUNT), K(contain_confirming_special_op), + K(need_confirm_new_queue_.get_size()), KPC(removing_old_set_), + K(readable_tablets_list_.get_size())); } else if (OB_FAIL(changing_new_map->set_refactored(tablet_id, tmp_status, 1))) { DUP_TABLE_LOG(WARN, "insert into changing new tablets failed", K(ret)); + } else { + DUP_TABLE_LOG(INFO, "insert a new dup tablet into set", K(ret), K(tablet_id), + KPC(changing_new_set_), K(need_confirm_new_queue_.get_size()), + KPC(removing_old_set_), K(readable_tablets_list_.get_size())); } } diff --git a/src/storage/tx/ob_dup_table_tablets.h b/src/storage/tx/ob_dup_table_tablets.h index f99cf28b1..968b4cb39 100644 --- a/src/storage/tx/ob_dup_table_tablets.h +++ b/src/storage/tx/ob_dup_table_tablets.h @@ -154,8 +154,8 @@ public: bool is_confirming() const { return flag_ == DupTabletSetChangeFlag::CONFIRMING; } bool can_be_confirmed_anytime() const { - return (trx_ref_ == 0 && readable_version_ >= need_confirm_scn_ - && flag_ == DupTabletSetChangeFlag::CONFIRMING) + return (trx_ref_ == 0 && readable_version_ >= need_confirm_scn_ && readable_version_.is_valid() + && need_confirm_scn_.is_valid() && flag_ == DupTabletSetChangeFlag::CONFIRMING) || flag_ == DupTabletSetChangeFlag::CONFIRMED; } bool has_confirmed() const { return DupTabletSetChangeFlag::CONFIRMED == flag_; } @@ -698,6 +698,7 @@ private: int cal_single_set_max_ser_size_(DupTabletChangeMap *hash_map, int64_t &max_ser_size, + const int64_t ser_size_limit, DupTabletSetIDArray &id_array); int merge_into_readable_tablets_(DupTabletChangeMap *change_map_ptr, const bool for_replay); diff --git a/src/storage/tx/ob_dup_table_util.cpp b/src/storage/tx/ob_dup_table_util.cpp index c81da67a4..610575e7a 100644 --- a/src/storage/tx/ob_dup_table_util.cpp +++ b/src/storage/tx/ob_dup_table_util.cpp @@ -92,6 +92,7 @@ int ObDupTabletScanTask::refresh_dup_tablet_schema_( dup_ls_status_info))) { if (OB_ENTRY_NOT_EXIST == ret) { DUP_TABLE_LOG(DEBUG, "no duplicate ls", K(dup_ls_status_info)); + ret = OB_SUCCESS; } else { DUP_TABLE_LOG(WARN, "get duplicate ls status info failed", K(ret), K(dup_ls_status_info)); }