Skip to content

Commit 85a029a

Browse files
xiexingguoneha-ojha
authored andcommitted
osd/PrimaryLogPG: fix potential pg-log overtrimming
In ceph#21580 I set a trap to catch some wired and random segmentfaults and in a recent QA run I was able to observe it was successfully triggered by one of the test case, see: ``` http://qa-proxy.ceph.com/teuthology/xxg-2018-07-30_05:25:06-rados-wip-hb-peers-distro-basic-smithi/2837916/teuthology.log ``` The root cause is that there might be holes on log versions, thus the approx_size() method should (almost) always overestimate the actual number of log entries. As a result, we might be at the risk of overtrimming log entries. ceph#18338 reveals a probably easier way to fix the above problem but unfortunately it also can cause big performance regression and hence comes this pr.. Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn> (cherry picked from commit 3654d56) Conflicts: src/osd/PrimaryLogPG.cc: trivial resolution
1 parent 3b8fc88 commit 85a029a

1 file changed

Lines changed: 22 additions & 11 deletions

File tree

src/osd/PrimaryLogPG.cc

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,19 +1593,30 @@ void PrimaryLogPG::calc_trim_to()
15931593
cct->_conf->osd_pg_log_trim_max >= cct->_conf->osd_pg_log_trim_min) {
15941594
return;
15951595
}
1596-
list<pg_log_entry_t>::const_iterator it = pg_log.get_log().log.begin();
1597-
eversion_t new_trim_to;
1598-
for (size_t i = 0; i < num_to_trim; ++i) {
1599-
new_trim_to = it->version;
1600-
++it;
1601-
if (new_trim_to >= limit) {
1602-
new_trim_to = limit;
1603-
dout(10) << "calc_trim_to trimming to limit: " << limit << dendl;
1604-
break;
1596+
auto it = pg_log.get_log().log.begin(); // oldest log entry
1597+
auto rit = pg_log.get_log().log.rbegin();
1598+
eversion_t by_n_to_keep; // start from tail
1599+
eversion_t by_n_to_trim = eversion_t::max(); // start from head
1600+
for (size_t i = 0; it != pg_log.get_log().log.end(); ++it, ++rit) {
1601+
i++;
1602+
if (i > target && by_n_to_keep == eversion_t()) {
1603+
by_n_to_keep = rit->version;
1604+
}
1605+
if (i >= num_to_trim && by_n_to_trim == eversion_t::max()) {
1606+
by_n_to_trim = it->version;
1607+
}
1608+
if (by_n_to_keep != eversion_t() &&
1609+
by_n_to_trim != eversion_t::max()) {
1610+
break;
16051611
}
16061612
}
1607-
dout(10) << "calc_trim_to " << pg_trim_to << " -> " << new_trim_to << dendl;
1608-
pg_trim_to = new_trim_to;
1613+
1614+
if (by_n_to_keep == eversion_t()) {
1615+
return;
1616+
}
1617+
1618+
pg_trim_to = std::min({by_n_to_keep, by_n_to_trim, limit});
1619+
dout(10) << __func__ << " pg_trim_to now " << pg_trim_to << dendl;
16091620
assert(pg_trim_to <= pg_log.get_head());
16101621
}
16111622
}

0 commit comments

Comments
 (0)