Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

feat(dup): verify private log validity before starting to duplicate #315

Merged
merged 6 commits into from
Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/dist/replication/lib/duplication/replica_duplicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,24 @@ error_s replica_duplicator::update_progress(const duplication_progress &p)
return error_s::ok();
}

void replica_duplicator::verify_start_decree(decree start_decree)
{
decree confirmed_decree = progress().confirmed_decree;
decree last_decree = progress().last_decree;
decree max_gced_decree = get_max_gced_decree();
dassert(max_gced_decree < start_decree,
"the logs haven't yet duplicated were accidentally truncated "
"[max_gced_decree: {}, start_decree: {}, confirmed_decree: {}, last_decree: {}]",
max_gced_decree,
start_decree,
confirmed_decree,
last_decree);
}

decree replica_duplicator::get_max_gced_decree() const
{
return _replica->private_log()->max_gced_decree(_replica->get_gpid());
}

} // namespace replication
} // namespace dsn
8 changes: 8 additions & 0 deletions src/dist/replication/lib/duplication/replica_duplicator.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ class replica_duplicator : public replica_base, public pipeline::base

std::string to_string() const;

// To ensure mutation logs after start_decree is available
// for duplication. If not, it means the eventual consistency
// of duplication is no longer guaranteed due to the missing logs.
// For current implementation the system will fail fast.
void verify_start_decree(decree start_decree);

decree get_max_gced_decree() const;

private:
friend class replica_duplicator_test;
friend class duplication_sync_timer_test;
Expand Down
24 changes: 24 additions & 0 deletions src/dist/replication/lib/mutation_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,30 @@ decree mutation_log::max_commit_on_disk() const
return _private_max_commit_on_disk;
}

decree mutation_log::max_gced_decree(gpid gpid) const
{
zauto_lock l(_lock);
return max_gced_decree_no_lock(gpid);
}

decree mutation_log::max_gced_decree_no_lock(gpid gpid) const
{
dassert(_is_private, "");

decree result = invalid_decree;
for (auto &log : _log_files) {
auto it = log.second->previous_log_max_decrees().find(gpid);
if (it != log.second->previous_log_max_decrees().end()) {
if (result == invalid_decree) {
result = it->second.max_decree;
} else {
result = std::min(result, it->second.max_decree);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

得到的是log_file中最小的max_decree,这个是最大的已经gc的decree嘛?

Copy link
Contributor Author

@neverchanje neverchanje Sep 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it->second.max_decree 是上一个日志文件的最大 decree,相当于当前日志最小 decree - 1,这个设计的很 tricky。
最终就是遍历一下所有日志,找最小的

Copy link
Contributor

@hycdong hycdong Sep 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确实tricky,以后可以考虑把max_decree这个变量名改掉

}
}
}
return result;
}

void mutation_log::check_valid_start_offset(gpid gpid, int64_t valid_start_offset) const
{
zauto_lock l(_lock);
Expand Down
6 changes: 6 additions & 0 deletions src/dist/replication/lib/mutation_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,12 @@ class mutation_log : public ref_counter
// thread safe
decree max_commit_on_disk() const;

// Returns `invalid_decree` when plog directory is empty, maybe data corruption occurred
// and the entire directory was tagged ".err".
// thread-safe & private log only
decree max_gced_decree(gpid gpid) const;
hycdong marked this conversation as resolved.
Show resolved Hide resolved
decree max_gced_decree_no_lock(gpid gpid) const;

// thread-safe
std::map<int, log_file_ptr> get_log_file_map() const;

Expand Down