diff --git a/src/storage/lob/ob_lob_manager.cpp b/src/storage/lob/ob_lob_manager.cpp index 3edec2cb82..d37cef9807 100644 --- a/src/storage/lob/ob_lob_manager.cpp +++ b/src/storage/lob/ob_lob_manager.cpp @@ -802,7 +802,7 @@ int ObLobManager::compare(ObLobLocatorV2& lob_left, ObLobCompareParams& cmp_params, int64_t& result) { INIT_SUCC(ret); - ObArenaAllocator tmp_allocator(ObModIds::OB_LOB_READER, OB_MALLOC_MIDDLE_BLOCK_SIZE, MTL_ID()); + ObArenaAllocator tmp_allocator("ObLobCmp", OB_MALLOC_MIDDLE_BLOCK_SIZE, MTL_ID()); ObLobManager *lob_mngr = MTL(ObLobManager*); if (OB_ISNULL(lob_mngr)) { ret = OB_ERR_UNEXPECTED; @@ -2584,13 +2584,30 @@ int ObLobManager::write_outrow_inner(ObLobAccessParam& param, ObLobQueryIter *it // do append => [old_data][padding][data] post_data = old_data; } else { - // combine data and old data - // [old_data][data] + // here has four situation + // [old][new][old] --> cover part of old data + // [new_data][old_data] --> cover front part + // [old_data][new_data] --> cover back part + // [new_data] --> full cover old data int64_t offset_byte_len = ObCharset::charpos(param.coll_type_, old_data.ptr(), old_data.length(), param.offset_); - post_data.assign_ptr(old_data.ptr(), offset_byte_len); + if (offset_byte_len > 0) { // offset is not 0, must have some old data at front + post_data.assign_ptr(old_data.ptr(), offset_byte_len); + } + if (param.offset_ + param.len_ < old_char_len) { // not full cover, must have some old data at back + int64_t end_byte_len = ObCharset::charpos(param.coll_type_, + old_data.ptr(), + old_data.length(), + param.offset_ + param.len_); + if (end_byte_len >= old_data.length()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get byte len is bigger then data length", K(ret), K(end_byte_len), K(old_data.length()), K(param)); + } else { + remain_buf.assign_ptr(old_data.ptr() + end_byte_len, old_data.length() - end_byte_len); + } + } } } @@ -2867,6 +2884,8 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, read_data.length(), replace_byte_len, replace_byte_st); + } else { + replace_byte_len = OB_MIN(replace_byte_len, read_data.length() - replace_byte_st); } ObString temp_read_buf; uint32_t temp_read_size = ObLobMetaUtil::LOB_OPER_PIECE_DATA_SIZE - replace_byte_st; @@ -2894,6 +2913,7 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, // try copy data to meta int64_t max_byte = ObLobMetaUtil::LOB_OPER_PIECE_DATA_SIZE - replace_byte_st; int64_t data_char_len = 0; + max_byte = OB_MIN(max_byte, temp_read_buf.length()); size_t data_by_len = ObCharset::max_bytes_charpos(param.coll_type_, temp_read_buf.ptr(), temp_read_buf.length(), max_byte, data_char_len); data_by_len = ob_lob_writer_length_validation(param.coll_type_, temp_read_buf.length(), data_by_len, data_char_len); MEMCPY(read_data.ptr() + replace_byte_st, temp_read_buf.ptr(), data_by_len); @@ -2901,6 +2921,7 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, if (data_by_len == temp_read_buf.length()) { // try copy remain data to meta if data has copy fully max_byte = ObLobMetaUtil::LOB_OPER_PIECE_DATA_SIZE - read_data.length(); + max_byte = OB_MIN(max_byte, remain_data.length()); size_t rdata_by_len = ObCharset::max_bytes_charpos(param.coll_type_, remain_data.ptr(), remain_data.length(), max_byte, data_char_len); rdata_by_len = ob_lob_writer_length_validation(param.coll_type_, remain_data.length(), rdata_by_len, data_char_len); if (rdata_by_len >= remain_data.length()) { @@ -2927,6 +2948,8 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, read_data.length(), by_len, by_st); + } else { + by_len = OB_MIN(by_len, read_data.length() - by_st); } // [0, by_len][by_len, 256K] // try copy data to meta in [by_len, 256K] @@ -2953,6 +2976,7 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, } } else { int64_t data_char_len = 0; + max_byte = OB_MIN(max_byte, temp_read_buf.length()); size_t data_by_len = ObCharset::max_bytes_charpos(param.coll_type_, temp_read_buf.ptr(), temp_read_buf.length(), max_byte, data_char_len); data_by_len = ob_lob_writer_length_validation(param.coll_type_, temp_read_buf.length(), data_by_len, data_char_len); @@ -2970,6 +2994,8 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, read_data.length(), by_len, by_st); + } else { + by_len = OB_MIN(by_len, read_data.length() - by_st); } // calc data ObString temp_read_buf; @@ -2997,6 +3023,7 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, } else { // calc data int64_t data_char_len = 0; + max_byte = OB_MIN(max_byte, temp_read_buf.length()); size_t data_by_len = ObCharset::max_bytes_charpos(param.coll_type_, temp_read_buf.ptr(), temp_read_buf.length(), max_byte, data_char_len); data_by_len = ob_lob_writer_length_validation(param.coll_type_, temp_read_buf.length(), data_by_len, data_char_len); MEMMOVE(read_data.ptr() + data_by_len, read_data.ptr() + by_len, piece_byte_len - by_len); @@ -3047,6 +3074,7 @@ int ObLobManager::replace_process_meta_info(ObLobAccessParam& param, read_data.assign_buffer(tmp_buf.ptr(), tmp_buf.size()); int64_t data_char_len = 0; + max_byte = OB_MIN(max_byte, temp_read_buf.length()); size_t data_by_len = ObCharset::max_bytes_charpos(param.coll_type_, temp_read_buf.ptr(), temp_read_buf.length(), max_byte, data_char_len); data_by_len = ob_lob_writer_length_validation(param.coll_type_, temp_read_buf.length(), data_by_len, data_char_len); MEMCPY(read_data.ptr(), temp_read_buf.ptr(), data_by_len); @@ -3256,15 +3284,14 @@ int ObLobManager::erase_process_meta_info(ObLobAccessParam& param, ObLobMetaScan new_meta_row.byte_len_ = read_data.length(); } } else { + // here expect read_data read full lob meta data read_data.assign_buffer(tmp_buf, tmp_buff.size()); - if (OB_FAIL(get_real_data(param, result, read_data))) { - LOG_WARN("failed to write data to read buf.", K(ret), K(result)); - } else { - new_meta_row.byte_len_ -= (by_len); - new_meta_row.char_len_ -= (local_end - local_begin); - MEMMOVE(read_data.ptr() + by_st, read_data.ptr() + (by_st + by_len), piece_byte_len - (by_st + by_len)); - read_data.assign_ptr(read_data.ptr(), read_data.length() - by_len); - } + MEMCPY(read_data.ptr(), result.meta_result_.info_.lob_data_.ptr(), result.meta_result_.info_.lob_data_.length()); + read_data.set_length(result.meta_result_.info_.lob_data_.length()); + new_meta_row.byte_len_ -= (by_len); + new_meta_row.char_len_ -= (local_end - local_begin); + MEMMOVE(read_data.ptr() + by_st, read_data.ptr() + (by_st + by_len), piece_byte_len - (by_st + by_len)); + read_data.assign_ptr(read_data.ptr(), read_data.length() - by_len); } } else { del_piece = true; @@ -3319,15 +3346,14 @@ int ObLobManager::erase_process_meta_info(ObLobAccessParam& param, ObLobMetaScan new_meta_row.byte_len_ = read_data.length(); } } else { - read_data.assign_buffer(tmp_buf, result.meta_result_.info_.byte_len_); - if (OB_FAIL(get_real_data(param, result, read_data))) { - LOG_WARN("failed to write data to read buf.", K(ret), K(result)); - } else { - new_meta_row.char_len_ = piece_char_len - local_end; - new_meta_row.byte_len_ = read_data.length() - by_len; - MEMMOVE(read_data.ptr(), read_data.ptr() + by_len, read_data.length() - by_len); - read_data.assign_ptr(read_data.ptr(), read_data.length() - by_len); - } + // here expect read_data read full lob meta data + read_data.assign_buffer(tmp_buf, tmp_buff.size()); + MEMCPY(read_data.ptr(), result.meta_result_.info_.lob_data_.ptr(), result.meta_result_.info_.lob_data_.length()); + read_data.set_length(result.meta_result_.info_.lob_data_.length()); + new_meta_row.char_len_ = piece_char_len - local_end; + new_meta_row.byte_len_ = read_data.length() - by_len; + MEMMOVE(read_data.ptr(), read_data.ptr() + by_len, read_data.length() - by_len); + read_data.assign_ptr(read_data.ptr(), read_data.length() - by_len); } } } diff --git a/src/storage/lob/ob_lob_meta.cpp b/src/storage/lob/ob_lob_meta.cpp index daba2eff3c..1771f83412 100644 --- a/src/storage/lob/ob_lob_meta.cpp +++ b/src/storage/lob/ob_lob_meta.cpp @@ -424,6 +424,7 @@ ObLobMetaWriteIter::ObLobMetaWriteIter(ObIAllocator* allocator) allocator_(allocator), last_info_(), iter_(nullptr), + iter_fill_size_(0), read_param_(nullptr), lob_common_(nullptr), is_end_(false) @@ -446,6 +447,7 @@ ObLobMetaWriteIter::ObLobMetaWriteIter( allocator_(allocator), last_info_(), iter_(nullptr), + iter_fill_size_(0), read_param_(nullptr), lob_common_(nullptr), is_end_(false) @@ -654,6 +656,8 @@ int ObLobMetaWriteIter::try_fill_data( row.info_.byte_len_ += by_len; row.info_.char_len_ += char_len; OB_ASSERT(row.info_.byte_len_ >= row.info_.char_len_); + offset_ += by_len; + iter_fill_size_ += by_len; } return ret; } @@ -846,8 +850,8 @@ int ObLobMetaWriteIter::get_next_row(ObLobMetaWriteResult &row) ret = try_fill_data(row, post_data_, post_data_.length(), true, use_inner_buffer, fill_full); } else if (!iter->is_end()) { ret = try_fill_data(row, use_inner_buffer, fill_full); - } else if (remain_buf_.length() > offset_ - post_data_.length() - padding_size_) { - ret = try_fill_data(row, remain_buf_, post_data_.length() + padding_size_, false, use_inner_buffer, fill_full); + } else if (remain_buf_.length() > offset_ - post_data_.length() - padding_size_ - iter_fill_size_) { + ret = try_fill_data(row, remain_buf_, post_data_.length() + padding_size_ + iter_fill_size_, false, use_inner_buffer, fill_full); } else { ret = OB_ITER_END; } @@ -911,6 +915,7 @@ void ObLobMetaWriteIter::reuse() remain_buf_.reset(); last_info_.reset(); iter_ = nullptr; + iter_fill_size_ = 0; lob_common_ = nullptr; is_end_ = false; } diff --git a/src/storage/lob/ob_lob_meta.h b/src/storage/lob/ob_lob_meta.h index 63bd575fce..3ddac377c1 100644 --- a/src/storage/lob/ob_lob_meta.h +++ b/src/storage/lob/ob_lob_meta.h @@ -164,6 +164,7 @@ private: ObIAllocator* allocator_; ObLobMetaInfo last_info_; void *iter_; // ObLobQueryIter + uint64_t iter_fill_size_; void *read_param_; // ObLobAccessParam void* lob_common_; // ObLobCommon bool is_end_;