min_last_complete_ondisk = eversion_t(0,0); // we don't know (yet)!
}
last_update_applied = info.last_update;
-
+ last_rollback_info_trimmed_to_applied = pg_log.get_rollback_trimmed_to();
need_up_thru = false;
PGLogEntryHandler handler;
if (!transaction_applied) {
pg_log.clear_can_rollback_to(&handler);
+ t.register_on_applied(
+ new C_UpdateLastRollbackInfoTrimmedToApplied(
+ this,
+ get_osdmap()->get_epoch(),
+ info.last_update));
} else if (trim_rollback_to > pg_log.get_rollback_trimmed_to()) {
pg_log.trim_rollback_info(
trim_rollback_to,
&handler);
+ t.register_on_applied(
+ new C_UpdateLastRollbackInfoTrimmedToApplied(
+ this,
+ get_osdmap()->get_epoch(),
+ trim_rollback_to));
}
dout(10) << "append_log adding " << keys.size() << " keys" << dendl;
}
}
+void PG::_scan_rollback_obs(
+ const vector<ghobject_t> &rollback_obs,
+ ThreadPool::TPHandle &handle)
+{
+ ObjectStore::Transaction *t = NULL;
+ eversion_t trimmed_to = last_rollback_info_trimmed_to_applied;
+ for (vector<ghobject_t>::const_iterator i = rollback_obs.begin();
+ i != rollback_obs.end();
+ ++i) {
+ if (i->generation < trimmed_to.version) {
+ osd->clog.error() << "osd." << osd->whoami
+ << " pg " << info.pgid
+ << " found obsolete rollback obj "
+ << *i << " generation < trimmed_to "
+ << trimmed_to
+ << "...repaired";
+ if (!t)
+ t = new ObjectStore::Transaction;
+ t->remove(coll, *i);
+ }
+ }
+ if (t) {
+ derr << __func__ << ": queueing trans to clean up obsolete rollback objs"
+ << dendl;
+ osd->store->queue_transaction_and_cleanup(osr.get(), t);
+ }
+}
+
void PG::_scan_snaps(ScrubMap &smap)
{
for (map<hobject_t, ScrubMap::object>::iterator i = smap.objects.begin();
// objects
vector<hobject_t> ls;
- int ret = get_pgbackend()->objects_list_range(start, end, 0, &ls);
+ vector<ghobject_t> rollback_obs;
+ int ret = get_pgbackend()->objects_list_range(
+ start,
+ end,
+ 0,
+ &ls,
+ &rollback_obs);
if (ret < 0) {
dout(5) << "objects_list_range error: " << ret << dendl;
return ret;
}
+
get_pgbackend()->be_scan_list(map, ls, deep, handle);
+ _scan_rollback_obs(rollback_obs, handle);
_scan_snaps(map);
// pg attrs
eversion_t last_complete_ondisk; // last_complete that has committed.
eversion_t last_update_applied;
+
+ struct C_UpdateLastRollbackInfoTrimmedToApplied : Context {
+ PGRef pg;
+ epoch_t e;
+ eversion_t v;
+ C_UpdateLastRollbackInfoTrimmedToApplied(PG *pg, epoch_t e, eversion_t v)
+ : pg(pg), e(e), v(v) {}
+ void finish(int) {
+ pg->lock();
+ if (!pg->pg_has_reset_since(e)) {
+ pg->last_rollback_info_trimmed_to_applied = v;
+ }
+ pg->unlock();
+ }
+ };
+ // entries <= last_rollback_info_trimmed_to_applied have been trimmed,
+ // and the transaction has applied
+ eversion_t last_rollback_info_trimmed_to_applied;
+
// primary state
public:
pg_shard_t primary;
void scrub_clear_state();
bool scrub_gather_replica_maps();
void _scan_snaps(ScrubMap &map);
+ void _scan_rollback_obs(
+ const vector<ghobject_t> &rollback_obs,
+ ThreadPool::TPHandle &handle);
void _request_scrub_map_classic(pg_shard_t replica, eversion_t version);
void _request_scrub_map(pg_shard_t replica, eversion_t version,
hobject_t start, hobject_t end, bool deep);