Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

luminous: osd: Limit pg log length during recovery/backfill so that we don't run out of memory #23211

Merged
merged 11 commits into from Sep 12, 2018
Merged
9 changes: 8 additions & 1 deletion src/osd/PG.cc
Expand Up @@ -3275,7 +3275,14 @@ void PG::append_log(
roll_forward_to));
}

pg_log.trim(trim_to, info);
dout(10) << __func__ << " approx pg log length = "
<< pg_log.get_log().approx_size() << dendl;
dout(10) << __func__ << " transaction_applied = "
<< transaction_applied << dendl;
if (!transaction_applied)
dout(10) << __func__ << " " << pg_whoami
<< " is backfill target" << dendl;
pg_log.trim(trim_to, info, transaction_applied);

// update the local pg, pg log
dirty_info = true;
Expand Down
31 changes: 21 additions & 10 deletions src/osd/PGLog.cc
Expand Up @@ -50,14 +50,8 @@ void PGLog::IndexedLog::trim(
set<string>* trimmed_dups,
eversion_t *write_from_dups)
{
if (complete_to != log.end() &&
complete_to->version <= s) {
generic_dout(0) << " bad trim to " << s << " when complete_to is "
<< complete_to->version
<< " on " << *this << dendl;
}

assert(s <= can_rollback_to);
generic_dout(20) << " complete_to " << complete_to->version << dendl;

auto earliest_dup_version =
log.rbegin()->version.version < cct->_conf->osd_pg_log_dups_tracked
Expand Down Expand Up @@ -91,13 +85,24 @@ void PGLog::IndexedLog::trim(
}
}

bool reset_complete_to = false;
// we are trimming past complete_to, so reset complete_to
if (e.version >= complete_to->version)
reset_complete_to = true;
if (rollback_info_trimmed_to_riter == log.rend() ||
e.version == rollback_info_trimmed_to_riter->version) {
log.pop_front();
rollback_info_trimmed_to_riter = log.rend();
} else {
log.pop_front();
}

// reset complete_to to the beginning of the log
if (reset_complete_to) {
generic_dout(0) << " moving complete_to " << " to "
<< log.begin()->version << dendl;
complete_to = log.begin();
}
}

while (!dups.empty()) {
Expand Down Expand Up @@ -162,16 +167,22 @@ void PGLog::clear_info_log(

void PGLog::trim(
eversion_t trim_to,
pg_info_t &info)
pg_info_t &info,
bool transaction_applied)
{
dout(10) << __func__ << " proposed trim_to = " << trim_to << dendl;
// trim?
if (trim_to > log.tail) {
// We shouldn't be trimming the log past last_complete
assert(trim_to <= info.last_complete);
dout(10) << __func__ << " missing = " << missing.num_missing() << dendl;
// Don't assert for backfill_targets
// or whenever there are missing items
if (transaction_applied && (missing.num_missing() == 0))
assert(trim_to <= info.last_complete);

dout(10) << "trim " << log << " to " << trim_to << dendl;
log.trim(cct, trim_to, &trimmed, &trimmed_dups, &write_from_dups);
info.log_tail = log.tail;
dout(10) << " after trim complete_to " << log.complete_to->version << dendl;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/osd/PGLog.h
Expand Up @@ -705,7 +705,8 @@ struct PGLog : DoutPrefixProvider {

void trim(
eversion_t trim_to,
pg_info_t &info);
pg_info_t &info,
bool transaction_applied = true);

void roll_forward_to(
eversion_t roll_forward_to,
Expand Down
20 changes: 12 additions & 8 deletions src/osd/PrimaryLogPG.cc
Expand Up @@ -1567,15 +1567,18 @@ void PrimaryLogPG::calc_trim_to()
PG_STATE_BACKFILL_TOOFULL)) {
target = cct->_conf->osd_max_pg_log_entries;
}
// limit pg log trimming up to the head of the log
eversion_t limit = pg_log.get_head();
dout(10) << __func__ << " limit = " << limit << dendl;

eversion_t limit = MIN(
min_last_complete_ondisk,
pg_log.get_can_rollback_to());
if (limit != eversion_t() &&
limit != pg_trim_to &&
pg_log.get_log().approx_size() > target) {
size_t num_to_trim = MIN(pg_log.get_log().approx_size() - target,
cct->_conf->osd_pg_log_trim_max);
dout(10) << __func__ << " approx pg log length = "
<< pg_log.get_log().approx_size() << dendl;
size_t num_to_trim = std::min(pg_log.get_log().approx_size() - target,
cct->_conf->osd_pg_log_trim_max);
dout(10) << __func__ << " num_to_trim = " << num_to_trim << dendl;
if (num_to_trim < cct->_conf->osd_pg_log_trim_min &&
cct->_conf->osd_pg_log_trim_max >= cct->_conf->osd_pg_log_trim_min) {
return;
Expand All @@ -1585,16 +1588,15 @@ void PrimaryLogPG::calc_trim_to()
for (size_t i = 0; i < num_to_trim; ++i) {
new_trim_to = it->version;
++it;
if (new_trim_to > limit) {
if (new_trim_to >= limit) {
new_trim_to = limit;
dout(10) << "calc_trim_to trimming to min_last_complete_ondisk" << dendl;
dout(10) << "calc_trim_to trimming to limit: " << limit << dendl;
break;
}
}
dout(10) << "calc_trim_to " << pg_trim_to << " -> " << new_trim_to << dendl;
pg_trim_to = new_trim_to;
assert(pg_trim_to <= pg_log.get_head());
assert(pg_trim_to <= min_last_complete_ondisk);
}
}

Expand Down Expand Up @@ -10667,6 +10669,8 @@ void PrimaryLogPG::_applied_recovered_object_replica()
void PrimaryLogPG::recover_got(hobject_t oid, eversion_t v)
{
dout(10) << "got missing " << oid << " v " << v << dendl;
dout(10) << __func__ << " complete_to "
<< pg_log.get_log().complete_to->version << dendl;
pg_log.recover_got(oid, v, info);
if (pg_log.get_log().complete_to != pg_log.get_log().log.end()) {
dout(10) << "last_complete now " << info.last_complete
Expand Down