fixed read block return -4016 in flashback
This commit is contained in:
parent
7b1f8e9db9
commit
5640c64a58
@ -1671,6 +1671,54 @@ TEST_F(TestObSimpleLogClusterSingleReplica, test_iterator_with_flashback)
|
||||
|
||||
}
|
||||
|
||||
TEST_F(TestObSimpleLogClusterSingleReplica, read_block_in_flashback)
|
||||
{
|
||||
SET_CASE_LOG_FILE(TEST_NAME, "read_block_in_flashback");
|
||||
OB_LOGGER.set_log_level("TRACE");
|
||||
const int64_t id = ATOMIC_AAF(&palf_id_, 1);
|
||||
int64_t leader_idx = 0;
|
||||
PalfHandleImplGuard leader;
|
||||
PalfEnv *palf_env = NULL;
|
||||
EXPECT_EQ(OB_SUCCESS, create_paxos_group(id, leader_idx, leader));
|
||||
|
||||
EXPECT_EQ(OB_SUCCESS, submit_log(leader, 2 * 32 + 2, id, MAX_LOG_BODY_SIZE));
|
||||
EXPECT_EQ(OB_SUCCESS, wait_until_has_committed(leader, leader.get_palf_handle_impl()->get_max_lsn()));
|
||||
|
||||
block_id_t min_block_id, max_block_id;
|
||||
LogStorage *log_storage = &leader.get_palf_handle_impl()->log_engine_.log_storage_;
|
||||
EXPECT_EQ(OB_SUCCESS, log_storage->get_block_id_range(min_block_id, max_block_id));
|
||||
EXPECT_EQ(2, max_block_id);
|
||||
SCN scn;
|
||||
char block_name_tmp[OB_MAX_FILE_NAME_LENGTH];
|
||||
EXPECT_EQ(OB_SUCCESS, block_id_to_tmp_string(max_block_id, block_name_tmp, OB_MAX_FILE_NAME_LENGTH));
|
||||
char block_name[OB_MAX_FILE_NAME_LENGTH];
|
||||
EXPECT_EQ(OB_SUCCESS, block_id_to_string(max_block_id, block_name, OB_MAX_FILE_NAME_LENGTH));
|
||||
::renameat(log_storage->block_mgr_.dir_fd_, block_name, log_storage->block_mgr_.dir_fd_, block_name_tmp);
|
||||
EXPECT_EQ(-1, ::openat(log_storage->block_mgr_.dir_fd_, block_name, LOG_READ_FLAG));
|
||||
EXPECT_EQ(OB_NEED_RETRY, read_log(leader));
|
||||
EXPECT_EQ(OB_NEED_RETRY, log_storage->get_block_min_scn(max_block_id, scn));
|
||||
|
||||
// 测试边界场景,read_log_tail_为文件中间,最后一个文件完全被flashback掉, 此时log_tail_是最后一个文件头
|
||||
log_storage->log_tail_ = LSN(2*PALF_BLOCK_SIZE);
|
||||
EXPECT_EQ(OB_NEED_RETRY, read_log(leader));
|
||||
EXPECT_EQ(OB_NEED_RETRY, log_storage->get_block_min_scn(max_block_id, scn));
|
||||
|
||||
// 测试边界场景,read_log_tail_最后一个文件头,最后一个文件完全被flashback掉
|
||||
log_storage->log_tail_ = LSN(2*PALF_BLOCK_SIZE);
|
||||
log_storage->readable_log_tail_ = LSN(2*PALF_BLOCK_SIZE);
|
||||
EXPECT_EQ(OB_ITER_END, read_log(leader));
|
||||
EXPECT_EQ(OB_ERR_OUT_OF_UPPER_BOUND, log_storage->get_block_min_scn(max_block_id, scn));
|
||||
|
||||
// 测试边界场景,readable_log_tail_还没改变前检验是否可读通过,直接读文件时报错文件不存在。
|
||||
log_storage->log_tail_ = LSN(3*PALF_BLOCK_SIZE);
|
||||
log_storage->readable_log_tail_ = LSN(3*PALF_BLOCK_SIZE);
|
||||
// 设置max_block_id_为1是为了构造check_read_out_of_bound返回OB_ERR_OUT_OF_UPPER_BOUND的场景
|
||||
log_storage->block_mgr_.max_block_id_ = 1;
|
||||
// log_storage返回OB_ERR_OUT_OF_UPPER_BOUND, iterator将其转换为OB_ITER_END
|
||||
EXPECT_EQ(OB_ITER_END, read_log(leader));
|
||||
EXPECT_EQ(OB_ERR_OUT_OF_UPPER_BOUND, log_storage->get_block_min_scn(max_block_id, scn));
|
||||
}
|
||||
|
||||
|
||||
} // namespace unittest
|
||||
} // namespace oceanbase
|
||||
|
@ -106,7 +106,8 @@ public:
|
||||
// - if the end_lsn get from get_file_end_lsn is smaller than 'log_tail_' of LogStorage, and it's
|
||||
// not the exact boundary of LogGroupEntry(for PalgGroupeBufferIterator, or LogEntry for PalfBufferIterator),
|
||||
// OB_NEED_RETRY may be return.
|
||||
//
|
||||
// - if read_data_from_storage_ is concurrent with the last step of flashback, opening last block on disk may be failed
|
||||
// due to rename, return OB_NEED_RETRY in this case.(TODO by runlin: retry by myself)
|
||||
// OB_ERR_OUT_LOWER_BOUND
|
||||
// - block has been recycled
|
||||
// OB_CHECKSUM_ERROR
|
||||
|
@ -603,20 +603,29 @@ int LogStorage::do_init_(const char *base_dir,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool LogStorage::check_read_out_of_lower_bound_(const block_id_t &block_id) const
|
||||
int LogStorage::check_read_out_of_bound_(const block_id_t &block_id) const
|
||||
{
|
||||
bool bool_ret = false;
|
||||
int ret = OB_SUCCESS;
|
||||
block_id_t min_block_id = LOG_INVALID_BLOCK_ID;
|
||||
block_id_t max_block_id = LOG_INVALID_BLOCK_ID;
|
||||
if (OB_FAIL(get_block_id_range(min_block_id, max_block_id))
|
||||
&& OB_ENTRY_NOT_EXIST != ret) {
|
||||
PALF_LOG(WARN, "get_block_id_range failed", K(ret), K(min_block_id), K(max_block_id));
|
||||
} else if (max_block_id == block_id) {
|
||||
ret = OB_NEED_RETRY;
|
||||
PALF_LOG(WARN, "the block to be read is in flashback, need read retry", K(min_block_id), K(max_block_id), K(block_id));
|
||||
} else if (max_block_id < block_id) {
|
||||
ret = OB_ERR_OUT_OF_UPPER_BOUND;
|
||||
PALF_LOG(WARN, "read something out of upper bound, the blocks may be deleted by flashback",
|
||||
K(min_block_id), K(max_block_id), K(block_id));
|
||||
} else if (min_block_id > block_id) {
|
||||
ret = OB_ERR_OUT_OF_LOWER_BOUND;
|
||||
PALF_LOG(TRACE, "read something out of lower bound", K(min_block_id), K(max_block_id), K(block_id));
|
||||
} else {
|
||||
bool_ret = (min_block_id > block_id || max_block_id < block_id || OB_ENTRY_NOT_EXIST == ret);
|
||||
PALF_LOG(TRACE, "curr block id range", K(min_block_id), K(max_block_id));
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
PALF_LOG(ERROR, "unexpected error, the block may be deleted by human", K(min_block_id), K(max_block_id), K(block_id));
|
||||
}
|
||||
return bool_ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LogStorage::inner_switch_block_()
|
||||
@ -763,13 +772,7 @@ int LogStorage::read_block_header_(const block_id_t block_id,
|
||||
}
|
||||
|
||||
if (OB_NO_SUCH_FILE_OR_DIRECTORY == ret) {
|
||||
if (true == check_read_out_of_lower_bound_(block_id)) {
|
||||
ret = OB_ERR_OUT_OF_LOWER_BOUND;
|
||||
PALF_LOG(WARN, "this block has been deleted", K(ret), K(block_id));
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
PALF_LOG(WARN, "unexpected error, maybe deleted by human or flashabck!!!", K(ret), K(block_id), KPC(this));
|
||||
}
|
||||
ret = check_read_out_of_bound_(block_id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -834,13 +837,7 @@ int LogStorage::inner_pread_(const LSN &read_lsn,
|
||||
}
|
||||
|
||||
if (OB_NO_SUCH_FILE_OR_DIRECTORY == ret) {
|
||||
if (true == check_read_out_of_lower_bound_(lsn_2_block(read_lsn, logical_block_size_))) {
|
||||
ret = OB_ERR_OUT_OF_LOWER_BOUND;
|
||||
PALF_LOG(WARN, "this block has been deleted", K(ret), K(read_lsn));
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
PALF_LOG(ERROR, "unexpected error, maybe deleted by human!!!", K(ret), K(read_lsn));
|
||||
}
|
||||
ret = check_read_out_of_bound_(lsn_2_block(read_lsn, logical_block_size_));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -127,7 +127,15 @@ private:
|
||||
const int64_t align_buf_size,
|
||||
const UpdateManifestCallback &update_manifest_cb,
|
||||
ILogBlockPool *log_block_pool);
|
||||
bool check_read_out_of_lower_bound_(const block_id_t &block_id) const;
|
||||
// @ret val:
|
||||
// OB_SUCCESS
|
||||
// OB_ERR_OUT_OF_LOWER_BOUND
|
||||
// OB_ERR_OUT_OF_UPPER_BOUND
|
||||
// in flashback, (flashback_block_id, max_block_id] may be deleted, however, fetch log may read
|
||||
// some blocks in range of (flashback_block_id, max_block_id].
|
||||
// OB_NEED_RETRY
|
||||
// OB_ERR_UNEXPECTED
|
||||
int check_read_out_of_bound_(const block_id_t &block_id) const;
|
||||
int inner_switch_block_();
|
||||
int append_block_header_used_for_meta_storage_();
|
||||
int append_block_header_(const LSN &block_min_lsn, const share::SCN &block_min_scn);
|
||||
|
Loading…
x
Reference in New Issue
Block a user